From d6e517df1952b31126b44307ad67f0f4ec47c69e Mon Sep 17 00:00:00 2001 From: DJ Mountney Date: Mon, 12 Jan 2026 13:23:19 -0800 Subject: [PATCH 1/2] chore: Add TLS proxy option to the config - Allows configuration of wildcard tls in a service in front of the services --- AGENTS.md | 60 +++++++++++++++ on-prem/.env.example | 23 ++++++ on-prem/docker-compose.cache.yml | 101 +++++++++++++++++++++++++ on-prem/docker-compose.database.yml | 100 +++++++++++++++++++++++++ on-prem/docker-compose.full.yml | 101 +++++++++++++++++++++++++ on-prem/scripts/generate-compose.sh | 51 +++++++++++-- on-prem/templates/compose.rustfs.yml | 5 ++ on-prem/templates/compose.traefik.yml | 103 ++++++++++++++++++++++++++ 8 files changed, 537 insertions(+), 7 deletions(-) create mode 100644 AGENTS.md create mode 100644 on-prem/templates/compose.traefik.yml diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..afa849b --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,60 @@ +# Agent Guidelines for currents-dev-docker + +## Docker Compose Patterns + +### Variable Naming + +- **`DC_` prefix**: Use for docker-compose-only variables (not passed to containers) + - `DC_MONGODB_PORT`, `DC_CURRENTS_IMAGE_TAG`, `DC_REDIS_VOLUME` +- **No prefix**: For app config variables that containers need + - `MONGODB_PASSWORD`, `APP_BASE_URL`, `CLICKHOUSE_CURRENTS_PASSWORD` + +### Port Configuration + +- Default **database ports to localhost-only**: `${DC_MONGODB_PORT:-127.0.0.1:27017}:27017` +- Default **application ports to all interfaces**: `${DC_API_PORT:-4000}:4000` +- Don't use `expose:` - it has no functional effect + +### Image Configuration + +- **Currents services**: Use repository + tag pattern + ```yaml + image: ${DC_CURRENTS_IMAGE_REPOSITORY:-currents-}api:${DC_CURRENTS_IMAGE_TAG:-dev} + ``` +- **Infrastructure services**: Use full image reference + ```yaml + image: ${DC_MONGODB_IMAGE:-mongo:8.2.3} + ``` + +### Initialization + +- Use `command` instead of `entrypoint` when you want to keep the default Docker entrypoint behavior +- For multi-line scripts in YAML, use array format with block scalar to avoid parsing issues with colons: + ```yaml + post_start: + - command: + - bash + - -c + - | + echo "script here" + ``` + +## MongoDB Specifics + +- **Replica sets + auth require keyFile** - even single-node replica sets +- **Change streams require replica sets** - can't use standalone MongoDB +- **Connection strings need `authSource=admin`** for root users created by `MONGO_INITDB_ROOT_*` +- Use localhost exception for initial user creation when auth is enabled + +## Security Patterns + +- **Never default passwords** - require them to be set, generate in setup.sh +- **Keep credentials out of healthcheck commands** - they show in `docker inspect` +- Use variable interpolation for derived URLs: `API_URL=${APP_BASE_URL}/v1` + +## Project Structure + +- Templates live in `on-prem/templates/compose.*.yml` +- `generate-compose.sh` merges templates into final compose files +- `setup.sh` generates secrets using `generate-secrets.sh` +- `.env.example` documents all configurable variables diff --git a/on-prem/.env.example b/on-prem/.env.example index d1377f9..382e78f 100644 --- a/on-prem/.env.example +++ b/on-prem/.env.example @@ -45,6 +45,29 @@ # DC_RUSTFS_S3_PORT=9000 # RustFS S3 API (default: all interfaces) # DC_RUSTFS_CONSOLE_PORT=9001 # RustFS Console (default: all interfaces) +# ============================================================================= +# Traefik TLS Termination (Optional) +# ============================================================================= +# When using the traefik profile, configure TLS termination with a wildcard cert. +# Certificate handling: +# - By default (TRAEFIK_GENERATE_TEMP_CERTS=false): Place wildcard.crt and wildcard.key in data/traefik/certs/ +# - For temporary auto-generated certs: Set TRAEFIK_GENERATE_TEMP_CERTS=true (Traefik generates self-signed certs in memory) +# +# DC_TRAEFIK_IMAGE=traefik:v3.3 # Traefik image +# DC_TRAEFIK_HTTP_PORT=80 # HTTP port (redirects to HTTPS) +# DC_TRAEFIK_HTTPS_PORT=443 # HTTPS port +# DC_TRAEFIK_CERTS_DIR=./data/traefik/certs # Certificate directory +# TRAEFIK_GENERATE_TEMP_CERTS=false # Generate temporary certs (set to true for Traefik to auto-generate) +# DC_TRAEFIK_CONFIG_DIR=./data/traefik/config # Directory for custom Traefik config files +# DC_TRAEFIK_DYNAMIC_CONFIG_PATH=/etc/traefik/dynamic.yml # Path to dynamic config (default uses built-in config, or set to /traefik-config/dynamic.yml for custom) + +# Domain configuration for Traefik routing +# TRAEFIK_DOMAIN=example.com # Base domain for wildcard cert +# TRAEFIK_API_SUBDOMAIN=currents-app # Subdomain for API/Dashboard +# TRAEFIK_DIRECTOR_SUBDOMAIN=currents-record # Subdomain for Director +# TRAEFIK_STORAGE_SUBDOMAIN=currents-storage # Subdomain for RustFS S3 API +# TRAEFIK_ENABLE_STORAGE=false # Enable storage routing (automatically set to true when rustfs is included) + # ============================================================================= # URL Configuration # ============================================================================= diff --git a/on-prem/docker-compose.cache.yml b/on-prem/docker-compose.cache.yml index ac93bde..a0e99cf 100644 --- a/on-prem/docker-compose.cache.yml +++ b/on-prem/docker-compose.cache.yml @@ -1,5 +1,8 @@ # Generated by: ./scripts/generate-compose.sh # Profile: cache - Cache (redis) +# +# Includes Traefik for TLS termination (opt-in with: --profile tls) +# Enable with: docker compose --profile tls up name: currents_cache @@ -101,6 +104,48 @@ services: redis: condition: service_started required: false + traefik: + hostname: traefik + image: ${DC_TRAEFIK_IMAGE:-traefik:v3.3} + restart: unless-stopped + profiles: + - tls + environment: + TRAEFIK_ENABLE_STORAGE: ${TRAEFIK_ENABLE_STORAGE:-false} + TRAEFIK_GENERATE_TEMP_CERTS: ${TRAEFIK_GENERATE_TEMP_CERTS:-false} + ports: + - ${DC_TRAEFIK_HTTP_PORT:-80}:80 + - ${DC_TRAEFIK_HTTPS_PORT:-443}:443 + networks: + - default + volumes: + - ${DC_TRAEFIK_CERTS_DIR:-./data/traefik/certs}:/certs + - ${DC_TRAEFIK_CONFIG_DIR:-./data/traefik/config}:/traefik-config:ro + command: + # Entrypoints + - --entrypoints.web.address=:80 + - --entrypoints.websecure.address=:443 + # HTTP to HTTPS redirect + - --entrypoints.web.http.redirections.entryPoint.to=websecure + - --entrypoints.web.http.redirections.entryPoint.scheme=https + # TLS configuration (file-based certificates) + - --entrypoints.websecure.http.tls=true + # File provider for dynamic configuration + - --providers.file.filename=${DC_TRAEFIK_DYNAMIC_CONFIG_PATH:-/etc/traefik/dynamic.yml} + - --providers.file.watch=true + # Enable API for healthcheck (insecure mode, internal only) + - --api.insecure=true + - --api.dashboard=false + # Health check endpoint + - --ping=true + configs: + - source: traefik_dynamic + target: /etc/traefik/dynamic.yml + healthcheck: + test: ['CMD', 'traefik', 'healthcheck', '--ping'] + interval: 10s + timeout: 5s + retries: 3 redis: hostname: redis image: ${DC_REDIS_IMAGE:-redis/redis-stack-server:7.4.0-v8} @@ -113,3 +158,59 @@ services: - ${DC_REDIS_VOLUME:-./data/redis}:/data networks: default: null +configs: + traefik_dynamic: + content: | + # Traefik dynamic configuration (supports Go templating with sprig) + {{- if ne (env "TRAEFIK_GENERATE_TEMP_CERTS") "true" }} + tls: + certificates: + - certFile: /certs/wildcard.crt + keyFile: /certs/wildcard.key + {{- end }} + + http: + routers: + # API / Dashboard service + api: + rule: "Host(`${TRAEFIK_API_SUBDOMAIN:-currents-app}.${TRAEFIK_DOMAIN}`)" + service: api + entryPoints: + - websecure + tls: {} + + # Director service (record API) + director: + rule: "Host(`${TRAEFIK_DIRECTOR_SUBDOMAIN:-currents-record}.${TRAEFIK_DOMAIN}`)" + service: director + entryPoints: + - websecure + tls: {} + + {{- if eq (env "TRAEFIK_ENABLE_STORAGE") "true" }} + # RustFS S3 API (conditionally enabled) + storage: + rule: "Host(`${TRAEFIK_STORAGE_SUBDOMAIN:-currents-storage}.${TRAEFIK_DOMAIN}`)" + service: rustfs + entryPoints: + - websecure + tls: {} + {{- end }} + + services: + api: + loadBalancer: + servers: + - url: "http://api:4000" + + director: + loadBalancer: + servers: + - url: "http://director:1234" + + {{- if eq (env "TRAEFIK_ENABLE_STORAGE") "true" }} + rustfs: + loadBalancer: + servers: + - url: "http://rustfs:9000" + {{- end }} diff --git a/on-prem/docker-compose.database.yml b/on-prem/docker-compose.database.yml index 4f7f6fe..59af3fe 100644 --- a/on-prem/docker-compose.database.yml +++ b/on-prem/docker-compose.database.yml @@ -1,5 +1,8 @@ # Generated by: ./scripts/generate-compose.sh # Profile: database - Database services (redis, mongodb, clickhouse) +# +# Includes Traefik for TLS termination (opt-in with: --profile tls) +# Enable with: docker compose --profile tls up name: currents_database @@ -137,6 +140,48 @@ services: redis: condition: service_started required: false + traefik: + hostname: traefik + image: ${DC_TRAEFIK_IMAGE:-traefik:v3.3} + restart: unless-stopped + profiles: + - tls + environment: + TRAEFIK_ENABLE_STORAGE: ${TRAEFIK_ENABLE_STORAGE:-false} + TRAEFIK_GENERATE_TEMP_CERTS: ${TRAEFIK_GENERATE_TEMP_CERTS:-false} + ports: + - ${DC_TRAEFIK_HTTP_PORT:-80}:80 + - ${DC_TRAEFIK_HTTPS_PORT:-443}:443 + networks: + - default + volumes: + - ${DC_TRAEFIK_CERTS_DIR:-./data/traefik/certs}:/certs + - ${DC_TRAEFIK_CONFIG_DIR:-./data/traefik/config}:/traefik-config:ro + command: + # Entrypoints + - --entrypoints.web.address=:80 + - --entrypoints.websecure.address=:443 + # HTTP to HTTPS redirect + - --entrypoints.web.http.redirections.entryPoint.to=websecure + - --entrypoints.web.http.redirections.entryPoint.scheme=https + # TLS configuration (file-based certificates) + - --entrypoints.websecure.http.tls=true + # File provider for dynamic configuration + - --providers.file.filename=${DC_TRAEFIK_DYNAMIC_CONFIG_PATH:-/etc/traefik/dynamic.yml} + - --providers.file.watch=true + # Enable API for healthcheck (insecure mode, internal only) + - --api.insecure=true + - --api.dashboard=false + # Health check endpoint + - --ping=true + configs: + - source: traefik_dynamic + target: /etc/traefik/dynamic.yml + healthcheck: + test: ['CMD', 'traefik', 'healthcheck', '--ping'] + interval: 10s + timeout: 5s + retries: 3 clickhouse: hostname: clickhouse image: ${DC_CLICKHOUSE_IMAGE:-clickhouse/clickhouse-server:25.8} @@ -231,6 +276,61 @@ services: networks: default: null configs: + traefik_dynamic: + content: | + # Traefik dynamic configuration (supports Go templating with sprig) + {{- if ne (env "TRAEFIK_GENERATE_TEMP_CERTS") "true" }} + tls: + certificates: + - certFile: /certs/wildcard.crt + keyFile: /certs/wildcard.key + {{- end }} + + http: + routers: + # API / Dashboard service + api: + rule: "Host(`${TRAEFIK_API_SUBDOMAIN:-currents-app}.${TRAEFIK_DOMAIN:-example.com}`)" + service: api + entryPoints: + - websecure + tls: {} + + # Director service (record API) + director: + rule: "Host(`${TRAEFIK_DIRECTOR_SUBDOMAIN:-currents-record}.${TRAEFIK_DOMAIN:-example.com}`)" + service: director + entryPoints: + - websecure + tls: {} + + {{- if eq (env "TRAEFIK_ENABLE_STORAGE") "true" }} + # RustFS S3 API (conditionally enabled) + storage: + rule: "Host(`${TRAEFIK_STORAGE_SUBDOMAIN:-currents-storage}.${TRAEFIK_DOMAIN:-example.com}`)" + service: rustfs + entryPoints: + - websecure + tls: {} + {{- end }} + + services: + api: + loadBalancer: + servers: + - url: "http://api:4000" + + director: + loadBalancer: + servers: + - url: "http://director:1234" + + {{- if eq (env "TRAEFIK_ENABLE_STORAGE") "true" }} + rustfs: + loadBalancer: + servers: + - url: "http://rustfs:9000" + {{- end }} clickhouse_users: content: | diff --git a/on-prem/docker-compose.full.yml b/on-prem/docker-compose.full.yml index 04fca8b..8502a9c 100644 --- a/on-prem/docker-compose.full.yml +++ b/on-prem/docker-compose.full.yml @@ -1,5 +1,8 @@ # Generated by: ./scripts/generate-compose.sh # Profile: full - All services (redis, mongodb, clickhouse, rustfs) +# +# Includes Traefik for TLS termination (opt-in with: --profile tls) +# Enable with: docker compose --profile tls up name: currents_full @@ -137,6 +140,49 @@ services: redis: condition: service_started required: false + # Enable RustFS storage routing in Traefik + traefik: + hostname: traefik + image: ${DC_TRAEFIK_IMAGE:-traefik:v3.3} + restart: unless-stopped + profiles: + - tls + environment: + TRAEFIK_ENABLE_STORAGE: "true" + TRAEFIK_GENERATE_TEMP_CERTS: ${TRAEFIK_GENERATE_TEMP_CERTS:-false} + ports: + - ${DC_TRAEFIK_HTTP_PORT:-80}:80 + - ${DC_TRAEFIK_HTTPS_PORT:-443}:443 + networks: + - default + volumes: + - ${DC_TRAEFIK_CERTS_DIR:-./data/traefik/certs}:/certs + - ${DC_TRAEFIK_CONFIG_DIR:-./data/traefik/config}:/traefik-config:ro + command: + # Entrypoints + - --entrypoints.web.address=:80 + - --entrypoints.websecure.address=:443 + # HTTP to HTTPS redirect + - --entrypoints.web.http.redirections.entryPoint.to=websecure + - --entrypoints.web.http.redirections.entryPoint.scheme=https + # TLS configuration (file-based certificates) + - --entrypoints.websecure.http.tls=true + # File provider for dynamic configuration + - --providers.file.filename=${DC_TRAEFIK_DYNAMIC_CONFIG_PATH:-/etc/traefik/dynamic.yml} + - --providers.file.watch=true + # Enable API for healthcheck (insecure mode, internal only) + - --api.insecure=true + - --api.dashboard=false + # Health check endpoint + - --ping=true + configs: + - source: traefik_dynamic + target: /etc/traefik/dynamic.yml + healthcheck: + test: ['CMD', 'traefik', 'healthcheck', '--ping'] + interval: 10s + timeout: 5s + retries: 3 clickhouse: hostname: clickhouse image: ${DC_CLICKHOUSE_IMAGE:-clickhouse/clickhouse-server:25.8} @@ -266,6 +312,61 @@ services: networks: default: null configs: + traefik_dynamic: + content: | + # Traefik dynamic configuration (supports Go templating with sprig) + {{- if ne (env "TRAEFIK_GENERATE_TEMP_CERTS") "true" }} + tls: + certificates: + - certFile: /certs/wildcard.crt + keyFile: /certs/wildcard.key + {{- end }} + + http: + routers: + # API / Dashboard service + api: + rule: "Host(`${TRAEFIK_API_SUBDOMAIN:-currents-app}.${TRAEFIK_DOMAIN}`)" + service: api + entryPoints: + - websecure + tls: {} + + # Director service (record API) + director: + rule: "Host(`${TRAEFIK_DIRECTOR_SUBDOMAIN:-currents-record}.${TRAEFIK_DOMAIN}`)" + service: director + entryPoints: + - websecure + tls: {} + + {{- if eq (env "TRAEFIK_ENABLE_STORAGE") "true" }} + # RustFS S3 API (conditionally enabled) + storage: + rule: "Host(`${TRAEFIK_STORAGE_SUBDOMAIN:-currents-storage}.${TRAEFIK_DOMAIN}`)" + service: rustfs + entryPoints: + - websecure + tls: {} + {{- end }} + + services: + api: + loadBalancer: + servers: + - url: "http://api:4000" + + director: + loadBalancer: + servers: + - url: "http://director:1234" + + {{- if eq (env "TRAEFIK_ENABLE_STORAGE") "true" }} + rustfs: + loadBalancer: + servers: + - url: "http://rustfs:9000" + {{- end }} clickhouse_users: content: | diff --git a/on-prem/scripts/generate-compose.sh b/on-prem/scripts/generate-compose.sh index 3c533c7..455dc48 100755 --- a/on-prem/scripts/generate-compose.sh +++ b/on-prem/scripts/generate-compose.sh @@ -12,7 +12,8 @@ # ./generate-compose.sh database storage # All data services including rustfs # # Requirements: -# - yq (https://github.com/mikefarah/yq) +# - yq (https://github.com/mikefarah/yq) OR +# - docker/podman (will use mikefarah/yq image) set -e @@ -20,10 +21,25 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" TEMPLATES_DIR="$SCRIPT_DIR/../templates" OUTPUT_DIR="$SCRIPT_DIR/.." -# Check for yq -if ! command -v yq &> /dev/null; then - echo "Error: yq is required but not installed." - echo "Install with: brew install yq (macOS) or see https://github.com/mikefarah/yq" +# Determine how to run yq +YQ_CMD="" +if command -v yq &> /dev/null; then + # Use local yq installation + YQ_CMD="yq" +elif command -v docker &> /dev/null; then + # Use docker with yq image + YQ_CMD="docker run --rm -v \"$TEMPLATES_DIR:/templates:ro\" mikefarah/yq:4" + echo "Note: Using Docker with mikefarah/yq:4 image (yq not found locally)" +elif command -v podman &> /dev/null; then + # Use podman with yq image + YQ_CMD="podman run --rm -v \"$TEMPLATES_DIR:/templates:ro\" mikefarah/yq:4" + echo "Note: Using Podman with mikefarah/yq:4 image (yq not found locally)" +else + echo "Error: yq is required but not installed, and neither docker nor podman are available." + echo "Install one of:" + echo " - yq: brew install yq (macOS) or see https://github.com/mikefarah/yq" + echo " - docker: https://docs.docker.com/get-docker/" + echo " - podman: https://podman.io/getting-started/installation" exit 1 fi @@ -63,7 +79,7 @@ get_profile_services() { show_usage() { echo "Usage: $0 [profile...]" echo "" - echo "Available profiles (all include the currents services):" + echo "Available profiles (all include the currents services + traefik with 'tls' profile):" for profile in full database cache analytics storage redis mongodb clickhouse rustfs; do printf " %-12s - %s\n" "$profile" "$(get_profile_desc $profile)" done @@ -111,6 +127,9 @@ OUTPUT_FILE="$OUTPUT_DIR/docker-compose.${PROFILE_NAME}.yml" # Always start with currents base COMPOSE_FILES="$TEMPLATES_DIR/compose.currents.yml" +# Always include traefik (with tls profile, so users opt-in with --profile tls) +COMPOSE_FILES="$COMPOSE_FILES $TEMPLATES_DIR/compose.traefik.yml" + # Add service-specific files based on collected services for service in $SERVICES; do COMPOSE_FILES="$COMPOSE_FILES $TEMPLATES_DIR/compose.${service}.yml" @@ -124,6 +143,9 @@ echo "Output: $OUTPUT_FILE" cat > "$OUTPUT_FILE" << EOF # Generated by: ./scripts/generate-compose.sh # Profile: $PROFILE_NAME - $PROFILE_DESC +# +# Includes Traefik for TLS termination (opt-in with: --profile tls) +# Enable with: docker compose --profile tls up name: currents_${PROFILE_NAME} @@ -132,6 +154,21 @@ EOF # Merge all compose files using yq # Use eval-all with ireduce to deep merge all files # --string-interpolation=false prevents yq from expanding ${VAR} variables -yq eval-all --string-interpolation=false '. as $item ireduce ({}; . * $item)' $COMPOSE_FILES >> "$OUTPUT_FILE" +if [[ "$YQ_CMD" == "yq" ]]; then + # Local yq - use directly + yq eval-all --string-interpolation=false '. as $item ireduce ({}; . * $item)' $COMPOSE_FILES >> "$OUTPUT_FILE" +else + # Docker/Podman - need to adjust paths for container + # Convert absolute paths to container paths + CONTAINER_FILES="" + for file in $COMPOSE_FILES; do + # Get relative path from TEMPLATES_DIR + rel_path="${file#$TEMPLATES_DIR/}" + CONTAINER_FILES="$CONTAINER_FILES /templates/$rel_path" + done + + # Run yq in container and append to output + eval "$YQ_CMD eval-all --string-interpolation=false '. as \$item ireduce ({}; . * \$item)' $CONTAINER_FILES" >> "$OUTPUT_FILE" +fi echo "Generated: $OUTPUT_FILE" diff --git a/on-prem/templates/compose.rustfs.yml b/on-prem/templates/compose.rustfs.yml index a397847..16d7056 100644 --- a/on-prem/templates/compose.rustfs.yml +++ b/on-prem/templates/compose.rustfs.yml @@ -37,3 +37,8 @@ services: sh -c "aws --endpoint-url=http://rustfs:9000 s3 mb s3://currents || true" networks: - default + + # Enable RustFS storage routing in Traefik + traefik: + environment: + TRAEFIK_ENABLE_STORAGE: "true" diff --git a/on-prem/templates/compose.traefik.yml b/on-prem/templates/compose.traefik.yml new file mode 100644 index 0000000..1688978 --- /dev/null +++ b/on-prem/templates/compose.traefik.yml @@ -0,0 +1,103 @@ +# Traefik reverse proxy for TLS termination +# Provides single wildcard certificate TLS termination for Currents services + +services: + traefik: + hostname: traefik + image: ${DC_TRAEFIK_IMAGE:-traefik:v3.3} + restart: unless-stopped + profiles: + - tls + environment: + TRAEFIK_ENABLE_STORAGE: ${TRAEFIK_ENABLE_STORAGE:-false} + TRAEFIK_GENERATE_TEMP_CERTS: ${TRAEFIK_GENERATE_TEMP_CERTS:-false} + ports: + - ${DC_TRAEFIK_HTTP_PORT:-80}:80 + - ${DC_TRAEFIK_HTTPS_PORT:-443}:443 + networks: + - default + volumes: + - ${DC_TRAEFIK_CERTS_DIR:-./data/traefik/certs}:/certs + - ${DC_TRAEFIK_CONFIG_DIR:-./data/traefik/config}:/traefik-config:ro + command: + # Entrypoints + - --entrypoints.web.address=:80 + - --entrypoints.websecure.address=:443 + # HTTP to HTTPS redirect + - --entrypoints.web.http.redirections.entryPoint.to=websecure + - --entrypoints.web.http.redirections.entryPoint.scheme=https + # TLS configuration (file-based certificates) + - --entrypoints.websecure.http.tls=true + # File provider for dynamic configuration + - --providers.file.filename=${DC_TRAEFIK_DYNAMIC_CONFIG_PATH:-/etc/traefik/dynamic.yml} + - --providers.file.watch=true + # Enable API for healthcheck (insecure mode, internal only) + - --api.insecure=true + - --api.dashboard=false + # Health check endpoint + - --ping=true + configs: + - source: traefik_dynamic + target: /etc/traefik/dynamic.yml + healthcheck: + test: ['CMD', 'traefik', 'healthcheck', '--ping'] + interval: 10s + timeout: 5s + retries: 3 + +configs: + traefik_dynamic: + content: | + # Traefik dynamic configuration (supports Go templating with sprig) + {{- if ne (env "TRAEFIK_GENERATE_TEMP_CERTS") "true" }} + tls: + certificates: + - certFile: /certs/wildcard.crt + keyFile: /certs/wildcard.key + {{- end }} + + http: + routers: + # API / Dashboard service + api: + rule: "Host(`${TRAEFIK_API_SUBDOMAIN:-currents-app}.${TRAEFIK_DOMAIN}`)" + service: api + entryPoints: + - websecure + tls: {} + + # Director service (record API) + director: + rule: "Host(`${TRAEFIK_DIRECTOR_SUBDOMAIN:-currents-record}.${TRAEFIK_DOMAIN}`)" + service: director + entryPoints: + - websecure + tls: {} + + {{- if eq (env "TRAEFIK_ENABLE_STORAGE") "true" }} + # RustFS S3 API (conditionally enabled) + storage: + rule: "Host(`${TRAEFIK_STORAGE_SUBDOMAIN:-currents-storage}.${TRAEFIK_DOMAIN}`)" + service: rustfs + entryPoints: + - websecure + tls: {} + {{- end }} + + services: + api: + loadBalancer: + servers: + - url: "http://api:4000" + + director: + loadBalancer: + servers: + - url: "http://director:1234" + + {{- if eq (env "TRAEFIK_ENABLE_STORAGE") "true" }} + rustfs: + loadBalancer: + servers: + - url: "http://rustfs:9000" + {{- end }} From 4921f1c214b0b1da40df05ca49443449ac4fdbde Mon Sep 17 00:00:00 2001 From: DJ Mountney Date: Mon, 12 Jan 2026 13:26:51 -0800 Subject: [PATCH 2/2] chore: update database template --- on-prem/docker-compose.database.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/on-prem/docker-compose.database.yml b/on-prem/docker-compose.database.yml index 59af3fe..65af03e 100644 --- a/on-prem/docker-compose.database.yml +++ b/on-prem/docker-compose.database.yml @@ -290,7 +290,7 @@ configs: routers: # API / Dashboard service api: - rule: "Host(`${TRAEFIK_API_SUBDOMAIN:-currents-app}.${TRAEFIK_DOMAIN:-example.com}`)" + rule: "Host(`${TRAEFIK_API_SUBDOMAIN:-currents-app}.${TRAEFIK_DOMAIN}`)" service: api entryPoints: - websecure @@ -298,7 +298,7 @@ configs: # Director service (record API) director: - rule: "Host(`${TRAEFIK_DIRECTOR_SUBDOMAIN:-currents-record}.${TRAEFIK_DOMAIN:-example.com}`)" + rule: "Host(`${TRAEFIK_DIRECTOR_SUBDOMAIN:-currents-record}.${TRAEFIK_DOMAIN}`)" service: director entryPoints: - websecure @@ -307,7 +307,7 @@ configs: {{- if eq (env "TRAEFIK_ENABLE_STORAGE") "true" }} # RustFS S3 API (conditionally enabled) storage: - rule: "Host(`${TRAEFIK_STORAGE_SUBDOMAIN:-currents-storage}.${TRAEFIK_DOMAIN:-example.com}`)" + rule: "Host(`${TRAEFIK_STORAGE_SUBDOMAIN:-currents-storage}.${TRAEFIK_DOMAIN}`)" service: rustfs entryPoints: - websecure