Docker · mkcert · SSL · Traefik · Nginx · HTTPS
Lokale SSL-Zertifikate mit mkcert und Reverse-Proxy
HTTPS ohne Browser-Warnungen in Docker

Self-signed Zertifikate erzeugen ständig Browser-Warnungen und lassen sich nicht für APIs und Service-Worker nutzen. mkcert kombiniert mit einem Docker-Reverse-Proxy löst das Problem vollständig: lokale Domains mit echtem vertrauenswürdigen HTTPS – ohne Cloud, ohne Let's Encrypt, ohne Klickorgien.

10 Min. Lesezeit mkcert · Traefik · Nginx · Docker Compose · /etc/hosts macOS · Linux · WSL2 · Docker Desktop

1. Warum lokales HTTPS mehr als Komfort ist

Lokales HTTPS mit mkcert ist nicht nur eine Frage des Komforts – es gibt technische Gründe, warum HTTPS in der lokalen Entwicklungsumgebung notwendig ist. Browser-Features wie Service Worker, Geolocation API, Web Crypto API, HTTP/2 und SameSite-Cookies mit Secure-Flag funktionieren ausschließlich über HTTPS oder auf localhost. Wer eine Anwendung testet, die eines dieser Features nutzt, kommt ohne lokales HTTPS nicht weit. Noch deutlicher: Wenn die Staging- und Produktionsumgebung HTTPS nutzen, ist der Entwicklungsstand auf HTTP ein anderer Stack – Probleme, die nur in Verbindung mit TLS auftreten, werden lokal nicht gefunden.

Self-signed Zertifikate sind keine Lösung für lokales HTTPS: Sie erzeugen Browser-Sicherheitswarnungen, werden von HTTP-Clients in Tests abgelehnt und machen die Arbeit mit APIs umständlich (jedes Tool muss einzeln konfiguriert werden, Zertifikats-Checks zu ignorieren). mkcert löst dieses Problem elegant: Es erstellt eine lokale Certificate Authority (CA) und installiert sie in den Vertrauensspeicher des Betriebssystems und der Browser. Danach ausgestellte Zertifikate werden als vertrauenswürdig behandelt – ohne Browser-Warnungen, ohne spezielle Konfiguration im HTTP-Client.

2. mkcert: lokale CA ohne Browser-Warnungen

mkcert ist ein einfaches Go-Tool von Filippo Valsorda, das speziell für die lokale Entwicklung entwickelt wurde. Es generiert eine lokale Root-CA und registriert sie im Systemvertrauensspeicher (NSS-Datenbank für Firefox, Keychain auf macOS, Zertifikatspeicher auf Windows). Danach können mit einem einzigen Befehl Zertifikate für beliebige lokale Domains generiert werden – und diese Zertifikate werden vom Browser als vertrauenswürdig behandelt, weil sie von der installierten lokalen CA signiert sind.

Der entscheidende Unterschied zu echten CA-Zertifikaten: Die mit mkcert generierte CA ist nur im lokalen Vertrauensspeicher des eigenen Rechners vertrauenswürdig – nicht im Internet. Das ist kein Nachteil, sondern eine Sicherheitseigenschaft: Die lokale CA kann keine Zertifikate für reale Domains ausstellen, die von anderen als vertrauenswürdig behandelt werden. Der private Schlüssel der lokalen CA liegt ausschließlich auf dem eigenen Rechner. Für Team-Setups muss die CA einmalig geteilt und auf jedem Entwickler-Rechner installiert werden – danach kann jeder Entwickler selbst Zertifikate für lokale Domains ausstellen.


# Install mkcert on different platforms

# macOS via Homebrew
brew install mkcert nss  # nss is needed for Firefox support

# Linux (Debian/Ubuntu)
sudo apt install libnss3-tools
curl -L https://github.com/FiloSottile/mkcert/releases/latest/download/mkcert-v1.4.4-linux-amd64 \
     -o /usr/local/bin/mkcert
chmod +x /usr/local/bin/mkcert

# Windows via Chocolatey
choco install mkcert

# Step 1: Create and install the local CA
# This modifies the system trust store — requires admin/sudo
mkcert -install

# Verify CA location
mkcert -CAROOT
# Output: /home/user/.local/share/mkcert (Linux)
# Output: /Users/user/Library/Application Support/mkcert (macOS)

# The CA certificate (rootCA.pem) must be distributed to all team members
# The private key (rootCA-key.pem) must NEVER be shared

3. mkcert installieren und CA einrichten

mkcert ist als einzelne Binary verfügbar und benötigt keine Runtime oder Installation von Abhängigkeiten. Auf macOS ist brew install mkcert der einfachste Weg; das NSS-Paket muss für Firefox-Unterstützung separat installiert werden. Der Befehl mkcert -install erstellt die lokale CA und installiert das Root-Zertifikat in allen erkannten Vertrauensspeichern: macOS Keychain, NSS für Firefox und Chrome, Windows Certificate Store. Nach diesem Schritt ist die CA aktiv und neue Browser-Sessions werden ausgestellte Zertifikate als vertrauenswürdig behandeln.

Das Verzeichnis, in dem mkcert die CA-Dateien ablegt (mkcert -CAROOT), enthält zwei Dateien: rootCA.pem (das öffentliche CA-Zertifikat) und rootCA-key.pem (der private Schlüssel). Das öffentliche Zertifikat kann und soll im Team geteilt werden, damit alle Entwickler dieselbe CA installieren und ausgestellte Zertifikate vertrauen. Der private Schlüssel muss strikt vertraulich bleiben – wer ihn besitzt, kann Zertifikate für beliebige Domains ausstellen, die von allen vertraut werden, die die CA installiert haben.

4. SSL-Zertifikate für lokale Domains generieren

Mit installierter lokaler CA ist das Generieren von Zertifikaten ein einzeiliger Befehl. mkcert akzeptiert beliebig viele Domains und IP-Adressen in einem Zertifikat: mkcert myproject.local *.myproject.local 127.0.0.1 ::1. Das Wildcard-Zertifikat für *.myproject.local deckt alle Subdomains ab, was für Setups mit mehreren Services unter einer Domain praktisch ist. Die generierten Dateien (myproject.local.pem und myproject.local-key.pem) werden in das Projektverzeichnis gelegt und als Secrets in den Docker-Container gemountet.

Das Zertifikate-Verzeichnis sollte nicht im Repository liegen – private Schlüssel gehören nicht in die Versionsverwaltung. Ein .gitignore-Eintrag für certs/*.pem verhindert das versehentliche Committen. Stattdessen liegt im Repository ein Setup-Skript, das den Befehl zum Generieren der Zertifikate dokumentiert und bei Bedarf ausführt. Für CI-Umgebungen, die HTTPS für Integrationstests benötigen, kann mkcert als Teil des Test-Setup-Skripts ausgeführt werden – die generierten Zertifikate existieren dann nur für die Dauer der CI-Session.


#!/usr/bin/env bash
# scripts/setup-certs.sh — Generate local SSL certificates for Docker development
set -euo pipefail

CERTS_DIR="./certs"
DOMAIN="${1:-myproject.local}"

# Ensure certs directory exists
mkdir -p "$CERTS_DIR"

# Check if mkcert is installed
if ! command -v mkcert &>/dev/null; then
  echo "ERROR: mkcert is not installed. Run: brew install mkcert nss"
  exit 1
fi

# Install local CA (safe to run multiple times — skips if already installed)
mkcert -install

# Generate certificate for the project domain and wildcard subdomains
mkcert \
  -cert-file "${CERTS_DIR}/${DOMAIN}.pem" \
  -key-file  "${CERTS_DIR}/${DOMAIN}-key.pem" \
  "${DOMAIN}" \
  "*.${DOMAIN}" \
  "localhost" \
  "127.0.0.1" \
  "::1"

echo "Certificates generated in ${CERTS_DIR}/"
echo "Add to /etc/hosts: 127.0.0.1 ${DOMAIN}"
echo "IMPORTANT: Never commit *-key.pem files to version control"

5. Nginx als Reverse-Proxy in Docker

Nginx ist die klassische Wahl für einen Reverse-Proxy in Docker-Entwicklungsumgebungen. Die Konfiguration ist explizit und gut dokumentiert; für Teams mit Nginx-Erfahrung ist es der natürliche Einstieg. Ein Nginx-Container nimmt HTTPS-Verbindungen auf Port 443 an, terminiert TLS mit dem mkcert-Zertifikat und leitet Requests an die Backend-Services weiter. Der Backend-Service selbst muss kein HTTPS sprechen – die TLS-Terminierung geschieht vollständig im Nginx-Container.

Das Setup besteht aus drei Teilen: dem Nginx-Docker-Service in der Compose-Datei, einer Nginx-Konfigurationsdatei mit SSL-Konfiguration und dem Bind-Mount des Zertifikats-Verzeichnisses in den Nginx-Container. Die Nginx-Konfiguration definiert einen Server-Block für HTTPS auf Port 443 mit den SSL-Zertifikat-Dateien und einem proxy_pass-Direktiv, das auf den Backend-Service im Docker-Netzwerk zeigt. HTTP-Requests auf Port 80 werden per Redirect auf HTTPS umgeleitet. Für mehrere Projekte auf demselben Rechner kann ein einzelner Nginx-Container als zentraler Reverse-Proxy für alle Projekte dienen.

6. Traefik als dynamischer Reverse-Proxy

Traefik ist eine modernere Alternative zu Nginx als Reverse-Proxy in Docker-Entwicklungsumgebungen. Der entscheidende Unterschied: Traefik konfiguriert sich dynamisch über Docker-Labels an den Service-Containern, statt eine statische Konfigurationsdatei zu benötigen. Ein neuer Service wird einfach mit den entsprechenden Labels gestartet, und Traefik erkennt ihn automatisch und richtet das Routing ein. Das ist besonders praktisch für Teams mit mehreren Projekten, die auf demselben Entwickler-Rechner laufen.

Mit mkcert-Zertifikaten und Traefik lässt sich ein vollständiger lokaler HTTPS-Stack in einer einzigen Compose-Datei definieren. Traefik liest die Zertifikate aus einem definierten Verzeichnis, das über einen Bind-Mount bereitgestellt wird. Die TLS-Konfiguration für lokale Domains wird über Traefik-Middleware-Labels an den Services definiert. Sobald das Traefik-Setup einmal läuft, muss für jedes neue Projekt nur noch ein neues Compose-File mit den entsprechenden Labels erstellt werden – ohne Traefik neu zu starten oder Konfigurationsdateien manuell anzupassen.


# compose.yml — Traefik reverse proxy with mkcert SSL certificates
services:
  traefik:
    image: traefik:v3.0
    container_name: traefik-proxy
    command:
      # Enable Docker provider — auto-discover containers via labels
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      # Load TLS certificates from directory
      - "--providers.file.directory=/etc/traefik/certs"
      - "--providers.file.watch=true"
      # Entrypoints: HTTP and HTTPS
      - "--entrypoints.web.address=:80"
      - "--entrypoints.websecure.address=:443"
      # Redirect HTTP to HTTPS globally
      - "--entrypoints.web.http.redirections.entrypoint.to=websecure"
      - "--entrypoints.web.http.redirections.entrypoint.scheme=https"
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./certs:/etc/traefik/certs:ro
      - ./traefik/dynamic.yml:/etc/traefik/certs/dynamic.yml:ro
    networks:
      - proxy

  myapp:
    image: nginx:alpine
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.myapp.rule=Host(`myproject.local`)"
      - "traefik.http.routers.myapp.entrypoints=websecure"
      - "traefik.http.routers.myapp.tls=true"
    networks:
      - proxy

networks:
  proxy:
    external: true

7. Multi-Domain-Setup für mehrere Projekte

Wer auf demselben Rechner mehrere Projekte gleichzeitig mit lokalem HTTPS betreibt, braucht eine Strategie für die Domain-Verwaltung. Der einfachste Ansatz: Jedes Projekt bekommt eine eigene .local-Domain (z.B. shop.local, api.local, admin.local) mit eigenem mkcert-Zertifikat und eigenem Eintrag in /etc/hosts. Ein zentraler Traefik-Container als globaler Proxy auf dem Entwickler-Rechner routet eingehende Requests an das richtige Projekt-Netzwerk weiter, basierend auf dem Hostnamen im Request.

Für große Teams mit vielen parallelen Projekten kann ein automatisiertes Skript die /etc/hosts-Einträge und Zertifikate verwalten: Das Skript liest eine Projekt-Konfigurationsdatei (Liste der Domains), generiert fehlende Zertifikate mit mkcert und aktualisiert /etc/hosts entsprechend. Eine Alternative zu /etc/hosts-Einträgen ist ein lokaler DNS-Resolver wie dnsmasq, der alle *.local-Anfragen auf 127.0.0.1 auflöst – das spart manuelle Einträge für jede neue Domain vollständig.

8. Team-Rollout: CA-Zertifikat verteilen

Der mkcert-CA-Ansatz skaliert gut auf Teams, wenn der Rollout-Prozess klar definiert ist. Der Schlüssel liegt im gemeinsamen CA-Zertifikat: Alle Entwickler installieren dasselbe rootCA.pem, das von einer einzigen autorisierten Person mit mkcert -install erstellt wurde. Danach können alle Entwickler entweder eigene Zertifikate für lokale Domains ausstellen, oder es gibt ein zentrales Zertifikate-Bundle im Projekt-Repository, das automatisch beim Setup-Skript generiert wird.

Das öffentliche CA-Zertifikat (rootCA.pem) kann sicher im Team-Repository oder einem internen Wiki abgelegt werden – es enthält keinen privaten Schlüssel und ist für sich genommen ungefährlich. Die Installation auf einem neuen Rechner ist trivial: mkcert -install nach dem Kopieren des CA-Verzeichnisses in den mkcert-CAROOT-Pfad. Für automatisierte Onboarding-Skripte kann mkcert so konfiguriert werden, dass es das CA-Verzeichnis aus einem bestimmten Pfad liest, statt das Standard-Home-Verzeichnis zu nutzen – das ermöglicht das Verwalten mehrerer CAs für verschiedene Projekte oder Clients auf demselben Rechner.

9. Reverse-Proxy-Optionen im Vergleich

Für lokale Docker-Entwicklungsumgebungen stehen mehrere Reverse-Proxy-Optionen zur Verfügung. Die Wahl hängt von der Präferenz für explizite Konfiguration versus dynamische Service-Discovery und von der Anzahl der parallel laufenden Projekte ab.

Proxy Konfiguration Neue Projekte Empfehlung
Nginx Statische Config-Dateien Config-Datei hinzufügen + Reload Teams mit Nginx-Erfahrung, 1–3 Projekte
Traefik Docker-Labels + dynamic.yml Nur Labels am Service Viele Projekte, dynamische Environments
Caddy Caddyfile (minimal) Caddyfile ergänzen Einfachste Syntax, eingebettete TLS-Logik
HAProxy haproxy.cfg Komplexe Config, Reload nötig Nur wenn HAProxy bereits im Stack ist
nginx-proxy Env-Variablen am Service VIRTUAL_HOST-Variable setzen Einfacher Einstieg, keine Labels nötig

Traefik ist für die meisten modernen Docker-Entwicklungsumgebungen die empfohlene Wahl: Die dynamische Service-Discovery via Labels macht neue Projekte mit minimaler Konfiguration zugänglich, und die HTTPS-Unterstützung mit eigenen Zertifikaten ist gut dokumentiert. Nginx ist die bessere Wahl, wenn das Team bereits Nginx-Kenntnisse hat und die Konfiguration explizit und nachvollziehbar sein soll. Caddy punktet mit der einfachsten Konfigurationssyntax und ist eine gute Option für kleinere Teams oder einzelne Entwickler ohne spezifische Proxy-Präferenz.

Mironsoft

Docker-Entwicklungsumgebungen, HTTPS-Setup und Team-Onboarding

Lokales HTTPS mit mkcert und Docker einrichten?

Wir richten mkcert, einen Reverse-Proxy und die vollständige lokale HTTPS-Infrastruktur für euer Entwicklerteam ein – inklusive Onboarding-Dokumentation und Setup-Skripten.

mkcert-Setup

Lokale CA einrichten, Zertifikate für alle Projektdomains generieren und Team-Rollout durchführen

Reverse-Proxy

Traefik oder Nginx als zentralen Proxy für alle lokalen Entwicklungsprojekte konfigurieren

Multi-Projekt

Setup-Skripte und Dokumentation für das gesamte Team erstellen und pflegen

10. Zusammenfassung

Lokales HTTPS mit mkcert und einem Docker-Reverse-Proxy ist in einer Stunde eingerichtet und beseitigt alle Probleme mit Browser-Warnungen und eingeschränkten Browser-APIs dauerhaft. mkcert erstellt eine lokale CA und installiert sie im Systemvertrauensspeicher; ausgestellte Zertifikate werden vom Browser als vollständig vertrauenswürdig behandelt. Traefik als dynamischer Reverse-Proxy nimmt HTTPS-Verbindungen an und leitet sie an Backend-Services weiter, ohne dass diese selbst TLS sprechen müssen. Für neue Projekte genügt es, Docker-Labels am Service-Container zu setzen.

Der Team-Rollout ist unkompliziert: Das öffentliche CA-Zertifikat wird einmalig geteilt und auf jedem Entwickler-Rechner installiert. Ein Setup-Skript im Repository generiert bei Bedarf neue Zertifikate für lokale Domains. Die /etc/hosts-Einträge oder ein lokaler dnsmasq-Resolver sorgen dafür, dass Domains wie myproject.local auf 127.0.0.1 auflösen. Mit dieser Kombination aus mkcert, Reverse-Proxy und DNS-Auflösung ist die lokale Entwicklungsumgebung identisch zur HTTPS-Produktionsumgebung – ohne Cloud-Abhängigkeiten und ohne Let's Encrypt-Limits.

Lokale SSL-Zertifikate mit mkcert — Das Wichtigste auf einen Blick

mkcert-Installation

brew install mkcert nss (macOS). mkcert -install erstellt die lokale CA und registriert sie im Systemvertrauensspeicher. Einmalig pro Rechner.

Zertifikate generieren

mkcert domain.local *.domain.local 127.0.0.1. Zertifikat und Schlüssel nie in Git committen. Setup-Skript für reproduzierbaren Prozess.

Reverse-Proxy

Traefik für dynamische Service-Discovery via Labels. Nginx für explizite, gut lesbare Konfiguration. Caddy für minimale Konfiguration.

Team-Rollout

rootCA.pem (ohne Schlüssel) teilen. Auf neuen Rechnern in CAROOT-Verzeichnis kopieren und mkcert -install ausführen. rootCA-key.pem niemals teilen.

11. FAQ: Lokale SSL-Zertifikate mit mkcert und Reverse-Proxy

1Was ist mkcert und warum besser als self-signed?
mkcert erstellt eine lokale CA im Systemvertrauensspeicher. Ausgestellte Zertifikate gelten als vertrauenswürdig – keine Browser-Warnungen. Self-signed-Zertifikate ohne CA-Eintrag erzeugen immer Warnungen.
2Lokale CA im Team teilen – sicher?
rootCA.pem (öffentlich) kann geteilt werden. rootCA-key.pem (privat) niemals teilen oder committen. Nur der Schlüssel ermöglicht das Ausstellen neuer Zertifikate.
3Warum HTTPS lokal notwendig?
Service Worker, Web Crypto API, Geolocation, Secure-Cookies und HTTP/2 erfordern HTTPS. Produktionsumgebungen nutzen HTTPS – die Entwicklungsumgebung sollte identisch sein.
4Zertifikat für mehrere Domains?
mkcert akzeptiert mehrere Domains: mkcert domain.local *.domain.local 127.0.0.1. Das Zertifikat gilt für alle angegebenen Domains und IPs.
5Wie löst Docker lokale Domains auf?
Docker löst keine Host-Domains auf. /etc/hosts-Eintrag auf dem Host nötig: 127.0.0.1 myproject.local. Alternativ dnsmasq für alle *.local-Anfragen.
6Nginx vs. Traefik als Reverse-Proxy?
Nginx: statische Config, Reload bei Änderungen. Traefik: dynamische Service-Discovery via Docker-Labels, kein Reload nötig. Traefik empfohlen für viele parallele Projekte.
7mkcert in der CI-Pipeline?
Ja. Als Teil des Test-Setup-Skripts ausführen. Zertifikate existieren nur für die CI-Session. Saubere Lösung für Integrationstests ohne externe Abhängigkeiten.
8Immer neuen /etc/hosts-Eintrag nötig?
Nicht mit dnsmasq. Ein lokaler Resolver kann alle *.local-Anfragen automatisch auf 127.0.0.1 auflösen – keine manuellen Einträge mehr für neue Domains.
9CA auf neuen Team-Rechner installieren?
rootCA.pem in mkcert-CAROOT-Verzeichnis kopieren, dann mkcert -install ausführen. Registriert das CA-Zertifikat im Systemvertrauensspeicher des neuen Rechners.
10mkcert auf Windows und WSL2?
Ja. Windows-Binary oder Chocolatey. Für WSL2 mkcert sowohl in WSL2 als auch auf Windows-Host installieren und ausführen, damit Browser auf beiden Seiten die Zertifikate vertrauen.