ARG vs ENV im Dockerfile - Build-Zeit gegen Laufzeit

ARG vs ENV im Dockerfile - Build-Zeit gegen Laufzeit

ARG und ENV werden beide im Dockerfile definiert — aber sie leben in unterschiedlichen Phasen. Das zu verwechseln führt zu Builds, die sich nicht wie erwartet verhalten.

ARG: nur während des Builds

ARG definiert eine Variable, die ausschließlich während docker build existiert. Im laufenden Container ist sie nicht mehr vorhanden.

ARG NODE_VERSION=20
FROM node:${NODE_VERSION}-alpine
# Standard verwenden
docker build -t myapp .

# Override beim Build
docker build --build-arg NODE_VERSION=18 -t myapp .

Nach dem Build ist NODE_VERSION im Container nicht mehr sichtbar.

ENV: Build-Zeit und Laufzeit

ENV setzt eine Umgebungsvariable, die sowohl während des Builds als auch im laufenden Container verfügbar ist.

ENV APP_ENV=production
ENV PORT=8080

Im Container:

docker run myapp env | grep APP_ENV
# APP_ENV=production

ENV-Werte lassen sich auch beim Start überschreiben:

docker run -e APP_ENV=development myapp

Kombination: ARG als Input für ENV

Das häufigste Pattern: ARG empfängt den Build-Parameter, ENV macht ihn zur Laufzeit verfügbar:

ARG APP_VERSION=1.0.0
ENV APP_VERSION=${APP_VERSION}
docker build --build-arg APP_VERSION=2.3.1 -t myapp .
# Im Container: APP_VERSION=2.3.1

Sicherheitsaspekte

Beide sind kein sicherer Speicherort für Secrets:

  • ARG-Werte sind in docker history sichtbar — auch wenn sie nach der Verwendung überschrieben werden:
docker history --no-trunc myimage
# Zeigt: |1 SECRET_KEY=abc123 ...
  • ENV-Werte sind via docker inspect abrufbar:
docker inspect mycontainer | grep -A 10 '"Env"'

Für Secrets — Datenbankpasswörter, API-Keys — Docker Secrets (Swarm), externe Secret-Manager oder zur Laufzeit gemountete Dateien verwenden. Niemals ARG oder ENV für sensitive Daten.

Gültigkeitsbereich von ARG

ARG gilt nur innerhalb der Stage, in der es definiert wurde. In Multi-Stage Builds muss es pro Stage neu deklariert werden:

ARG VERSION=1.0

FROM alpine AS builder
ARG VERSION   # ohne das: VERSION ist hier leer
RUN echo "Building version $VERSION"

FROM alpine AS runtime
ARG VERSION   # ohne das: VERSION ist hier ebenfalls leer
LABEL version="$VERSION"