DevToolBoxKOSTENLOS
Blog

.env Datei Guide: Best Practices für Umgebungsvariablen

10 Min. Lesezeitvon DevToolBox

Umgebungsvariablen halten Geheimnisse aus dem Quellcode heraus und ermöglichen Konfigurationsänderungen ohne Redeployment. Die .env-Datei ist die Standardmethode zur lokalen Verwaltung geworden. Dieser Leitfaden behandelt Syntaxregeln, Framework-Setup, Sicherheit, umgebungsspezifische Dateien, Docker-Integration, häufige Fehler und Produktionsalternativen.

.env Syntaxregeln

Eine .env-Datei ist eine Klartextdatei mit einer Variable pro Zeile. Hier sind die Regeln, die jeder Entwickler kennen sollte:

Grundsyntax

Jede Zeile folgt dem KEY=VALUE-Muster. Keine Leerzeichen um das Gleichheitszeichen.

# .env
DATABASE_URL=postgres://localhost:5432/mydb
API_KEY=sk-1234567890abcdef
PORT=3000
DEBUG=true

Anführungszeichenregeln

Werte können ohne Anführungszeichen, in einfachen oder doppelten Anführungszeichen stehen. Das Verhalten unterscheidet sich:

# Unquoted — trailing whitespace trimmed
APP_NAME=My Application

# Single quotes — literal, no interpolation
PASSWORD='p@$$w0rd#123'

# Double quotes — escape sequences + interpolation
GREETING="Hello\nWorld"
FULL_URL="${BASE_URL}/api/v1"
  • Ohne Anführungszeichen: nachfolgende Leerzeichen werden entfernt, keine Escape-Sequenzen.
  • Einfache Anführungszeichen: Wert wird wörtlich übernommen, keine Interpolation, kein Escaping.
  • Doppelte Anführungszeichen: unterstützt Escape-Sequenzen (\n, \t) und Variableninterpolation.

Mehrzeilige Werte

Verwenden Sie doppelte Anführungszeichen und \n für Zeilenumbrüche oder tatsächliche Zeilenumbrüche in doppelten Anführungszeichen:

# Method 1: \n in double quotes
PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----\nMIIEpAIB...\n-----END RSA PRIVATE KEY-----"

# Method 2: actual newlines in double quotes
PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEA...
-----END RSA PRIVATE KEY-----"

Kommentare

Zeilen, die mit # beginnen, sind Kommentare. Inline-Kommentare funktionieren nur bei nicht-gequoteten Werten in einigen Parsern:

# This is a full-line comment
DATABASE_URL=postgres://localhost/mydb  # inline comment (some parsers)

# Empty lines are ignored

API_KEY=abc123  # This may or may not work depending on the parser

Variableninterpolation

Referenzieren Sie andere Variablen mit ${VAR}-Syntax (von den meisten Parsern in doppelt gequoteten Werten unterstützt):

BASE_URL=https://api.example.com
API_V1=${BASE_URL}/v1
API_V2=${BASE_URL}/v2

DB_HOST=localhost
DB_PORT=5432
DB_NAME=myapp
DATABASE_URL=postgres://${DB_HOST}:${DB_PORT}/${DB_NAME}

Framework-Setup

Node.js (dotenv)

Der beliebteste .env-Loader für Node.js. Installation und Konfiguration:

# Install
npm install dotenv

# --- app.js (CommonJS) ---
require('dotenv').config();
console.log(process.env.DATABASE_URL);

# --- app.ts (ES Modules) ---
import 'dotenv/config';
console.log(process.env.DATABASE_URL);

# --- Or load from CLI ---
node -r dotenv/config app.js
node -r dotenv/config app.js dotenv_config_path=.env.local

Next.js, Vite und Create React App laden .env-Dateien automatisch — kein Paket nötig.

Python (python-dotenv)

.env in Python-Projekten laden:

# Install
pip install python-dotenv

# --- app.py ---
from dotenv import load_dotenv
import os

load_dotenv()  # loads .env from current directory
# load_dotenv('.env.local')  # or specify a path

database_url = os.getenv('DATABASE_URL')
print(database_url)

# --- Django: manage.py or settings.py ---
from dotenv import load_dotenv
from pathlib import Path

env_path = Path('.') / '.env'
load_dotenv(dotenv_path=env_path)

Go (godotenv)

.env in Go-Projekten laden:

// Install
// go get github.com/joho/godotenv

package main

import (
    "fmt"
    "log"
    "os"
    "github.com/joho/godotenv"
)

func main() {
    err := godotenv.Load()  // loads .env
    if err != nil {
        log.Fatal("Error loading .env file")
    }
    dbURL := os.Getenv("DATABASE_URL")
    fmt.Println(dbURL)
}

PHP (vlucas/phpdotenv)

Wird von Laravel und den meisten PHP-Frameworks verwendet:

// Install
// composer require vlucas/phpdotenv

<?php
require 'vendor/autoload.php';

$dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
$dotenv->load();

// Access variables
$dbUrl = $_ENV['DATABASE_URL'];
// or
$dbUrl = getenv('DATABASE_URL');

// Required variables (throws exception if missing)
$dotenv->required(['DATABASE_URL', 'API_KEY']);

Ruby (dotenv Gem)

Wird von Rails und anderen Ruby-Projekten verwendet:

# Gemfile
gem 'dotenv-rails', groups: [:development, :test]

# Or for non-Rails Ruby:
gem 'dotenv'

# --- app.rb ---
require 'dotenv/load'
puts ENV['DATABASE_URL']

# --- Rails: .env is loaded automatically ---
# Access via ENV['DATABASE_URL'] anywhere in your app

Sicherheit: .env-Dateien niemals committen

Ihre .env-Datei enthält Geheimnisse (API-Schlüssel, Datenbankpasswörter, Tokens). Sie in die Versionskontrolle zu committen ist der Sicherheitsfehler Nr. 1.

.gitignore Muster

Fügen Sie diese Muster sofort zu Ihrer .gitignore-Datei hinzu:

# .gitignore

# Ignore all .env files
.env
.env.local
.env.*.local
.env.development
.env.production

# More aggressive pattern — ignore all .env variants
.env*

# But DO commit the example file
!.env.example

.env.example verwenden

Committen Sie eine .env.example-Datei mit leeren Werten, damit Teammitglieder wissen, welche Variablen benötigt werden:

# .env.example — commit this file
# Copy to .env and fill in your values

DATABASE_URL=
API_KEY=
SMTP_HOST=
SMTP_PORT=587
SMTP_USER=
SMTP_PASS=
REDIS_URL=
JWT_SECRET=

# Optional
DEBUG=false
LOG_LEVEL=info

.env bereits committet?

Wenn Sie versehentlich eine .env-Datei committet haben, entfernen Sie sie aus dem Tracking und rotieren Sie alle Geheimnisse:

# Step 1: Remove .env from Git tracking (keeps local file)
git rm --cached .env

# Step 2: Add to .gitignore
echo ".env" >> .gitignore

# Step 3: Commit the removal
git add .gitignore
git commit -m "Remove .env from tracking, add to .gitignore"

# Step 4: CRITICAL — Rotate ALL secrets in the .env file
# Every API key, password, and token that was exposed
# must be regenerated immediately

Umgebungsspezifische Dateien

Die meisten Frameworks unterstützen mehrere .env-Dateien für verschiedene Umgebungen. Das Verständnis der Ladereihenfolge ist entscheidend.

Ladereihenfolge (Next.js / Vite / CRA)

Dateien werden in dieser Priorität geladen (spätere Dateien überschreiben frühere):

# Loading priority (highest to lowest):

# 1. Shell environment variables (always win)
# 2. .env.{NODE_ENV}.local   (e.g. .env.production.local)
# 3. .env.local               (NOT loaded in test)
# 4. .env.{NODE_ENV}          (e.g. .env.production)
# 5. .env                     (default fallback)

# Example for NODE_ENV=production:
# .env                     → loaded first (base defaults)
# .env.production          → overrides .env
# .env.local               → overrides .env.production
# .env.production.local    → overrides everything above

.env.local wird immer von git ignoriert (zu .gitignore hinzufügen). Es wird NICHT während Tests geladen, um Tests deterministisch zu halten.

Welche Datei für was?

FilePurposeGit
.envDefault values, non-secret configCommit
.env.exampleTemplate with empty valuesCommit
.env.localLocal secrets & overridesIgnore
.env.developmentDev-specific (shared)Commit
.env.productionProduction-specific (non-secret)Commit
.env.testTest environment configCommit
.env.production.localProduction secrets (local only)Ignore

Docker & Docker Compose Integration

env_file Direktive

Docker Compose kann .env-Dateien direkt in Container laden:

# docker-compose.yml (or compose.yml)
services:
  web:
    image: node:20-alpine
    env_file:
      - .env                  # base defaults
      - .env.production       # production overrides
    ports:
      - "3000:3000"

  db:
    image: postgres:16
    env_file:
      - .env.db               # separate file for DB secrets
    volumes:
      - pgdata:/var/lib/postgresql/data

environment vs env_file

Sie können Umgebungsvariablen auch inline setzen. Hier ist der Unterschied:

# Using env_file (loads from file)
services:
  web:
    env_file:
      - .env

# Using environment (inline)
services:
  web:
    environment:
      - NODE_ENV=production
      - PORT=3000
      - DATABASE_URL=${DATABASE_URL}   # from shell or .env

# Using environment (mapping syntax)
services:
  web:
    environment:
      NODE_ENV: production
      PORT: 3000
  • env_file: lädt aus Datei, hält compose.yml sauber, leicht pro Umgebung wechselbar.
  • environment: in compose.yml sichtbar, gut für nicht-geheime Werte, unterstützt Variablensubstitution.

.env für Docker Compose Variablen

Docker Compose liest automatisch eine .env-Datei im Projektstammverzeichnis für Variablensubstitution in compose.yml:

# .env (in same directory as compose.yml)
POSTGRES_VERSION=16
NODE_VERSION=20
APP_PORT=3000

# compose.yml — uses .env for variable substitution
services:
  web:
    image: node:${NODE_VERSION}-alpine
    ports:
      - "${APP_PORT}:3000"

  db:
    image: postgres:${POSTGRES_VERSION}
    environment:
      POSTGRES_DB: myapp

10 häufige .env-Fehler und Lösungen

Die häufigsten .env-Probleme, auf die Entwickler stoßen:

#FehlerUrsacheLösung
1process.env.VAR ist undefineddotenv nicht geladen oder nach Verwendung geladendotenv.config() ganz oben in der Einstiegsdatei aufrufen
2Variablen in Produktion leer.env-Datei nicht deployed; Abhängigkeit von Datei statt Plattform-UmgebungsvariablenUmgebungsvariablen in der Hosting-Plattform setzen (Vercel, AWS, etc.)
3.env-Werte enthalten AnführungszeichenParser behandelt Anführungszeichen als literale ZeichenParser-Dokumentation prüfen
4Falsche .env-Datei geladenArbeitsverzeichnis weicht vom erwarteten Pfad abpath-Option verwenden: dotenv.config({ path: ".env.local" })
5Mehrzeiliger Wert abgeschnittenWert nicht korrekt in doppelten AnführungszeichenMehrzeilige Werte in doppelte Anführungszeichen einschließen
6Sonderzeichen beschädigen Wert$ oder # als Interpolation/Kommentar interpretiertEinfache Anführungszeichen verwenden oder mit \ escapen
7BOM-Encoding-FehlerWindows-Editor speichert .env mit UTF-8 BOMAls UTF-8 ohne BOM speichern
8Docker-Container-Umgebungsvariablen leerenv_file-Pfad falsch oder Datei nicht im Build-KontextPfad relativ zum compose.yml-Speicherort überprüfen
9Leerzeichen um = brechen ParsingKEY = VALUE statt KEY=VALUELeerzeichen um das Gleichheitszeichen entfernen
10Variablen im Browser nicht verfügbar (React/Next)Erforderliches Präfix fehlt (NEXT_PUBLIC_ oder REACT_APP_)Framework-erforderliches Präfix hinzufügen

Produktionsalternativen

In der Produktion werden .env-Dateien nicht empfohlen. Verwenden Sie stattdessen diese Alternativen:

Plattform-Umgebungsvariablen

Jede große Hosting-Plattform bietet UI oder CLI zum Setzen von Umgebungsvariablen:

# Vercel
vercel env add DATABASE_URL production
vercel env ls

# AWS (Parameter Store)
aws ssm put-parameter \
  --name "/myapp/prod/DATABASE_URL" \
  --value "postgres://..." \
  --type SecureString

# Heroku
heroku config:set DATABASE_URL=postgres://...
heroku config

# Railway
railway variables set DATABASE_URL=postgres://...

# Fly.io
fly secrets set DATABASE_URL=postgres://...

Docker Secrets

Für Docker Swarm oder Compose verwenden Sie Secrets für sensible Daten:

# compose.yml with Docker secrets
services:
  web:
    image: myapp:latest
    secrets:
      - db_password
      - api_key
    environment:
      DB_PASSWORD_FILE: /run/secrets/db_password

secrets:
  db_password:
    file: ./secrets/db_password.txt    # for Compose
    # external: true                    # for Swarm
  api_key:
    file: ./secrets/api_key.txt

# In your app, read from file:
# const secret = fs.readFileSync('/run/secrets/db_password', 'utf8').trim();

Secret Manager (Vault, AWS Secrets Manager)

Für Enterprise-Anwendungen einen dedizierten Secret Manager verwenden:

# HashiCorp Vault
vault kv put secret/myapp/production \
  DATABASE_URL="postgres://..." \
  API_KEY="sk-..."

# Read in application
vault kv get -field=DATABASE_URL secret/myapp/production

# AWS Secrets Manager
aws secretsmanager create-secret \
  --name "myapp/production/db" \
  --secret-string '{"url":"postgres://...","password":"..."}'

# Read in Node.js with AWS SDK
import { SecretsManager } from '@aws-sdk/client-secrets-manager';
const client = new SecretsManager({ region: 'us-east-1' });
const { SecretString } = await client.getSecretValue({
  SecretId: 'myapp/production/db'
});
const secrets = JSON.parse(SecretString);

Secret Manager bieten Rotation, Audit-Logging, Zugriffskontrolle und Verschlüsselung im Ruhezustand — Funktionen, die .env-Dateien nicht bieten können.

Häufig gestellte Fragen

Sollte ich meine .env-Datei in Git committen?

Committen Sie niemals .env-Dateien mit Geheimnissen in die Versionskontrolle. Committen Sie stattdessen eine .env.example-Datei mit leeren Platzhalterwerten. Fügen Sie .env*-Muster zu Ihrer .gitignore hinzu.

Was ist der Unterschied zwischen .env, .env.local und .env.production?

.env enthält Standardwerte für alle Umgebungen. .env.local enthält lokale Überschreibungen und wird nicht committet. .env.production enthält produktionsspezifische Werte, die nur bei NODE_ENV=production geladen werden.

Warum ist process.env.MY_VAR in Node.js undefined?

Häufigste Ursachen: 1) Vergessen, require("dotenv").config() oben aufzurufen, 2) .env-Datei nicht im Stammverzeichnis, 3) Tippfehler im Variablennamen, 4) Bei ES-Modulen "import dotenv/config" verwenden.

Wie verwende ich .env-Variablen in Docker Compose?

Docker Compose liest automatisch eine .env-Datei im selben Verzeichnis wie compose.yml für ${VAR}-Variablensubstitution. Verwenden Sie env_file oder environment zum Weitergeben an Container.

Kann ich .env-Dateien in der Produktion verwenden?

Nicht empfohlen. In der Produktion verwenden Sie Plattform-Umgebungsvariablen, Docker Secrets oder einen Secret Manager wie HashiCorp Vault oder AWS Secrets Manager.

Wie exponiere ich .env-Variablen an den Browser in React oder Next.js?

In Next.js mit NEXT_PUBLIC_-Präfix. In Create React App REACT_APP_-Präfix. In Vite VITE_-Präfix. Nur präfixierte Variablen werden in das Client-Bundle eingebettet.

𝕏 Twitterin LinkedIn
War das hilfreich?

Bleiben Sie informiert

Wöchentliche Dev-Tipps und neue Tools.

Kein Spam. Jederzeit abbestellbar.

Verwandte Tools ausprobieren

🐳Docker Compose Generator.gi.gitignore GeneratorNXNginx Config Generator

Verwandte Artikel

Docker Compose Spickzettel: Services, Volumes und Netzwerke

Docker Compose Referenz: Service-Definitionen, Volumes, Netzwerke, Umgebungsvariablen und Stack-Beispiele.

Docker Compose env_file vs environment: Wann was verwenden (mit Beispielen)

Verstehen Sie den Unterschied zwischen env_file und environment in Docker Compose. Anwendungsfälle, Variablenpriorität und Multi-Environment-Setups.