Docker Compose OAuth
Docker Compose OAuth
Section titled “Docker Compose OAuth”This example deploys FrontMark as a static Nginx site and adds the dedicated OAuth/API proxy container for Sveltia CMS. The public CMS URL stays:
https://sigmax.dev/frontmark/admin/Build Images
Section titled “Build Images”Build the static image and the OAuth sidecar:
make image IMAGE=registry.example.com/frontmark:latestmake image_oauth OAUTH_IMAGE=registry.example.com/frontmark-oauth:latestThe generated CMS backend should contain:
api_root: https://sigmax.dev/frontmark/api/forgejo/v1base_url: https://sigmax.dev/frontmark/oauth/forgejoauth_methods: - oauth - tokenCompose File
Section titled “Compose File”services: traefik: image: traefik:v3.1 command: - --providers.docker=true - --providers.docker.exposedbydefault=false - --entrypoints.web.address=:80 - --entrypoints.websecure.address=:443 - --certificatesresolvers.letsencrypt.acme.email=admin@example.com - --certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json - --certificatesresolvers.letsencrypt.acme.httpchallenge=true - --certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web ports: - "80:80" - "443:443" volumes: - /var/run/docker.sock:/var/run/docker.sock:ro - traefik-letsencrypt:/letsencrypt networks: - frontmark
frontmark: image: registry.example.com/frontmark:latest restart: unless-stopped labels: - traefik.enable=true - traefik.http.routers.frontmark.rule=Host(`sigmax.dev`) && PathPrefix(`/frontmark`) - traefik.http.routers.frontmark.entrypoints=websecure - traefik.http.routers.frontmark.tls.certresolver=letsencrypt - traefik.http.routers.frontmark.priority=10 - traefik.http.services.frontmark.loadbalancer.server.port=4321 networks: - frontmark
frontmark-oauth: image: registry.example.com/frontmark-oauth:latest restart: unless-stopped environment: PUBLIC_GIT_ORIGIN: https://gitea.newkube.ia86.cc FRONTMARK_BASE_PATH: /frontmark SVELTIA_ALLOWED_ORIGINS: https://sigmax.dev # Optional for confidential OAuth applications: # GITEA_CLIENT_SECRET: ${GITEA_CLIENT_SECRET} labels: - traefik.enable=true - traefik.http.routers.frontmark-oauth.rule=Host(`sigmax.dev`) && (PathPrefix(`/frontmark/oauth/forgejo`) || PathPrefix(`/frontmark/api/forgejo/v1`)) - traefik.http.routers.frontmark-oauth.entrypoints=websecure - traefik.http.routers.frontmark-oauth.tls.certresolver=letsencrypt - traefik.http.routers.frontmark-oauth.priority=100 - traefik.http.services.frontmark-oauth.loadbalancer.server.port=4321 networks: - frontmark
volumes: traefik-letsencrypt:
networks: frontmark: name: frontmarkThe OAuth/API router has priority 100; the static catch-all has priority 10. That order matters because /frontmark/oauth/forgejo/* and /frontmark/api/forgejo/v1/* must never land on the static Nginx container.
OAuth App
Section titled “OAuth App”Configure the Forgejo OAuth application with this redirect URI:
https://sigmax.dev/frontmark/admin/If the OAuth app requires a confidential client secret, keep it only on the proxy container:
GITEA_CLIENT_SECRET=...The static FrontMark container does not need the secret.
Verify
Section titled “Verify”After docker compose up -d, check:
curl -I https://sigmax.dev/frontmark/admin/curl https://sigmax.dev/frontmark/admin/config.jsoncurl https://sigmax.dev/frontmark/api/forgejo/v1/versionExpected results:
| URL | Result |
|---|---|
/frontmark/admin/ | Static admin page. |
/frontmark/admin/config.json | api_root points to /frontmark/api/forgejo/v1. |
/frontmark/api/forgejo/v1/version | JSON response from Forgejo through the proxy. |
/frontmark/oauth/forgejo/login/oauth/authorize | Redirects to the configured Forgejo OAuth authorization endpoint. |