Docker Compose
Overview
Section titled “Overview”Production stack: docker/compose.prod.yml — Postgres, Redis, API, CRDT merge worker, queue worker, UI. Marketing (www) and scheduler are optional (Compose profiles).
Services bind to 127.0.0.1 by default so an upstream reverse proxy can terminate TLS.
Prepare environment files
Section titled “Prepare environment files”- Copy
docker/stack.env.exampletodocker/stack.env. SetPOSTGRES_PASSWORD,APP_KEY, and public URLs (APP_URL,FRONTEND_URL,SESSION_DOMAIN,SANCTUM_STATEFUL_DOMAINS,CORS_ALLOWED_ORIGINS). - Set
NOTE_CRDT_MERGE_URL=http://crdt-merge:3000(default instack.env.example) so the API calls the internal merge worker instead of Node subprocesses. - Optionally copy
api/.env.production.examplefor reference — production Compose injects env fromdocker/stack.envviaenv_fileon API services.
Build or pull images
Section titled “Build or pull images”From the repository root:
# Local build (testing)docker build -f docker/api/Dockerfile -t garrison-api:local .docker build -f docker/ui/Dockerfile \ --build-arg VITE_API_URL=https://api.garrison.test \ --build-arg VITE_WWW_URL=https://www.garrison.test \ -t garrison-ui:local .# Optional marketing site:docker build -f docker/www/Dockerfile -t garrison-www:local .
# Or pull from registry after CIdocker pull registry.example.com/group/garrison/api:latestSet GARRISON_IMAGE_API and GARRISON_IMAGE_UI in .env.production when using a registry. Set GARRISON_IMAGE_WWW only if you enable the www profile.
Start the stack
Section titled “Start the stack”docker compose -f docker/compose.prod.yml --env-file docker/stack.env up -d postgres redis migrate crdt-merge api queue uiThe migrate service runs php artisan migrate --force once, then exits. Do not run db:seed in production.
After deploy, run the Production smoke checklist (/up, GraphQL auth, CRDT note push).
Marketing site (optional)
Section titled “Marketing site (optional)”Enable the www service when you want the Astro marketing site in this stack:
docker compose -f docker/compose.prod.yml --profile www --env-file .env.production up -dOmit --profile www to run only the API, UI, Postgres, Redis, and queue worker.
Reverse proxy
Section titled “Reverse proxy”Point your proxy at the published localhost ports (defaults):
| Host | Port |
|---|---|
api.garrison.test | 8080 |
app.garrison.test | 8081 |
www.garrison.test | 8082 (only with --profile www) |
Override with GARRISON_API_PORT, GARRISON_UI_PORT, and GARRISON_WWW_PORT in .env.production.
Upgrade
Section titled “Upgrade”docker compose -f docker/compose.prod.yml --env-file .env.production pulldocker compose -f docker/compose.prod.yml --env-file .env.production up -ddocker compose -f docker/compose.prod.yml run --rm api php artisan migrate --forceScheduler (optional)
Section titled “Scheduler (optional)”docker compose -f docker/compose.prod.yml --profile scheduler --env-file .env.production up -dBackups
Section titled “Backups”Back up the garrison-postgres Docker volume regularly. Test restore on a non-production host before relying on it.
See also
Section titled “See also”- Production smoke checklist
- Portainer
docker/README.mdin the repository