Umgebungsvariablen
Kopiere .env.local.example nach .env.local und fülle die Werte aus. Einige Variablen (Auth, DB) sind nicht im Example enthalten und müssen manuell hinzugefügt werden.
Datenbank
| Variable | Beschreibung | Pflicht |
|---|---|---|
DATABASE_URL | PostgreSQL Connection-String für Drizzle ORM (z.B. postgres://user:pass@host:port/db) | Ja |
Wird von Drizzle ORM in src/server/db/index.ts und drizzle.config.ts verwendet.
Auth.js (NextAuth v5)
| Variable | Beschreibung | Pflicht |
|---|---|---|
AUTH_SECRET | Session-Verschlüsselungs-Secret für Auth.js JWT-Tokens | Ja |
NEXTAUTH_URL | Base-URL der App (z.B. http://localhost:3000) | Ja (Dev) |
AUTH_GOOGLE_ID | Google OAuth Client ID | Nein |
AUTH_GOOGLE_SECRET | Google OAuth Client Secret | Nein |
Google OAuth ist optional — wird nur aktiviert, wenn beide Google-Variablen gesetzt sind. Ohne Google OAuth funktioniert nur Email/Password-Login.
Verschlüsselung
| Variable | Beschreibung | Pflicht |
|---|---|---|
ENCRYPTION_KEY | AES-256-GCM Key (32-Byte Hex, 64 Zeichen) für Tenant-E-Mails | Ja |
Generieren mit: node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
Der pgcrypto-Key für DHL/Shopify-Credentials wird separat auf Datenbank-Ebene konfiguriert:
ALTER DATABASE postgres SET app.settings.encryption_key = 'your-key';
Dieser Wert gehört nicht in .env.local — die App liest ihn nie direkt.
E-Mail (Resend)
| Variable | Beschreibung |
|---|---|
RESEND_API_KEY | Resend API-Key (resend.com/api-keys) |
RESEND_FROM_EMAIL | Absender-E-Mail (verifizierte Domain erforderlich) |
Cron
| Variable | Beschreibung |
|---|---|
CRON_SECRET | Bearer-Token für Cron-Endpunkte (32-Byte Hex) |
Generieren mit: node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
DHL Parcel DE
| Variable | Beschreibung |
|---|---|
DHL_CLIENT_ID | App-Level OAuth Client ID (developer.dhl.com) |
DHL_CLIENT_SECRET | App-Level OAuth Client Secret |
Diese Credentials sind App-Level (für alle Tenants gleich). Tenant-spezifische GKP-Zugangsdaten werden mit pgcrypto verschlüsselt in der DB gespeichert.
Shopify
| Variable | Beschreibung |
|---|---|
SHOPIFY_CLIENT_ID | App Client ID (partners.shopify.com) |
SHOPIFY_CLIENT_SECRET | App Client Secret |
Redirect-URL: https://app.roestify.de/api/v1/shopify/oauth/callback
Stripe (Billing)
| Variable | Beschreibung |
|---|---|
STRIPE_SECRET_KEY | Stripe Secret Key (sk_test_xxx) |
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY | Publishable Key (pk_test_xxx) |
STRIPE_WEBHOOK_SECRET | Webhook-Signing-Secret (whsec_xxx) |
STRIPE_STARTER_PRICE_ID | Preis-ID Starter-Plan (price_xxx) |
STRIPE_PRO_PRICE_ID | Preis-ID Pro-Plan (price_xxx) |
Bestellformular (Dealer-Portal)
| Variable | Beschreibung |
|---|---|
ORDER_FORM_JWT_SECRET | JWT-Secret für B2B-Dealer-Portal-Sessions (32-Byte Hex, 64 Zeichen) |
Generieren mit: node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
Das Bestellformular nutzt ein eigenes JWT (kein Auth.js), weil externe Kunden sich per OTP-Code authentifizieren.
Platform Admin
| Variable | Beschreibung |
|---|---|
PLATFORM_ADMIN_EMAILS | Komma-getrennte Liste der Platform-Admin-E-Mails (PROJ-31) |
S3-Storage
| Variable | Beschreibung |
|---|---|
S3_ENDPOINT | S3-kompatibler Endpoint (AWS, Cloudflare R2, MinIO) |
S3_REGION | Region (z.B. auto für R2) |
S3_ACCESS_KEY_ID | Access Key |
S3_SECRET_ACCESS_KEY | Secret Key |
S3_BUCKET_NAME | Bucket-Name |
Wird für Tenant-Logos, Rechnungs-PDFs und Report-Dateien verwendet.
Analytics & Monitoring
| Variable | Beschreibung |
|---|---|
NEXT_PUBLIC_SENTRY_DSN | Sentry DSN (Error Tracking) |
NEXT_PUBLIC_POSTHOG_KEY | PostHog API Key (EU Cloud) |
NEXT_PUBLIC_POSTHOG_HOST | PostHog Host |
Entwicklung & Tests
| Variable | Beschreibung |
|---|---|
ANTHROPIC_API_KEY | Für Übersetzungs-Sync-Scripts (scripts/translate/, nur Dev) |
E2E_USER_EMAIL | Playwright E2E-Test-User E-Mail |
E2E_USER_PASSWORD | Playwright E2E-Test-User Passwort |
- Variablen ohne
NEXT_PUBLIC_werden nie an den Browser gesendet .env.localist in.gitignore— wird nie committed- Tenant-spezifische Secrets (DHL-Passwort, Shopify-Token) werden mit pgcrypto verschlüsselt in der DB gespeichert, nicht in .env
AUTH_SECRETundORDER_FORM_JWT_SECRETmüssen in Production kryptographisch stark sein (min. 32 Bytes)
Übersicht: Pflicht vs. Optional
| Variable | Dev | Production |
|---|---|---|
DATABASE_URL | Pflicht | Pflicht |
AUTH_SECRET | Pflicht | Pflicht |
NEXTAUTH_URL | Pflicht | Automatisch |
ENCRYPTION_KEY | Pflicht | Pflicht |
ORDER_FORM_JWT_SECRET | Pflicht | Pflicht |
RESEND_API_KEY / RESEND_FROM_EMAIL | Optional | Pflicht |
CRON_SECRET | Optional | Pflicht |
STRIPE_* | Optional | Pflicht |
S3_* | Optional | Pflicht |
DHL_* | Optional | Optional |
SHOPIFY_* | Optional | Optional |
AUTH_GOOGLE_* | Optional | Optional |
PLATFORM_ADMIN_EMAILS | Optional | Pflicht |
NEXT_PUBLIC_SENTRY_DSN | Optional | Empfohlen |
E2E_* | Optional | Nein |
ANTHROPIC_API_KEY | Optional | Nein |