ENV Dateien Umgebungsvariablen
Umgebungsvariablen und .env Dateien richtig nutzen
Umgebungsvariablen trennen Konfiguration vom Code. Passwörter, API-Keys und Einstellungen gehören nicht in den Quellcode, sondern in .env Dateien.
Warum Umgebungsvariablen?
- Sicherheit: Sensible Daten nicht im Code/Git
- Flexibilität: Unterschiedliche Einstellungen pro Umgebung
- 12-Factor-App: Best Practice für moderne Anwendungen
- Einfaches Deployment: Konfiguration ohne Code-Änderung
Grundlagen: .env Datei
Format
# .env Datei # Kommentare beginnen mit # DATABASE_HOST=localhost DATABASE_PORT=5432 DATABASE_NAME=myapp DATABASE_USER=admin DATABASE_PASSWORD=geheimes_passwort # Strings mit Leerzeichen in Anführungszeichen APP_NAME="Meine Anwendung" # Boolean als String DEBUG=true # URLs API_URL=https://api.example.com REDIS_URL=redis://localhost:6379
.env NIEMALS committen!
# .gitignore .env .env.local .env.*.local
.env.example als Vorlage
# .env.example (wird committet) DATABASE_HOST=localhost DATABASE_PORT=5432 DATABASE_NAME= DATABASE_USER= DATABASE_PASSWORD= DEBUG=false API_URL=
Umgebungsspezifische Dateien
| Datei | Zweck | Committen? |
|---|---|---|
.env |
Standard/Entwicklung | Nein |
.env.local |
Lokale Überschreibungen | Nein |
.env.development |
Entwicklungsumgebung | Optional |
.env.production |
Produktionsumgebung | Nein |
.env.example |
Vorlage für Teammitglieder | Ja |
Node.js: dotenv
# Installation npm install dotenv
// Am Anfang der Anwendung laden
require('dotenv').config();
// Oder mit ES Modules
import 'dotenv/config';
// Variablen nutzen
const dbHost = process.env.DATABASE_HOST;
const dbPort = parseInt(process.env.DATABASE_PORT);
const isDebug = process.env.DEBUG === 'true';
// Mit Fallback
const port = process.env.PORT || 3000;
TypeScript mit Validierung
// config.ts
import { z } from 'zod';
import 'dotenv/config';
const envSchema = z.object({
DATABASE_HOST: z.string(),
DATABASE_PORT: z.string().transform(Number),
DATABASE_NAME: z.string(),
DATABASE_USER: z.string(),
DATABASE_PASSWORD: z.string(),
DEBUG: z.enum(['true', 'false']).transform(v => v === 'true'),
});
export const config = envSchema.parse(process.env);
Python: python-dotenv
# Installation pip install python-dotenv
import os
from dotenv import load_dotenv
# .env laden
load_dotenv()
# Variablen nutzen
db_host = os.getenv('DATABASE_HOST')
db_port = int(os.getenv('DATABASE_PORT', '5432'))
debug = os.getenv('DEBUG', 'false').lower() == 'true'
# Pflichtfelder prüfen
api_key = os.environ['API_KEY'] # Wirft KeyError wenn fehlt
PHP: vlucas/phpdotenv
# Installation composer require vlucas/phpdotenv
<?php
require 'vendor/autoload.php';
$dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
$dotenv->load();
// Pflichtfelder definieren
$dotenv->required(['DATABASE_HOST', 'DATABASE_NAME']);
// Variablen nutzen
$dbHost = $_ENV['DATABASE_HOST'];
$debug = $_ENV['DEBUG'] === 'true';
// Oder mit getenv()
$apiKey = getenv('API_KEY');
Docker und .env
docker-compose.yml
version: '3.8'
services:
app:
build: .
env_file:
- .env
environment:
- NODE_ENV=production
# Einzelne Variable aus .env
- DATABASE_URL=${DATABASE_URL}
Dockerfile
# Build-Zeit Variablen
ARG NODE_ENV=production
# Laufzeit Variablen
ENV NODE_ENV=${NODE_ENV}
# Nicht empfohlen: Sensible Daten im Image
# ENV API_KEY=xxx # NIEMALS so!
Sicherheits-Best-Practices
⚠️ Sicherheitsregeln:
- .env Dateien NIEMALS ins Git committen
- Keine Secrets in Docker Images backen
- Produktions-Secrets über Secrets Manager
- Regelmäßig API-Keys rotieren
- Keine Secrets in Logs ausgeben
Secrets Management für Produktion
| Tool | Beschreibung |
|---|---|
| HashiCorp Vault | Secrets Management Plattform |
| AWS Secrets Manager | AWS-native Lösung |
| Docker Secrets | Für Docker Swarm |
| Kubernetes Secrets | Für K8s Umgebungen |
💡 Tipp:
Nutzen Sie für Produktion echte Secrets Manager. .env Dateien sind für Entwicklung, nicht für kritische Produktions-Secrets.