Skip to content

Multi-Service Apps

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:24-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:18-alpine
environment:
- POSTGRES_DB=mydb
- POSTGRES_USER=user
- POSTGRES_PASSWORD=secret

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:
- db

Health-checked start order (production pattern):

services:
app:
depends_on:
db:
condition: service_healthy
db:
image: postgres:18-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=secret

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) -->

Stream logs from all services at once:

Terminal window
docker compose logs -f

Follow only one service:

Terminal window
docker compose logs -f app

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:18-alpine
    environment:
      - POSTGRES_PASSWORD=secret
EOF

# Start both services (app waits 3s then probes db)
docker compose up

# Clean up
docker compose down
OptionBenefitCost
Docker ComposeWires up several services with one file, get a full local run in secondsRuns on a single host — no cross-node orchestration as the number of services grows
KubernetesManages service-to-service communication across a cluster with self-healingNeeds separate Service, Deployment, and network policy objects — much more complex than a compose.yaml
  • Assuming depends_on: - db guarantees db is ready to accept connections before app starts, when it only controls container start order — use healthcheck with condition: service_healthy if you need to wait for real readiness.
  • Hardcoding an IP address or localhost instead of the service name when connecting to the database, breaking networking the moment the container is recreated with a new IP.
  • Forgetting that the network Compose creates automatically is project-scoped — running several projects with similar directory names can accidentally create duplicate networks.

💡 Real-world example

A common pipeline in real teams runs app + db locally with Docker Compose during development for a fast, complete dev experience, then deploys the same image to Kubernetes in production, replacing depends_on with a readiness probe and the Compose network with a Kubernetes Service — the application code does not change, only the orchestration layer.

How does the app service connect to the database in a Compose app?
What does depends_on: - db guarantee?
Which command streams logs from all services simultaneously?
What creates the internal network that connects all Compose services?