name: ccn-platform # Production base configuration. # Deploys a pre-built image pulled from a registry — no build step. # # docker compose -f docker-compose.yml pull # docker compose -f docker-compose.yml up -d # # The `-f docker-compose.yml` flag is important in production: it skips the docker-compose.override.yml file, which # Compose would otherwise merge in automatically for local development. # # Run one replica: sessions, passkey ceremonies, and recovery links live in the process's memory, so a second instance # would not know the first one's sign-ins — and a restart signs everyone out. services: website: image: ${HOST_CONTAINER}/${HOST_OWNER}/${IMAGE_NAME}:${IMAGE_TAG:-latest} platform: ${IMAGE_PLATFORM:-linux/amd64} container_name: ${HOST_OWNER}-${IMAGE_NAME} restart: unless-stopped ports: - "${HOST_PORT:-8080}:8080" environment: # Empty leaves the tracker off. ANALYTICS_WEBSITE_ID: ${ANALYTICS_WEBSITE_ID:-} ANALYTICS_DOMAINS: ${ANALYTICS_DOMAINS:-} ANALYTICS_RECORDER: ${ANALYTICS_RECORDER:-false} DATABASE_DRIVER: ${DATABASE_DRIVER:-postgres} DATABASE_HOST: ${DATABASE_HOST:?DATABASE_HOST is required} DATABASE_PORT: ${DATABASE_PORT:-5432} DATABASE_NAME: ${DATABASE_NAME:-ccn} DATABASE_PASSWORD: ${DATABASE_PASSWORD:?DATABASE_PASSWORD is required} DATABASE_POOL_MAX_PER_EVENT_LOOP: ${DATABASE_POOL_MAX_PER_EVENT_LOOP:-4} DATABASE_TLS: ${DATABASE_TLS:-require} DATABASE_USERNAME: ${DATABASE_USERNAME:-ccn} LOG_LEVEL: ${LOG_LEVEL:-info} HTTP_SERVER_NAME: ${HTTP_SERVER_NAME:-CCNWebsite} HTTPS_TRUST_FORWARDED_PROTO: "${HTTPS_TRUST_FORWARDED_PROTO:-true}" # The origin browsers bind passkeys to: exactly where the sign-in screen is served — same scheme, same host, no # `www.` either way. Left at the app's default (http://localhost:8080) every ceremony fails, so it follows # SITE_ORIGIN unless set apart. It must be HTTPS: browsers run WebAuthn nowhere else but localhost, and it is # what marks the session cookie `Secure`. PASSKEYS_ORIGIN: ${PASSKEYS_ORIGIN:-${SITE_ORIGIN:-https://ccn.rock-n-co.de}} # Falls back to the policy the app ships with; set it in `.env` to allow the analytics origin, # which must match `String.Analytics.origin`. RATE_LIMIT_TRUST_FORWARDED_FOR: "${RATE_LIMIT_TRUST_FORWARDED_FOR:-true}" SECURITY_CONTENT_SECURITY_POLICY: "${SECURITY_CONTENT_SECURITY_POLICY:-default-src 'self'; object-src 'none'; base-uri 'self'; form-action 'self'; frame-ancestors 'none'}" SECURITY_STRICT_TRANSPORT_SECURITY: "${SECURITY_STRICT_TRANSPORT_SECURITY:-max-age=31536000; includeSubDomains}" # The public origin: scheme and host, no trailing slash. The HTTPS redirect and the canonical links derive from it. SITE_ORIGIN: ${SITE_ORIGIN:-https://ccn.rock-n-co.de} # Off while the site is a prototype: every response is marked `X-Robots-Tag: noindex, nofollow`. SITE_INDEXABLE: "${SITE_INDEXABLE:-false}" volumes: # The photos sellers upload. The rest of the image is read-only, and without the volume a redeploy would lose them. - website-uploads:/app/Resources/Static/uploads healthcheck: test: ["CMD", "curl", "--fail", "--silent", "--show-error", "http://127.0.0.1:8080/health"] interval: 30s timeout: 5s retries: 3 start_period: 10s volumes: website-uploads: