Docker Compose in CI for Multi-Service Tests
When your tests need an app plus a database plus a cache, Compose brings the whole stack up with one command.
Service containers cover simple dependencies, but real integration tests often need several services wired together. Docker Compose describes that whole stack in one file and runs identically on a laptop and in CI. This lesson shows the pattern end to end.
Describe the stack
A compose file defines each service and how they depend on one another. Health checks let dependents wait until a service is actually ready.
compose.yaml
services:
db:
image: postgres:16
environment:
POSTGRES_PASSWORD: postgres
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 5s
retries: 5
app:
build: .
depends_on:
db:
condition: service_healthy
environment:
DATABASE_URL: postgres://postgres:postgres@db:5432/postgresRun tests against the stack
Use --build to rebuild changed images and run to execute your suite inside the app service. Compose handles the internal networking.
Terminal
docker compose up -d --build
docker compose run --rm app npm run test:integration
docker compose down -vTips for reliable Compose CI
- Always pair depends_on with a healthcheck so tests do not race startup.
- Use docker compose down -v to remove volumes and avoid state leaking between runs.
- Pin image tags so the stack is reproducible across runs.
- Stream logs with docker compose logs on failure to debug flaky services.
Key takeaways
- Compose brings up an entire multi-service stack with one file and one command.
- Pair depends_on with health checks so tests wait for services to be ready, not just started.
- Tear down with down -v to keep runs isolated and reproducible.