Alle Artikel
HTTPSmkcertlocal developmentlocalhost tunneling

Localhost-HTTPS: mkcert vs. Tunnel, ehrlich verglichen

Zwei Tools, ein Problem: Dein Dev-Server muss über HTTPS erreichbar sein. mkcert gibt dir ein lokal vertrautes TLS-Zertifikat, sodass https://localhost:3000 einfach funktioniert. Ein Tunnel gibt dir eine öffentliche HTTPS-URL mit einem echten Zertifikat von einer echten CA. Sie sind keine Konkurrenten — sie lösen verschiedene Probleme —, aber die Leute behandeln sie ständig so.

Die kurze Antwort

  • Du brauchst HTTPS nur auf deiner eigenen Maschine, für deinen eigenen Browser? Nimm mkcert.
  • Du brauchst, dass ein externer Dienst (Stripe, GitHub, Auth0, ein Telefon) deinen Dev-Server erreicht? Nimm einen Tunnel.
  • Beides? Fahre beides. Sie stehen sich nicht im Weg.

Das ist der ganze Artikel in drei Punkten. Der Rest ist nur das Warum.

mkcert: lokal vertraute Zertifikate in 30 Sekunden

mkcert installiert eine lokale Zertifizierungsstelle in den Trust Store deines Betriebssystems und stellt daraus Zertifikate aus. Dein Browser sieht das Zertifikat als vertraut, weil die CA vertraut ist. Keine Diese Verbindung ist nicht privat-Warnungen, keine --ignore-certificate-errors-Flags, kein Selbstbasteln eigener self-signed Certs.

# einmal pro Maschine
mkcert -install

# einmal pro Projekt
mkcert localhost 127.0.0.1

# du hast jetzt localhost.pem und localhost-key.pem

Binde sie in deinen Dev-Server ein (Vite, Next.js, Express, Django runserver_plus unterstützen alle TLS-Args), und du hast https://localhost:3000 mit einem echten Zertifikat.

Der Haken: nur deine Maschine vertraut dieser CA. Der Browser deines Teamkollegen warnt. Dein Telefon vertraut ihr nicht, ohne dass du das CA-Root manuell installierst.

Tunnel: echtes HTTPS, echte öffentliche URL

Ein localhost-Tunnel leitet Traffic von einer öffentlichen HTTPS-URL zu deinem lokalen Port. Das Zertifikat wird von einer echten CA (Let's Encrypt o. Ä.) ausgestellt und von jedem Browser auf jedem Gerät vertraut.

npx portpreview 3000

Der Tunnel übernimmt die TLS-Terminierung am Cloud-Gateway. Dein lokaler Server kann auf reinem HTTP bleiben — die öffentliche URL ist HTTPS, und das ist die Fläche, die jeder externe Dienst berührt.

Seite an Seite

BedarfmkcertTunnel
HTTPS in deinem lokalen BrowserJaJa (über die öffentliche URL)
Service-Worker- / Secure-Cookie-Test im BrowserJaJa
Externer Provider kann dich erreichenNeinJa
Telefon in der Hand kann dich erreichenNein (ohne CA-Installation)Ja
OAuth-Provider akzeptiert die URLManchmal (Google: ja; viele: nein)Ja
Stripe / GitHub / Twilio können webhookenNeinJa
Setup-Zeit30 Sekunden pro MaschineEin Befehl pro Session
Funktioniert offlineJaNein
Überlebt FlugmodusJaNein

Wo die Leute das falsch machen

mkcert für Webhook-Testing nutzen wollen

Stripe kann der lokalen CA deiner Maschine nicht vertrauen. Egal wie vertraut das Zertifikat in deinem Browser aussieht — Stripe ist in einem anderen Netzwerk. Für jeden eingehenden Traffic aus dem öffentlichen Internet brauchst du einen Tunnel.

Einen Tunnel für reines Solo-Browser-HTTPS nutzen

Willst du nur, dass Service Worker funktionieren oder ein Secure Cookie in deinem eigenen Browser gesetzt wird, ist mkcert schneller und offline-tauglich. Verbrenne keine Tunnel-Session für etwas, das eine Zertifikatsdatei löst.

Ein Tool wählen und den anderen Use-Case durchzwingen

Beides zu fahren ist okay. Der Großteil unseres Setups nutzt mkcert für die tägliche Browser-Arbeit und einen Tunnel, wenn wir Webhooks oder OAuth-Callbacks testen. Sie wohnen ohne Konflikt in package.json zusammen.

Was ist mit Caddy oder nginx?

Ja, du kannst Caddy mit automatischem HTTPS vor deinem Dev-Server fahren, und das funktioniert auch — es ist im Grunde „mkcert mit Extraschritten und einem Reverse Proxy". Für die meiste lokale Entwicklung ist mkcert einfacher. Für aufwendigeres Routing mit mehreren lokalen Diensten verdient sich Caddy sein Geld.

Unser tatsächliches Setup

Ein Repo, in dem wir arbeiten, hat mkcert im Dev-Skript für localhost-seitiges HTTPS und ein separates tunnel-npm-Skript, das portpreview startet, wenn jemand Webhooks oder Mobile-Testing braucht. Die Tunnel-URL kommt per Env-Var rein, sodass OAuth-Redirect-URIs leicht zu tauschen sind. Es dauerte 20 Minuten zu verkabeln, und wir haben seither nie wieder über lokales TLS nachgedacht.

Für OAuth-spezifisches Tunnel-Setup siehe wie man OAuth-Callbacks lokal testet. Zum Teilen von Previews mit Teamkollegen oder Designern deinen lokalen Dev-Server teilen. Tritt der PortPreview-Warteliste bei für die Tunnel-Seite dieses Setups.

Häufig gestellte Fragen

Sollte ich mkcert oder einen Tunnel für lokales HTTPS nutzen?
Beides, für Verschiedenes. mkcert gibt deinem eigenen Browser ein vertrautes Zertifikat auf localhost und funktioniert offline. Ein Tunnel gibt dir eine öffentliche HTTPS-URL, die externe Dienste und andere Geräte erreichen können. Sie stehen sich nicht im Weg — die meisten Teams nutzen beides.
Kann mkcert Webhook-Testing von Stripe oder GitHub bewältigen?
Nein. mkcert-Zertifikate werden nur auf der Maschine vertraut, die die CA installiert hat. Externe Webhook-Provider können localhost nicht erreichen, egal wie vertraut das Zertifikat im lokalen Browser ist. Nutze für jeden eingehenden öffentlichen Traffic einen Tunnel.
Funktioniert mkcert für OAuth-localhost-Callbacks?
Manche Provider (Google, bestimmte Dev-Stufen von Auth0) akzeptieren localhost über HTTP oder HTTPS zur Entwicklung. Viele nicht. mkcert gibt dir HTTPS für die, die es tun; für die strengen ist ein Tunnel mit öffentlicher HTTPS-URL nötig.