Multi-Service Apps
Running a web app and a database together
Section titled “Running a web app and a database together”Almost every real application needs a database. With Docker Compose you define both services in one file and Compose handles the networking automatically — no manual docker network create required.
Here is a web app backed by PostgreSQL:
services: app: image: node:22-alpine working_dir: /app command: ["node", "server.js"] ports: - "3000:3000" environment: - DATABASE_HOST=db - DATABASE_PORT=5432 - DATABASE_NAME=mydb depends_on: - db
db: image: postgres:17-alpine environment: - POSTGRES_DB=mydb - POSTGRES_USER=user - POSTGRES_PASSWORD=secretdepends_on — start order
Section titled “depends_on — start order”depends_on tells Compose to start the db service before app. This controls container start order, not readiness — the database process inside the container may not be accepting connections the instant the container starts. For production, add a healthcheck to db and use depends_on: condition: service_healthy in app.
Basic start order (sufficient for learning and development):
depends_on: - dbHealth-checked start order (production pattern):
services: app: depends_on: db: condition: service_healthy
db: image: postgres:17-alpine healthcheck: test: ["CMD-SHELL", "pg_isready -U user -d mydb"] interval: 5s timeout: 5s retries: 5 environment: - POSTGRES_DB=mydb - POSTGRES_USER=user - POSTGRES_PASSWORD=secretAutomatic networking
Section titled “Automatic networking”When you run docker compose up, Compose automatically creates a network for your project. Every service in the file is attached to that network. Services reach each other using their service name as the hostname.
In the example above, app connects to the database at host db port 5432 — exactly the service name. No IP addresses, no manual network configuration.
app --[db:5432]--> db <-- myapp-network (auto-created) -->Viewing logs from multiple services
Section titled “Viewing logs from multiple services”Stream logs from all services at once:
docker compose logs -fFollow only one service:
docker compose logs -f appHands-on practice
Section titled “Hands-on practice”The snippet below starts an app container that connects to a PostgreSQL container using the service name db.
# Write a two-service compose.yaml
cat > compose.yaml <<'EOF'
services:
app:
image: alpine
command: >
sh -c "
echo 'Waiting for db...' &&
sleep 3 &&
echo 'Connecting to db:5432 (postgres service)' &&
nc -zv db 5432 &&
echo 'Connection to db succeeded via service name DNS!'
"
depends_on:
- db
db:
image: postgres:17-alpine
environment:
- POSTGRES_PASSWORD=secret
EOF
# Start both services (app waits 3s then probes db)
docker compose up
# Clean up
docker compose down