Meerdere containers beheren met Docker Compose
In het vorige hoofdstuk leerde je hoe je één container opstart. Maar een echte webapplicatie bestaat bijna nooit uit één container. Je hebt bijvoorbeeld een Node.js app én een PostgreSQL database nodig.
Beide containers apart opstarten, configureren en koppelen is omslachtig en foutgevoelig. Docker Compose lost dit op.
Wat is Docker Compose?
Docker Compose is een tool waarmee je meerdere containers definieert en beheert in één YAML-bestand. Met één commando start je alle containers tegelijk op, en met één commando stop je ze weer.
Docker Compose wordt meegeleverd met Docker Desktop. Je hoeft niets extra te installeren.
De oudere versie van Compose gebruikte het commando docker-compose (met een koppelteken). De moderne versie, die meekomt met Docker Desktop, gebruikt docker compose (met een spatie). Gebruik altijd de nieuwe variant met een spatie.
De docker-compose.yml
Je definieert je applicatie in een bestand dat je docker-compose.yml noemt. Dit bestand staat in de root van je project.
De structuur ziet er zo uit:
services:
service-name:
image: image-name
ports:
- '8080:80'
environment:
- VARIABLE=value
depends_on:
- other-service
volumes:
- my-volume:/path/in/container
volumes:
my-volume:
De belangrijkste onderdelen:
| Sleutel | Uitleg |
|---|---|
services | Alle containers die je wilt draaien. Elke service is één container. |
image | De image die Docker gebruikt. Of gebruik build om een lokale Dockerfile te bouwen. |
ports | Koppelt een poort op je computer aan een poort in de container. |
environment | Omgevingsvariabelen die de container meekrijgt. |
depends_on | Wacht met starten totdat een andere service klaar is. |
volumes | Koppelt opslag aan de container, zodat data niet verloren gaat. |
Een praktisch voorbeeld
We bouwen een eenvoudige setup: een Node.js app die verbinding maakt met een PostgreSQL database.
services:
app:
build: .
ports:
- '3000:3000'
environment:
- DATABASE_URL=postgres://postgres:secret@db:5432/mydb
depends_on:
- db
db:
image: postgres:16-alpine
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=secret
- POSTGRES_DB=mydb
volumes:
- db-data:/var/lib/postgresql/data
volumes:
db-data:
En de bijbehorende Dockerfile voor de Node.js app:
FROM node:22-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]
Wat er hier gebeurt:
appwordt gebouwd vanuit de lokaleDockerfile(vandaarbuild: .).dbgebruikt de officiële PostgreSQL image.appkrijgt deDATABASE_URLmee als omgevingsvariabele, metdbals hostnaam. Docker Compose zorgt ervoor dat services elkaar via hun servicenaam kunnen bereiken.depends_onzorgt dat de database eerst opstart voordat de app begint.- Het
db-datavolume zorgt dat de database-inhoud bewaard blijft, ook na het stoppen.
Compose opstarten en stoppen
Start alle services in één keer op:
$ docker compose up
Wil je de containers op de achtergrond draaien? Gebruik de -d vlag (detached):
$ docker compose up -d
Stop alle containers en verwijder de netwerken:
$ docker compose down
Bekijk de logs van alle services in real time:
$ docker compose logs -f
Gebruik docker compose logs -f app om alleen de logs van één specifieke service te bekijken.
Volumes voor data
Zonder een volume verlies je alle data in je database zodra je docker compose down uitvoert. Docker gooit de container weg, inclusief alles wat erin stond.
Met een named volume slaat Docker de data op buiten de container. De volgende keer dat je opstart, staat alle data er nog. Declareer het volume altijd op twee plekken: bij de service én onderaan in het volumes blok.
services:
db:
image: postgres:16-alpine
volumes:
- db-data:/var/lib/postgresql/data # volume koppelen
volumes:
db-data: # volume declareren
Omgevingsvariabelen
Wachtwoorden en geheime sleutels horen niet rechtstreeks in je docker-compose.yml. Gebruik een .env bestand. Docker Compose leest dit bestand automatisch in.
POSTGRES_PASSWORD=secret
DATABASE_URL=postgres://postgres:secret@db:5432/mydb
services:
app:
build: .
environment:
- DATABASE_URL=${DATABASE_URL}
db:
image: postgres:16-alpine
environment:
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
Voeg .env toe aan je .gitignore, zodat je wachtwoorden niet in versiebeheer terechtkomen. Lees meer over veilig omgaan met omgevingsvariabelen in het hoofdstuk over omgevingsvariabelen.
Handige Compose-commando's
| Commando | Wat het doet |
|---|---|
docker compose up | Start alle services op. |
docker compose up -d | Start alle services op de achtergrond. |
docker compose down | Stopt alle services en verwijdert de netwerken. |
docker compose ps | Toont alle draaiende services en hun status. |
docker compose logs -f | Volgt de logs van alle services live. |
docker compose exec app sh | Opent een shell in de app container. |
docker compose build | Bouwt alle images opnieuw. |
docker compose restart | Herstart alle services. |
Met Docker Compose beheer je een volledige applicatieomgeving als één geheel. Je hoeft nooit meer individuele containers handmatig op te starten of te stoppen.