Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
1beae2a
chore: add nginx to railway as service exposing ipfs ws
Faolain Apr 1, 2025
9268bfd
fix: ai misled me on what railway provides...services cannot be toget…
Faolain Apr 1, 2025
7038924
fix: hardcoding port because dynamic requires other work
Faolain Apr 1, 2025
8efa137
refactor: switch from nginx to caddy
Faolain Apr 2, 2025
2b4bded
fix: broken caddyfile
Faolain Apr 2, 2025
0ce4bce
lint: caddyfile formatter
Faolain Apr 2, 2025
123592d
refactor: switch from using bash to jq
Faolain Apr 2, 2025
04e1317
debug: add logging to caddy
Faolain Apr 2, 2025
f76d8ab
fix: broken caddyfile
Faolain Apr 2, 2025
ad88fe8
fix: broken caddyfile
Faolain Apr 2, 2025
bd0d88e
chore: add logging to caddyfile
Faolain Apr 2, 2025
ee27ff6
fix: nth attempt at caddyfile fix
Faolain Apr 2, 2025
baf2212
fix: caddyfile more times
Faolain Apr 2, 2025
7fb11f1
fix: caddyfile
Faolain Apr 2, 2025
2365b40
fix: add back jupyter token
Faolain Apr 2, 2025
f697696
fix: add back jupyter token
Faolain Apr 2, 2025
c89d4e6
refactor: switch from nginx to caddy in filenames
Faolain Apr 3, 2025
cedb454
refactor: create gateway caddy reverse proxy
Faolain Apr 3, 2025
b786bd7
fix: gateway path for caddy
Faolain Apr 3, 2025
29b751e
feat: listen on ip6 as well for railway private networking
Faolain Apr 3, 2025
a4d08b2
fix: listen on all address not just loopback
Faolain Apr 3, 2025
e2a2ce6
refactor: add webui access via basic auth
Faolain Apr 4, 2025
7f33ae8
chore: remove authorization
Faolain Apr 4, 2025
d2ab93c
fix: wrong jupyter-ipfs host
Faolain Apr 4, 2025
35e2d05
test: change webui route
Faolain Apr 4, 2025
55552c7
test: undo webui test change
Faolain Apr 4, 2025
1bb33fc
chore: expose rpc api
Faolain Apr 4, 2025
1bce1f5
fix: remove upstream webui url
Faolain Apr 4, 2025
8738b8b
fix: add caddy to cors
Faolain Apr 4, 2025
dcac53b
fix: reverse proxy rpc endpoints as well
Faolain Apr 4, 2025
ad7055b
feat: shell of two more dclimate courses
Faolain Apr 4, 2025
e567e0e
test: basic auth for caddy webui
Faolain Apr 4, 2025
d93c055
fix: remove reverse proxy to api
Faolain Apr 4, 2025
7f7ddec
fix: comment out dynamic cors configuration
Faolain Apr 4, 2025
13dd2ec
feat: add auth to ipfs
Faolain Apr 7, 2025
70edc2b
feat: stac metadata documentation for cids
Faolain Apr 8, 2025
465fb3b
feat: added basic zarr client example
Faolain Apr 14, 2025
b128ead
refactor: update 201 with zarrv3 async
Faolain May 22, 2025
fdb98dd
fix: 202b encryption
TheGreatAlgo May 27, 2025
0b1ac3a
fix: rename example
TheGreatAlgo May 30, 2025
89ccf99
fix: support encrypted zarr
TheGreatAlgo Jun 2, 2025
6ff0330
refactor: add authorization to caddy
Faolain Jun 19, 2025
eccd3c5
refactor: remove caddy auth
Faolain Jun 19, 2025
a7a1403
fix: commented out forward
Faolain Jun 19, 2025
e298fee
Revert "fix: support encrypted zarr"
Faolain Jun 19, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 65 additions & 0 deletions Caddyfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# /Caddyfile
{
# Optional global config
}

http://:{$PORT} {
log {
output stdout
format json {
message_key msg # Key for the log message
level_key severity # Key for the log level
time_key timestamp # Key for the timestamp
name_key logger # Key for the logger name
caller_key function # Key for the caller information
stacktrace_key stack # Key for error stacktraces
time_format "2006-01-02 15:04:05 MST" # RFC3339-like format
time_local # Use local timezone
duration_format "ms" # Show durations in milliseconds
level_format "upper" # Uppercase log levels
}
format append {
server_env {env.jupyter-ipfs}
static_field static_value
}
}

reverse_proxy {env.jupyter-ipfs}:4001
}



# # /Caddyfile
# {
# log {
# # Log to stderr so it appears in Railway logs
# output stderr
# # # Use JSON format for clarity, include the variable value
# # format json {
# # time_format rfc3339
# # # Add a custom field 'private_host_var' using the placeholder
# # field private_host_var "{env.JUPYTER_IPFS_PRIVATE_HOST}"
# # # Add other useful fields
# # field level "{log.level}"
# # field ts "{log.time}"
# # field msg "{log.msg}"
# # field request "{log.request>method} {log.request>uri}"
# # field status "{log.response>status}"
# # field size "{log.response>size}"
# # field duration "{log.duration}"
# # field remote_ip "{log.request>remote_ip}"
# # field proto "{log.request>proto}"
# # }
# level DEBUG # Or DEBUG for more verbosity
# }
# }

# # Define the main site block listening on the port Railway provides ($PORT)
# http://:{$PORT} {
# # Reverse proxy all requests to the internal jupyter-ipfs service.
# # Use the environment variable injected by Railway.
# # Port 4001 is the internal IPFS WS port.
# # --- MODIFIED LINE: Removed http:// ---
# reverse_proxy {env.JUPYTER_IPFS_PRIVATE_HOST}:4001
# # --- END MODIFIED LINE ---
# }
69 changes: 69 additions & 0 deletions Caddyfile - mod.gateway
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# Caddyfile.gateway

# Listen on the port Railway provides for this service
# Caddy automatically picks up the $PORT environment variable.
http://:{$PORT} {
# --- Logging Configuration (kept from your example) ---
log {
output stdout
format json {
message_key msg # Key for the log message
level_key severity # Key for the log level
time_key timestamp # Key for the timestamp
name_key logger # Key for the logger name
caller_key function # Key for the caller information
stacktrace_key stack # Key for error stacktraces
time_format "2006-01-02 15:04:05 MST" # RFC3339-like format
time_local # Use local timezone
duration_format "ms" # Show durations in milliseconds
level_format "upper" # Uppercase log levels
}
format append {
service_role ipfs-fully-auth-proxy
server_env {env.jupyter-ipfs}
# static_field static_value # Keep if needed
}
}

# --- Define Authentication Matchers using Environment Variables ---
# Ensure IPFS_API_KEY, IPFS_BEARER_TOKEN, and IPFS_BASIC_AUTH_BASE64
# are set in the Railway environment for this service.
@apiKey header X-Api-Key {env.IPFS_API_KEY}
@bearerToken header Authorization "Bearer {env.IPFS_BEARER_TOKEN}"
@basicAuth header Authorization "Basic {env.IPFS_BASIC_AUTH_BASE64}"

# --- Routing Logic ---

# Route 1: Handle requests specifically for the IPFS API path
handle /api/v0/* {
# Require *at least one* of the defined authentication methods to be valid.
authorize {
@apiKey
@bearerToken
@basicAuth
}

# If authorization succeeded, proxy the request to the IPFS Gateway endpoint.
# Ensure jupyter-ipfs environment variable points to your IPFS service name in Railway.
reverse_proxy {env.jupyter-ipfs}:5001
}

# Route 2: /webui* (Browser Authenticated Web UI Access)
# Requires separate Basic Auth credentials, triggers browser prompt.
handle /webui* {
# Enforce Basic Auth specifically for Web UI access.
# Reads WEBUI_USER and WEBUI_HASH from environment variables.
basicauth {
realm "IPFS Web UI Access"
{env.WEBUI_USER} {env.WEBUI_HASH}
}
# Proxy authenticated requests to IPFS API port (5001, where webui lives)
reverse_proxy {env.IPFS_UPSTREAM_HOST}:5001
}

# Route 3: Handle all other requests (e.g., /ipfs/*, /ipns/*, /)
# These requests will be proxied directly to the Gateway without the specific auth checks above.
handle {
reverse_proxy {env.jupyter-ipfs}:8080
}
}
56 changes: 56 additions & 0 deletions Caddyfile copy.gateway
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# /etc/caddy/Caddyfile for Authenticated IPFS API Proxy
# This version assumes all necessary environment variables are provided externally (e.g., by Railway).

# Listen on the port Railway provides for this service
# Caddy automatically picks up the $PORT environment variable.
http://:{$PORT} {
# --- Logging Configuration ---
log {
output stdout
format json {
message_key msg
level_key severity
time_key timestamp
name_key logger
caller_key function
stacktrace_key stack
time_format "2006-01-02 15:04:05 MST"
time_local
duration_format "ms"
level_format "upper"
}
format append {
service_role ipfs-auth-api-proxy # Identify this service
}
}

# --- Define Authentication Matchers using Environment Variables ---
# Caddy will read these directly from the environment provided by Railway.
# Ensure IPFS_API_KEY, IPFS_BEARER_TOKEN, and IPFS_BASIC_AUTH_BASE64 are set in Railway.
# Note: Header values containing spaces need quotes in the matcher definition.

@apiKey header X-Api-Key {env.IPFS_API_KEY}
@bearerToken header Authorization "Bearer {env.IPFS_BEARER_TOKEN}"
@basicAuth header Authorization "Basic {env.IPFS_BASIC_AUTH_BASE64}"

# --- Routing Logic ---

# Handle requests specifically for the IPFS API path
handle /api/v0/* {
# Require *at least one* of the defined authentication methods to be valid.
authorize {
@apiKey
@bearerToken
@basicAuth
}

# If authorization succeeded, proxy the request to the IPFS daemon API endpoint.
# Ensure IPFS_API_UPSTREAM is set in Railway (e.g., ipfs-daemon:5001).
reverse_proxy {env.IPFS_API_UPSTREAM}
}

# --- Default Deny for other paths ---
handle {
respond "Forbidden: Access via this endpoint requires authentication at /api/v0/" 403
}
}
58 changes: 58 additions & 0 deletions Caddyfile.api
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# /etc/caddy/Caddyfile for the IPFS API Authentication Gateway Service

{
# Optional: Define env var defaults for local testing if needed
# env IPFS_API_KEY=test
# env IPFS_BEARER_TOKEN=test
# env IPFS_BASIC_AUTH_BASE64=dGVzdDp0ZXN0 # test:test
# env IPFS_API_UPSTREAM=ipfs-daemon:5001 # Example internal address for IPFS API
}

# Listen on the unique port Railway provides for THIS service
:{$PORT} {
log {
output stdout
format json {
message_key msg
level_key severity
time_key timestamp
name_key logger
caller_key function
stacktrace_key stack
time_format "2006-01-02 15:04:05 MST"
time_local
duration_format "ms"
level_format "upper"
}
format append {
# Identify logs from this specific service
service_role api-gateway
# Optionally add other static or dynamic fields
# server_env {env.RAILWAY_SERVICE_NAME}
}
}

# --- Define Authentication Matchers ---
@apiKey header X-Api-Key {env.IPFS_API_KEY}
@bearerToken header Authorization "Bearer {env.IPFS_BEARER_TOKEN}"
@basicAuth header Authorization "Basic {env.IPFS_BASIC_AUTH_BASE64}"

# --- Routing Logic for API ---
handle /api/v0/* {
# Require one of the auth methods
authorize {
@apiKey
@bearerToken
@basicAuth
}

# Proxy authorized requests to the IPFS daemon API
reverse_proxy {env.IPFS_API_UPSTREAM}
}

# --- Deny all other requests to this gateway ---
# Prevents accessing other IPFS ports/paths via this authenticated endpoint
handle {
respond "Forbidden: Access restricted to authenticated /api/v0/* requests." 403
}
}
46 changes: 46 additions & 0 deletions Caddyfile.gateway
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Caddyfile.gateway
{
# Optional global config
}

http://:{$PORT} {
log {
output stdout
format json {
message_key msg # Key for the log message
level_key severity # Key for the log level
time_key timestamp # Key for the timestamp
name_key logger # Key for the logger name
caller_key function # Key for the caller information
stacktrace_key stack # Key for error stacktraces
time_format "2006-01-02 15:04:05 MST" # RFC3339-like format
time_local # Use local timezone
duration_format "ms" # Show durations in milliseconds
level_format "upper" # Uppercase log levels
}
format append {
server_env {env.jupyter-ipfs}
static_field static_value
}
}

# Handle requests specifically for the IPFS RPC API
# Must come before a more general fallback
handle /api/v0* {
reverse_proxy {env.jupyter-ipfs}:5001 {
# Optional but good practice: Forward original scheme
# header_upstream X-Forwarded-Proto {scheme}
}
}

handle /webui* {
basic_auth {
# Username "Bob", password "hiccup"
Bob $2a$14$Zkx19XLiW6VYouLHR5NmfOFU0z2GTNmpkT/5qqR7hx4IjWJPDhjvG
}
# Proxy authenticated requests to IPFS API port (5001, where webui lives)
reverse_proxy {env.jupyter-ipfs}:5001
}

reverse_proxy {env.jupyter-ipfs}:8080
}
9 changes: 9 additions & 0 deletions Dockerfile-ipfs-ws-proxy.caddy
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Dockerfile-ipfs-ws-proxy.caddy
FROM caddy:2-alpine

# Copy the Caddyfile into the standard configuration location
COPY Caddyfile /etc/caddy/Caddyfile

# No EXPOSE or CMD needed usually, the base image handles it.
# It will run Caddy using /etc/caddy/Caddyfile and listen on $PORT.
# Railway sets $PORT based on the railway.json "containerPort".
7 changes: 7 additions & 0 deletions Dockerfile.api
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Dockerfile.api
FROM caddy:2-alpine

# Copy the specific Caddyfile for THIS service
COPY Caddyfile.api /etc/caddy/Caddyfile

# Base image handles running Caddy with /etc/caddy/Caddyfile on $PORT
7 changes: 7 additions & 0 deletions Dockerfile.gateway
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Dockerfile.api
FROM caddy:2-alpine

# Copy the specific Caddyfile for THIS service
COPY Caddyfile.gateway /etc/caddy/Caddyfile

# Base image handles running Caddy with /etc/caddy/Caddyfile on $PORT
1 change: 1 addition & 0 deletions Dockerfile.jupyter
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ RUN apt-get update && apt-get install -y \
python3-venv \
libffi-dev \
libssl-dev \
jq \
&& rm -rf /var/lib/apt/lists/*

ARG KUBO_VERSION=0.33.2
Expand Down
6 changes: 6 additions & 0 deletions main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
def main():
print("Hello from zarr-getting-started!")


if __name__ == "__main__":
main()
Loading