Day-2 Docker Operations
Once an environment is running, you operate it with docker compose from its directory (/app/staging or /app/production). Every command shares the same anatomy, and two details trip people up if you skip them.
The command shape
VERSION=staging-latest docker compose -p staging --env-file .env -f deploy/docker-compose.prod.yml <cmd>
Two required pieces:
-p staging/-p production— the project flag. It gives each environment its own Docker network, which is what keeps two environments on one host from cross-connecting (without it they'd share adeploy_defaultnetwork and one API could reach the other's Postgres). Always pass it.VERSION=...prefix — compose needs it to resolve${VERSION}in the image tags. Even forpsorlogs, where the version is irrelevant, compose warns without it. UseVERSION=staging-latest(staging) orVERSION=v0.17.0(production).
Everyday operations
- See services:
... ps - Logs:
... logs api --tail 50(add-fto stream) - Restart one service:
... restart api - Apply an
.envchange:... stop apithen... up -d api— notrestart. A plain restart reuses the existing container and won't pick up new env values. - Shell into a container:
... exec api sh - Connect to Postgres:
... exec postgres psql -U postgres -d circus— Postgres publishes no host port (it's reachable only over the Docker network), soexecis the way in, notpsql -h localhost. - Resource usage:
docker stats --no-stream - Pull + restart everything:
export VERSION=... && ... pull && ... up -d
The nuclear option
... down -v stops everything and removes volumes — destroying the database. Reserve it for a deliberate clean slate (see Rollback & Environment Recovery); the next CI deploy rebuilds from the schema.