Files
RuvdsTest/docker-compose.yml
danamir 154411e7a4
Some checks failed
CI/CD / build-test-deploy (push) Has been cancelled
Fix nginx crash-loop on a fully fresh docker compose up
nginx resolves a plain `proxy_pass http://server:8080;` hostname once at
config-load time. On a cold `docker compose up` that creates every
container at once, the `server` container isn't always registered in
Docker's embedded DNS yet by the time the client's nginx starts — nginx
then fails immediately ("host not found in upstream") and doesn't retry,
so it just crash-loops.

Route the target through a variable instead (`set $upstream_server ...;
proxy_pass $upstream_server;`) with an explicit `resolver`, which makes
nginx resolve the hostname lazily per-request via Docker's DNS rather than
once at startup. Also add `depends_on: [server]` on the client service so
it at least doesn't start before the server container exists at all.

Verified with repeated `docker compose down && docker compose up` cycles
locally — this only reliably reproduced starting every container from
nothing simultaneously, which prior local testing hadn't actually done
(the server container had usually stayed running across rebuilds).
2026-08-06 14:44:52 +03:00

57 lines
1.9 KiB
YAML

services:
postgres:
image: postgres:16-alpine
environment:
POSTGRES_DB: quizsystem
POSTGRES_USER: quizsystem
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-devpassword}
volumes:
- pgdata:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U quizsystem -d quizsystem"]
interval: 5s
timeout: 5s
retries: 10
networks: [quizsystem]
server:
build:
context: .
dockerfile: src/Server/Dockerfile
environment:
ConnectionStrings__Postgres: "Host=postgres;Port=5432;Database=quizsystem;Username=quizsystem;Password=${POSTGRES_PASSWORD:-devpassword}"
Jwt__Secret: ${JWT_SECRET:?Set JWT_SECRET in .env — see .env.example}
Client__Origin: ${CLIENT_ORIGIN:-http://localhost:8081}
ASPNETCORE_ENVIRONMENT: Production
depends_on:
postgres:
condition: service_healthy
# Bound to loopback only: the client container is the sole public entry
# point (it proxies /api/* to this service itself — see
# src/Client/nginx.conf), so nothing outside this host needs to reach
# the API directly. Still published on localhost for local debugging.
ports: ["127.0.0.1:5144:8080"]
networks: [quizsystem]
client:
build:
context: .
dockerfile: src/Client/Dockerfile
# Doesn't fix the DNS race on its own (nginx.conf's lazy resolver does
# that) — just avoids nginx crashing into a restart loop for no reason
# by not starting client before `server` exists at all.
depends_on:
- server
# Loopback-only in production, where a host-level nginx (TLS + the real
# domain) is the actual public entry point and proxies here — see
# docs/DEPLOY.md. For local `docker compose up`, still reachable at
# http://localhost:8081 same as before.
ports: ["127.0.0.1:8081:80"]
networks: [quizsystem]
volumes:
pgdata:
networks:
quizsystem: