Files
jobtrackingapp/docs/verification/sec-002-ingress-compose.md
T
cesnimda e8e6fac420
CI and Deploy / test (push) Successful in 6m42s
CI and Deploy / test (pull_request) Failing after 3m59s
CI and Deploy / deploy (push) Successful in 31s
CI and Deploy / deploy (pull_request) Has been skipped
fix(deploy): restore proxy compatibility port
2026-08-24 21:09:22 +02:00

3.4 KiB

SEC-002 ingress and Compose verification

Date: 2026-08-02
Status: VERIFIED LOCALLY; operator Traefik and production checks remain.

Implemented boundary

  • Production automation explicitly selects docker-compose.yml; the auto-loaded override was replaced by explicitly selected docker-compose.dev.yml.
  • Base Compose retains the frontend's production compatibility port 3000 because the operator-owned reverse proxy still targets that host port. Backend, ai-service, and bundled Ollama remain unpublished; development additionally exposes backend 5202 and profile-scoped Ollama 11434.
  • Nginx and backend communicate over an internal dedicated CIDR; the backend accepts exactly one forwarded hop only from that CIDR.
  • Nginx derives its application server name from APP_PUBLIC_BASE_URL, rejects other Hosts except /health, and preserves Traefik's replaced proto/client headers rather than substituting internal HTTP.
  • Deploy preflight requires and validates the canonical origin and dedicated proxy CIDR. CI post-deploy commands use the production Compose file explicitly.

Commands and results

Command/check Result
focused ExternalOriginTests including proxy config Pass; 14/14
full backend Release suite Pass; 476/476
frontend npm run build Pass; Next production build and TypeScript
production and dev docker compose ... config --quiet Pass
parsed Compose assertion including bundled-ollama Pass; production ports absent; dev 3000/5202/11434; internal CIDR aligned
normalized bash -n deploy/deploy.sh Pass
bash -n job-tracker-ui/configure-nginx-origin.sh Pass
mounted nginx template nginx -t using already-installed local frontend image Pass
ephemeral origin substitution with canonical host/port then nginx -t Pass
ephemeral substitution with credential-bearing origin Rejected as expected
git diff --check Pass; line-ending conversion warnings only

No image was pulled and no production or persistent service was changed. Ephemeral Docker validation containers were removed automatically.

Limitations and production gates

  • No Traefik configuration exists in this repository. Production verification proved it still targets host port 3000, so that compatibility ingress remains. Migrate Traefik onto jobtracker_shared, verify its exact Host() rule/TLS/header handling, then remove the host port in a coordinated release.
  • WEB_PROXY_SUBNET must be chosen after production Docker-network inventory. Deploys recover a missing value from a uniquely labelled existing Compose web_proxy network. On its first creation, the documented 172.31.250.0/29 candidate is accepted only after a complete Docker network inventory proves it does not overlap; unreadable or overlapping inventory remains fail-closed.
  • Host firewall and docker ps/published-port state are unverified.
  • The exact nginx:1.29.8-alpine base image was not installed locally. Syntax was checked with the existing local nginx frontend image; approved CI must build the pinned Dockerfile.
  • A complete local proxy/browser smoke was not run because rebuilding the pinned container would require an unavailable base image/package access. No browser claim is made.
  • Rollback is a normal application-version rollback plus the previous .env; do not reintroduce the deleted auto-loaded override or published production ports. If the new CIDR overlaps, roll back before replacement and select a non-overlapping CIDR.