services: caddy: image: caddy:2-alpine restart: unless-stopped ports: - "80:80" - "443:443" - "443:443/udp" # HTTP/3 environment: SITE_HOSTNAME: ${SITE_HOSTNAME} volumes: # Mount the whole caddy/ dir so both Caddyfile AND certs/ are accessible. - ./caddy:/etc/caddy:ro # Static content for hephaestus.x — landing pages served before falling through to Forgejo. - /var/www/hephaestus.x:/srv/hephaestus.x:ro - caddy-data:/data - caddy-config:/config depends_on: - forgejo - auth-proxy postgres: image: postgres:16-alpine restart: unless-stopped environment: POSTGRES_USER: ${POSTGRES_USER} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} POSTGRES_DB: ${POSTGRES_DB} volumes: - postgres-data:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER}"] interval: 10s timeout: 5s retries: 5 auth-proxy: build: ./auth-proxy restart: unless-stopped environment: ISSUER: ${AUTH_PROXY_ISSUER} CLIENT_ID: ${AUTH_PROXY_CLIENT_ID} CLIENT_SECRET: ${AUTH_PROXY_CLIENT_SECRET} CHALLENGE_DOMAIN: ${AUTH_PROXY_CHALLENGE_DOMAIN} FORGEJO_REDIRECT_URI: ${FORGEJO_ROOT_URL}user/oauth2/hephaestus-wallet/callback # Caddy proxies /auth/* → auth-proxy:4000 over the internal network. No public port. expose: - "4000" volumes: - auth-proxy-keys:/data forgejo: # Small extension of the official image that adds the Silent Mode CA cert # (Argonautica root) to the OS trust store, so Forgejo's Go client can # validate hephaestus.x's cert on OIDC-discovery calls. build: ./forgejo restart: unless-stopped environment: USER_UID: "1000" USER_GID: "1000" FORGEJO__database__DB_TYPE: postgres FORGEJO__database__HOST: postgres:5432 FORGEJO__database__NAME: ${POSTGRES_DB} FORGEJO__database__USER: ${POSTGRES_USER} FORGEJO__database__PASSWD: ${POSTGRES_PASSWORD} FORGEJO__server__DOMAIN: ${FORGEJO_DOMAIN} FORGEJO__server__ROOT_URL: ${FORGEJO_ROOT_URL} FORGEJO__security__SECRET_KEY: ${FORGEJO_SECRET_KEY} FORGEJO__security__INTERNAL_TOKEN: ${FORGEJO_INTERNAL_TOKEN} FORGEJO__oauth2__JWT_SECRET: ${FORGEJO_OAUTH_JWT_SECRET} # --- Storage backend: Sia via silentmode.st's s3d (public endpoint on port 8600) --- # Cert is a real LE cert issued to navigate.st (with SAN for s3.silentmode.st); # Go's default TLS chain trusts it fine. No skip-verify needed. # The 'hephaestus' bucket was pre-created on the 'sync' account. # Path prefixes keep repos/LFS/attachments/packages/archives separated within the bucket. FORGEJO__storage__MINIO_ENDPOINT: ${SIA_STORAGE_ENDPOINT} FORGEJO__storage__MINIO_ACCESS_KEY_ID: ${SIA_STORAGE_ACCESS_KEY} FORGEJO__storage__MINIO_SECRET_ACCESS_KEY: ${SIA_STORAGE_SECRET_KEY} FORGEJO__storage__MINIO_BUCKET: ${SIA_STORAGE_BUCKET} FORGEJO__storage__MINIO_LOCATION: us-east-1 FORGEJO__storage__MINIO_USE_SSL: "true" FORGEJO__storage.lfs__STORAGE_TYPE: minio FORGEJO__storage.lfs__MINIO_BASE_PATH: lfs/ FORGEJO__storage.attachments__STORAGE_TYPE: minio FORGEJO__storage.attachments__MINIO_BASE_PATH: attachments/ FORGEJO__storage.packages__STORAGE_TYPE: minio FORGEJO__storage.packages__MINIO_BASE_PATH: packages/ FORGEJO__storage.repo-archive__STORAGE_TYPE: minio FORGEJO__storage.repo-archive__MINIO_BASE_PATH: archives/ # Live git repos still live on local disk under /data/git — S3 is only for LFS # and other cold blobs. Never point [repository] itself at S3. # --- CORS (so hephaestus.x and other BCNR-served pages can list public repos) --- FORGEJO__cors__ENABLED: "true" FORGEJO__cors__ALLOW_DOMAIN: "*" FORGEJO__cors__ALLOW_CREDENTIALS: "false" FORGEJO__cors__METHODS: "GET,HEAD" # --- Quota (free tier: 500 MB per user) --- FORGEJO__quota__ENABLED: "true" FORGEJO__quota__DEFAULT_GROUPS: free # --- Registration + signin --- # Local form is disabled via SHOW_REGISTRATION_BUTTON=false + ALLOW_ONLY_EXTERNAL_REGISTRATION=true. # DISABLE_REGISTRATION must stay FALSE — it blocks OIDC auto-provisioning too, not just the form. FORGEJO__service__DISABLE_REGISTRATION: "false" FORGEJO__service__SHOW_REGISTRATION_BUTTON: "false" FORGEJO__service__ALLOW_ONLY_EXTERNAL_REGISTRATION: "true" # OIDC callback creates users automatically using the preferred_username claim (= cashaddr). FORGEJO__oauth2_client__ENABLE_AUTO_REGISTRATION: "true" FORGEJO__oauth2_client__ACCOUNT_LINKING: "auto" FORGEJO__oauth2_client__USERNAME: "preferred_username" FORGEJO__oauth2_client__UPDATE_AVATAR: "false" # Skip the web installer wizard — everything is already configured FORGEJO__server__INSTALL_LOCK: "true" # hephaestus.x isn't in ICANN DNS, so the Forgejo container can't resolve # it via its default resolver. Map it to the host gateway so OIDC-discovery # calls (Forgejo → https://hephaestus.x/auth/…) reach Caddy on the host. extra_hosts: - "hephaestus.x:host-gateway" # Caddy proxies / → forgejo:3000 over the internal network. No public HTTP port. # 22 stays on 2222 for git-over-SSH (no TLS involved). expose: - "3000" ports: - "2222:22" volumes: - forgejo-data:/data depends_on: postgres: condition: service_healthy auth-proxy: condition: service_started volumes: postgres-data: forgejo-data: auth-proxy-keys: caddy-data: caddy-config: