Docker Compose for Full-Stack Projects: Our Production Template
The annotated Docker Compose template we copy into every full-stack project — web, API, Postgres, and Redis with healthchecks, volumes, and sane defaults.
A good Docker Compose file is the fastest onboarding tool a team can have: clone, run one command, and the whole stack is alive. Here is the template we copy into nearly every full-stack project, with the reasoning behind each choice.
The template
services:
api:
build: ./api
env_file: .env
depends_on:
db:
condition: service_healthy
ports: ["8000:8000"]
web:
build: ./web
depends_on: [api]
ports: ["3000:3000"]
db:
image: postgres:16-alpine
environment:
POSTGRES_PASSWORD: ${DB_PASSWORD}
volumes: [pgdata:/var/lib/postgresql/data]
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 5s
retries: 5
cache:
image: redis:7-alpine
volumes: [redisdata:/data]
volumes:
pgdata:
redisdata:Healthchecks over guesswork
The most common Compose bug is the API starting before the database is ready. depends_on alone only waits for the container to start, not to be ready. Pairing it with a healthcheck and condition: service_healthy eliminates the race entirely.
Named volumes for persistence
Bind mounts are great for source code in development, but database data belongs in named volumes. They survive docker compose down, are easy to back up, and keep your host filesystem clean.
One .env, never secrets in the file
Keep configuration in a .env file that is git-ignored, and reference variables with ${VAR}. Never commit credentials into the compose file itself — a rule that overlaps with our broader take on access control and security.
Dev and prod from one base
Use a base compose.yaml and override it with compose.override.yaml for local hot-reload, or a compose.prod.yaml for production builds. You keep one source of truth and layer environment-specific changes on top.
Key takeaways
- Use healthchecks + conditions to kill startup races.
- Persist data in named volumes, not bind mounts.
- Keep secrets in a git-ignored
.env. - Layer dev/prod with override files.
Reliable infrastructure is the backbone of our Cloud & DevOps services. Need a containerization or CI/CD setup that just works? Reach out.