Secrets en configuratie beheren met Docker Compose

Hoe zorg je ervoor dat gevoelige gegevens veilig blijven in een Docker Compose setup? Praktische aanpak voor secrets, environment variabelen en config management.

Jean-Pierre Broeders

Freelance DevOps Engineer

2 maart 20265 min. leestijd

Secrets en configuratie beheren met Docker Compose

Ergens in een .env bestand op een productieserver staan database wachtwoorden in plain text. Herkenbaar? Het gebeurt vaker dan je denkt. Docker Compose maakt het makkelijk om snel iets op te zetten, maar dat gemak heeft een keerzijde: gevoelige configuratie belandt al snel op plekken waar het niet hoort.

Het probleem met .env bestanden

De standaard aanpak is simpel. Gooi alles in een .env, refereer ernaar in docker-compose.yml, klaar. Werkt prima voor development. Maar in productie loop je tegen een paar vervelende dingen aan.

Ten eerste: .env bestanden worden regelmatig per ongeluk gecommit. Ja, .gitignore bestaat. Nee, niet iedereen configureert het correct. Een snelle git add . en het staat op GitHub. Soms in een publieke repo.

Ten tweede: alle secrets staan bij elkaar. De database credentials naast de SMTP configuratie naast de API keys van externe diensten. Eén lek en alles ligt op straat.

# Dit ziet er onschuldig uit, maar...
DB_PASSWORD=supergeheim123
SMTP_PASSWORD=ookgeheim
STRIPE_SECRET_KEY=sk_live_ditmagnietuitlekken

Docker Secrets: de ingebouwde oplossing

Docker heeft een secrets mechanisme. In Swarm mode werkt dat out-of-the-box, maar ook zonder Swarm valt er iets te doen met file-based secrets.

services:
  api:
    image: myapp:latest
    secrets:
      - db_password
      - smtp_password
    environment:
      DB_PASSWORD_FILE: /run/secrets/db_password

secrets:
  db_password:
    file: ./secrets/db_password.txt
  smtp_password:
    file: ./secrets/smtp_password.txt

Het verschil? Secrets worden gemount als bestanden in /run/secrets/, niet als environment variabelen. Dat is veiliger. Environment variabelen duiken op in docker inspect, in logs, in crash dumps. Bestanden in /run/secrets/ niet.

Wel moet de applicatie ermee overweg kunnen. Veel frameworks ondersteunen de _FILE suffix conventie — Laravel, Node.js libraries, Postgres images. De applicatie leest dan het pad uit DB_PASSWORD_FILE en haalt daar de waarde op.

Meerdere omgevingen scheiden

Een compose setup die zowel staging als productie bedient, vraagt om een duidelijke scheiding. Override files zijn daar perfect voor.

# Base configuratie
docker-compose.yml

# Omgeving-specifieke overrides
docker-compose.staging.yml
docker-compose.production.yml

De base file bevat alles wat gedeeld wordt. Services, netwerken, volumes. De override files voegen omgeving-specifieke zaken toe: andere images, andere resource limits, andere secrets.

# docker-compose.production.yml
services:
  api:
    image: myapp:v2.3.1  # Pinned versie, geen :latest
    deploy:
      resources:
        limits:
          memory: 512M
    secrets:
      - prod_db_password
    logging:
      driver: json-file
      options:
        max-size: "10m"
        max-file: "3"

secrets:
  prod_db_password:
    file: /etc/myapp/secrets/db_password

Starten gaat dan met:

docker compose -f docker-compose.yml -f docker-compose.production.yml up -d

Het mooie hieraan: de productie secrets staan op een compleet andere plek dan de staging secrets. Geen verwarring mogelijk.

Externe secret managers koppelen

Voor serieuze setups is het slim om secrets niet als bestanden op de server te bewaren, maar uit een vault te halen. HashiCorp Vault, AWS Secrets Manager, Azure Key Vault — ze doen allemaal hetzelfde: secrets centraal opslaan en on-demand beschikbaar maken.

Een pragmatische aanpak zonder de hele infrastructuur om te gooien:

#!/bin/bash
# pull-secrets.sh - draait voor docker compose up

set -euo pipefail

mkdir -p /tmp/app-secrets

# Haal secrets op uit vault
vault kv get -field=password secret/myapp/db > /tmp/app-secrets/db_password
vault kv get -field=key secret/myapp/stripe > /tmp/app-secrets/stripe_key

# Zet permissies strak
chmod 600 /tmp/app-secrets/*

# Start de stack
docker compose up -d

# Ruim op (secrets staan nu alleen in de containers)
rm -rf /tmp/app-secrets

Niet de meest elegante oplossing ter wereld, maar het werkt. De secrets bestaan kort op disk, worden in de containers geladen en daarna opgeruimd. Beter dan permanent in een .env bestand.

Rotatie zonder downtime

Wachtwoorden veranderen. API keys verlopen. Secrets moeten geroteerd kunnen worden zonder de hele boel plat te leggen.

Met file-based secrets is dat relatief eenvoudig:

  1. Update het secret bestand
  2. Herstart alleen de service die het nodig heeft: docker compose restart api
  3. De container pikt het nieuwe bestand op bij het starten

Bij environment variabelen-gebaseerde secrets is een volledige recreate nodig:

docker compose up -d --force-recreate api

Dat is disruptiever. Nog een reden om file-based secrets te prefereren boven environment variabelen.

Praktische checklist

Een paar dingen die helpen om secrets onder controle te houden:

  • Scan je repo met tools als gitleaks of trufflehog. Automatisch, in CI. Niet handmatig.
  • Gebruik .env.example in de repo met dummy waarden. Nieuwe teamleden weten dan welke variabelen nodig zijn zonder de echte waarden te zien.
  • Zet file permissions goed. Secrets bestanden: chmod 600. Alleen de eigenaar mag lezen.
  • Roteer regelmatig. Stel een reminder in. Elke 90 dagen op z'n minst voor database wachtwoorden.
  • Log geen secrets. Klinkt voor de hand liggend, maar check je applicatie logging. Een debug statement dat het hele environment dumpt, is sneller geschreven dan je denkt.

Afsluiting

Secrets management hoeft niet complex te zijn. Begin met het scheiden van configuratie en secrets, gebruik file-based secrets waar mogelijk, en bouw van daaruit verder. Perfect is de vijand van goed genoeg — een .env bestand dat niet in git staat is al een enorme verbetering ten opzichte van hardcoded credentials in de broncode. Maar er is meer mogelijk, en de stap naar Docker secrets of een externe vault is kleiner dan het lijkt.

Wil je op de hoogte blijven?

Schrijf je in voor mijn nieuwsbrief of neem contact op voor freelance projecten.

Neem Contact Op