Most realistic test scenarios require multiple services running together, such as an application under test plus its database and mocks. Docker Compose allows you to define and start these multi-container stacks with a single command, both locally and in CI.
Defining Multi-Service Test Stacks with Compose
A docker-compose.yml file declares services, images, ports, networks and shared volumes. For example, you might define an app service, a db service and a mock-api service that your tests rely on.
# docker-compose.yml (test stack example)
version: '3.9'
services:
db:
image: postgres:16
environment:
POSTGRES_USER: testuser
POSTGRES_PASSWORD: testpass
POSTGRES_DB: testdb
ports:
- '5432:5432'
mock-api:
image: qa-mock-api:latest
ports:
- '3000:3000'
app:
image: myapp-under-test:latest
environment:
DATABASE_URL: postgres://testuser:testpass@db:5432/testdb
MOCK_API_URL: http://mock-api:3000
depends_on:
- db
- mock-api
db or mock-api without hard-coding IPs.In CI, you typically call docker compose up -d before running your test suite and docker compose down -v afterwards.
Common Mistakes
Mistake 1 โ Hard-coding localhost URLs for services inside containers
This breaks networking.
โ Wrong: Using localhost from one container to reach another.
โ
Correct: Use the Docker Compose service names (like db or mock-api) as hostnames.
Mistake 2 โ Running compose stacks manually without scripts
This reduces repeatability.
โ Wrong: Typing long compose commands by hand each time.
โ
Correct: Wrap compose commands in reusable scripts (for example ./scripts/start-test-stack.sh).