Zum Inhalt springen
Warum .env-Variablen in Docker nicht funktionieren – und wie du Build- und Runtime-Environments richtig trennst

Warum .env-Variablen in Docker nicht funktionieren – und wie du Build- und Runtime-Environments richtig trennst

Warum .env-Variablen in Docker nicht funktionieren – Das Build-Time vs. Runtime Problem

Lokal läuft alles perfekt – aber im Docker-Container fehlen plötzlich bestimmte .env-Variablen. Dieses Problem tritt häufig auf, wenn Anwendungen mit docker-compose und einem Dockerfile gemeinsam betrieben werden. Die Ursache ist fast immer die gleiche: Environment-Variablen stehen im falschen Kontext zur Verfügung.

Das eigentliche Problem: Build-Time vs. Runtime Environment

Docker unterscheidet strikt zwischen zwei Zeitpunkten:

  • Build-Time – Dockerfile wird ausgeführt. Nur ARG und ENV sind verfügbar.
  • Run-Time – Der Container wird gestartet. docker-compose.yml liefert die Variablen.

Und genau hier entsteht das Problem: .env Variablen aus docker-compose werden NICHT in die Dockerfile-Buildphase übernommen. Daher funktioniert es lokal problemlos, aber im Container fehlen Werte.

Warum funktioniert es lokal, aber nicht in Docker?

Lokal kann deine Anwendung direkt auf die .env Datei zugreifen. Im Container hingegen existiert die Datei nicht oder liegt an einer anderen Stelle.

Ergebnis: Die App läuft ohne Environment Werte.

Wie Docker mit .env umgeht

Viele Entwickler glauben, dass Docker Compose automatisch alle Werte aus .env in den Container übernimmt. Das ist falsch.

Docker Compose nutzt die .env Datei ausschließlich um Variablen im Compose File selbst zu ersetzen:

environment:
  APP_ENV: ${APP_ENV}
    

Aber:

Diese Werte sind nur zur Laufzeit verfügbar – nicht im Dockerfile.

Warum du Variablen in Dockerfile UND docker-compose definieren musstest

Das ist ein typischer Workaround, wenn Entwickler nicht wissen, welcher Teil wann ausgeführt wird.

Beispiel:

# Dockerfile
ENV API_URL=${API_URL}
    

Dies funktioniert nur, wenn API_URL als ARG übergeben wird.

# Dockerfile
ARG API_URL
ENV API_URL=${API_URL}
    

Und dann in docker-compose:

build:
  context: .
  args:
    API_URL: ${API_URL}
    

Erst jetzt ist die Variable wirklich in beiden Welten verfügbar.

Die drei zuverlässigen Lösungswege

1. Variablen als ARG während des Builds übergeben

# Dockerfile
ARG APP_URL
ENV APP_URL=${APP_URL}
    
# docker-compose.yml
build:
  args:
    APP_URL: ${APP_URL}
    

2. .env Datei in den Container kopieren (nicht empfohlen!)

Fehleranfällig und unsicher — nur für interne Projekte.

3. Offizielle Empfehlung: ENV nur zur Laufzeit setzen

Wenn dein Build nicht von Variablen abhängt:

environment:
  APP_URL: ${APP_URL}
    

Best Practice: So trennt man Variablen richtig

  • Dockerfile → nur Werte, die beim Build notwendig sind
  • docker-compose → alle Werte, die die App zur Laufzeit braucht

Damit bleibt dein Setup sauber, sicher und nachvollziehbar.

Fazit

Das Problem lässt sich klar benennen: Environment Variables Build-Time vs Runtime Mismatch.

Wenn du verstehst, dass Docker zwei getrennte Welten hat, kannst du Variablen sauber und korrekt übergeben – und solche Fehler gehören der Vergangenheit an.

Brauchst du Hilfe bei Docker oder DevOps? Wir unterstützen beim Aufbau stabiler, sicherer und optimierter Container-Infrastrukturen.