# Local dev stack: Keyway + demo app. Secrets come from `.env` (see # `.env.example`); the SQLite file lives in the named volume; the SP # signing key/cert are bind-mounted read-only from the repo root. # # NOTE on --addr: inside a container localhost means the container itself, # so both services must listen on 0.0.0.0. --base-url stays a loopback URL # here because the browser resolves it on the host, where ports are # published. For a public host, use docker-compose.prod.yml instead. services: keyway: build: . image: keyway:local env_file: - .env command: - start - --addr=0.0.0.0:8080 - --db=/data/keyway.db - --base-url=${KEYWAY_BASE_URL:-http://127.0.0.1:8080} - --sp-key=/data/sp.key - --sp-cert=/data/sp.crt ports: # Loopback-bound: the browser reaches these on the host, but a # production VM exposes nothing directly — traffic goes via Caddy. # Port numbers are env-driven so parallel per-customer stacks # (scripts/new-customer.ps1) don't collide on one machine. - "127.0.0.1:${KEYWAY_PORT:-8080}:8080" volumes: - keyway-data:/data # Paths are env-driven so one repo serves many isolated customers: # each customer dir (customers//) carries its own pair, selected # with --env-file customers//.env (see scripts/new-customer.ps1). - ${SP_KEY_PATH:-./sp.key}:/data/sp.key:ro - ${SP_CERT_PATH:-./sp.crt}:/data/sp.crt:ro restart: unless-stopped healthcheck: # Shell-free probe (the image is scratch): status exits 0 only when # the binary, master key, and SQLite file all work together. test: ["CMD", "/keyway", "status", "--db", "/data/keyway.db"] interval: 30s timeout: 5s retries: 3 start_period: 10s demo: image: keyway:local entrypoint: ["/demo-sso"] command: # --keyway is the browser-facing address embedded in login links # (KEYWAY_PUBLIC_URL): loopback for dev, the tunnel/prod origin when # Keyway is publicly reachable. --keyway-internal is the server-side # address for code exchange over the compose network. One flag for # both would hand the browser a container-internal hostname it cannot # resolve. - --keyway=${KEYWAY_PUBLIC_URL:-http://127.0.0.1:8080} - --keyway-internal=http://keyway:8080 - --addr=0.0.0.0:3000 - --tenant=${DEMO_TENANT:-acme} - --redirect=${DEMO_REDIRECT:-http://localhost:3000/callback} - --connection=${DEMO_CONNECTION_ID:-} ports: - "127.0.0.1:${DEMO_PORT:-3000}:3000" depends_on: keyway: condition: service_healthy restart: unless-stopped volumes: keyway-data: