Umgebungsvariablen in Docker Compose - env_file und environment richtig einsetzen
Umgebungsvariablen in Docker Compose - env_file und environment richtig einsetzen
Docker Compose bietet zwei Wege, Umgebungsvariablen an Container zu übergeben — und einen dritten, der oft verwechselt wird.
Variante 1: environment (inline)
Direkt im Compose-File, gut für wenige, nicht-geheime Werte:
services:
app:
image: myapp
environment:
APP_ENV: production
APP_PORT: 8080
DB_HOST: db
Oder als Liste:
environment:
- APP_ENV=production
- APP_PORT=8080
Variable ohne Wert übernimmt den Wert aus der Shell-Umgebung:
environment:
- SECRET_KEY # Wert kommt vom aufrufenden System
Variante 2: env_file (externe Datei)
Für viele Variablen oder wenn Secrets nicht ins Compose-File gehören:
services:
app:
image: myapp
env_file:
- .env
- .env.production
Die .env-Datei hat ein simples Format:
APP_ENV=production
DB_HOST=db
DB_PASSWORD=supersecret
# Kommentare sind erlaubt
Mehrere Dateien werden der Reihe nach geladen — spätere Dateien überschreiben frühere.
Die auto-geladene .env-Datei
Hier liegt die häufigste Verwechslung: Eine .env-Datei im selben Verzeichnis wie das Compose-File wird automatisch geladen — aber nicht als env_file: für Container, sondern für Variable Substitution im Compose-File selbst:
# docker-compose.yml
services:
db:
image: postgres:${PG_VERSION} # Wird aus .env ersetzt
ports:
- "${DB_PORT}:5432"
# .env
PG_VERSION=16
DB_PORT=5432
Das ist praktisch für Versions-Pins und Ports — aber diese Variablen landen nicht automatisch im Container.
Priorität: Wer gewinnt?
Von höchster zu niedrigster Priorität:
- Shell-Umgebungsvariablen des aufrufenden Systems
- Werte in
.env(für Compose-Substitution) - Defaultwerte im Compose-File:
${VAR:-default}
environment:
DB_HOST: ${DB_HOST:-localhost} # Fallback auf localhost wenn nicht gesetzt
.env.example als Konvention
Niemals .env committen. Stattdessen eine .env.example mit allen Keys aber ohne echte Werte:
# .env.example — in Git versioniert
APP_ENV=
DB_HOST=
DB_PASSWORD=
SECRET_KEY=
In .gitignore:
.env
.env.production
.env.local
Neue Entwickler kopieren .env.example zu .env und füllen die Werte aus. So ist klar, welche Variablen erwartet werden, ohne dass Secrets in Git landen.
Zusammenfassung
| | environment: | env_file: | auto .env |
|---|---|---|---|
| Werte sichtbar im Compose-File | Ja | Nein | Nein |
| Geht in Container | Ja | Ja | Nein (nur Substitution) |
| Gut für Secrets | Nein | Ja | Nein |
Die Faustregel: Ports, Feature-Flags und nicht-geheime Konfiguration inline via environment:, Datenbankpasswörter und API-Keys in einer env_file:-Datei, die nicht versioniert wird.