Docker Compose
FlagPulse's docker-compose.yml defines four services on a shared flagpulse_net network.
Services
postgres
postgres:16, with a healthcheck (pg_isready) that gates the backend service from starting until the database is ready. Data persists in the postgres_data volume.
redis
redis:7-alpine, used for flag/SDK-key caching and the dynamic CORS origin set. Data persists in the redis_data volume (mostly useful for surviving quick restarts — cached values expire on their own).
backend
Built from backend/Dockerfile (node:24-slim). Depends on Postgres being healthy and Redis having started. Startup command runs migrations before the server:
npm run migrate && npm run startListens internally on port 3000 — not published directly; only reachable through the nginx service.
nginx
Built from frontend/Dockerfile, using the repo root as build context so it can also copy in the built frontend assets. Publishes ${PORT}:80 — this is the only port exposed to the host. Serves the compiled React app and proxies /api/ to backend:3000 (see nginx/nginx.conf).
Bring it up
docker compose up --buildAdd -d to run detached. To rebuild only the backend after a code change:
docker compose up --build backendData persistence & resets
Both postgres_data and redis_data are named volumes. To fully reset (⚠️ destroys all data):
docker compose down -vMigrations
Migrations live in backend/db/migrations/*.sql and run automatically on every backend container start via backend/db/migrate.js. Applied files are tracked in a schema_migrations table, so re-running is idempotent — only new, unapplied files get executed, each in its own transaction.
Shutdown behavior
On SIGINT, the backend clears the cors:origin Redis set, closes the Redis connection, and closes the Postgres pool before exiting — the set is rebuilt from Postgres on the next startup via syncCorsOrigins().
Next: use the SDK
Once your server is deployed and you've created a project, environment, and flag from the dashboard, grab that environment's SDK key and move on to Using in React (or the HTTP Quickstart if you're not on React).