Lokale Entwicklungsdomains ohne Portkonflikte, ohne Framework-Bindung
Als Laravel-Entwickler hatte ich mit Valet lange eine komfortable Lösung: Domains, Zertifikate, Routing — alles automatisch, solange man im PHP-Ökosystem bleibt. Das Problem beginnt, sobald Docker-Container oder andere Frameworks ins Spiel kommen. Ein Nuxt-Projekt auf Port 3000, eine Go-API auf Port 8080, ein Docker-basierter Service ohne exponierte Ports — Valet kennt davon nichts. Plötzlich konkurrieren Projekte um Ports, Zertifikate fehlen und /etc/hosts wird zur Verwaltungsarbeit.
Genau an dieser Stelle setzt proxypark an. Ein einzelnes Bash-Script, das DNS, TLS-Zertifikate, Reverse-Proxy und Docker-Anbindung in einer konsistenten Toolchain zusammenführt. Kein Framework-Lock-in, kein Daemon, keine eigenen Dependencies. Das Ergebnis: park link myapp 3000 — und https://myapp.test funktioniert sofort, im Browser, mit grünem Schloss. Bestehende Valet-Projekte laufen dabei unverändert weiter — proxypark kann parallel zu Valet betrieben werden und übernimmt nur die Projekte, die Valet nicht bedienen kann.
Dieser Beitrag erklärt, warum ich proxypark gebaut habe, welche Alternativen es gibt und warum keine davon das vollständige Problem löst.
proxypark auf GitHub
Open Source, MIT-lizenziert. Ein einzelnes Bash-Script — Installation in 30 Sekunden, keine eigenen Dependencies. Clone, Symlink, park install, fertig.
Das Problem: Vier Baustellen, kein gemeinsamer Nenner
Lokale Entwicklung hat vier Infrastruktur-Probleme, die fast immer einzeln gelöst werden:
DNS — Jede .test-Domain muss irgendwo auf 127.0.0.1 aufgelöst werden. Manuell über /etc/hosts oder per dnsmasq, das man selbst konfigurieren muss.
Zertifikate — Moderne Browser erzwingen HTTPS. Selbstsignierte Zertifikate erzeugen Warnungen, Wildcard-Zertifikate für .test werden seit der Aufnahme in die Public Suffix List abgelehnt. Jede Domain braucht ein eigenes Zertifikat.
Routing — Ein Reverse-Proxy muss Anfragen anhand des Hostnamens an den richtigen Port weiterleiten. Ohne das konkurrieren alle Projekte um Port 80 und 443.
Docker-Anbindung — Container, die keine Ports exponieren, sind vom Host aus unsichtbar. Wer sie erreichen will, braucht entweder Port-Mappings oder eine Netzwerkbrücke zum Proxy.
Jedes dieser Probleme hat eigene Tools. Aber kein einzelnes Tool löst alle vier gleichzeitig — und genau das war der Auslöser für proxypark.
Wie proxypark funktioniert
proxypark setzt auf drei bewährte Komponenten: dnsmasq für DNS-Auflösung, mkcert für vertrauenswürdige Zertifikate und Traefik als Reverse-Proxy. Die Verbindung zwischen ihnen ist das Entscheidende.
Jeder park link-Befehl erzeugt eine kleine YAML-Datei im Verzeichnis ~/.proxypark/dynamic/. Traefik überwacht dieses Verzeichnis über seinen File-Provider und übernimmt Änderungen sofort — ohne Neustart, ohne Reload. Gleichzeitig regeneriert proxypark das Zertifikatsbundle, sodass die neue Domain sofort per HTTPS erreichbar ist.
Für Docker-Container gibt es park link:docker, das Container direkt über ein internes Docker-Netzwerk anbindet — ohne exponierte Ports, ohne Docker-Socket-Zugriff. Das umgeht die bekannten Probleme mit Docker Desktop, OrbStack und Colima auf macOS, bei denen der Socket über Symlinks umgeleitet wird und Berechtigungsprobleme entstehen.
# Lokalen Service verlinken
park link myapp 3000
# → https://myapp.test
# Docker-Container ohne exponierte Ports
park link:docker api api-container:8080
# → https://api.test → api-container:8080
# Subdomains per Punkt-Notation
park link admin.myapp 3001
# → https://admin.myapp.test
Die Alternativen — und warum sie nicht reichen
Laravel Valet
Valet ist die bekannteste Lösung im PHP-Umfeld und für Laravel-Projekte nach wie vor hervorragend. Es übernimmt DNS, Zertifikate und Reverse-Proxy — aber eben nur für PHP. Valet startet einen eigenen nginx, erwartet eine bestimmte Verzeichnisstruktur und kennt nur Laravel, Symfony und Co. Sobald ein Nuxt-Frontend, eine Go-API oder ein Docker-basierter Service dazukommt, endet Valets Zuständigkeit. proxypark ist stack-agnostisch: Alles was auf einem Port lauscht, kann verlinkt werden — und dank park valet enable laufen beide Tools parallel. Valet bedient weiter die PHP-Projekte, proxypark übernimmt den Rest.
Traefik mit Docker-Labels
Der „offizielle" Weg, Traefik in Docker-Umgebungen zu nutzen. Jeder Container bekommt Labels wie traefik.http.routers..., Traefik liest den Docker-Socket und konfiguriert sich selbst. Klingt elegant, funktioniert auf macOS aber unzuverlässig — Docker Desktop leitet den Socket über Symlinks um, OrbStack und Colima haben eigene Eigenheiten. proxypark umgeht das komplett: Es schreibt YAML-Dateien, die Traefik per File-Provider liest. Kein Socket, keine Rechteprobleme, keine Abhängigkeit vom Docker-Runtime.
Caddy
Caddy kann Ähnliches mit seiner automatischen HTTPS-Funktion und einem einfachen Caddyfile. Aber Caddy löst nur den Proxy-Teil — DNS und Zertifikatsverteilung für .test-Domains muss man selbst aufsetzen. proxypark liefert die komplette Kette: dnsmasq für DNS, mkcert für vertrauenswürdige Zertifikate, Traefik für Routing.
Manuelles nginx/Apache mit /etc/hosts
Die Oldschool-Variante. Für jedes Projekt eine Config-Datei schreiben, Zertifikate generieren, nginx neu laden, /etc/hosts pflegen. Funktioniert, aber bei fünf oder mehr Projekten wird es zur Verwaltungsarbeit. proxypark reduziert das auf park link name port — ein Befehl statt fünf Dateien.
Was proxypark anders macht
Der Kern von proxypark ist kein technischer Durchbruch, sondern eine Designentscheidung: Ein einzelnes Bash-Script ohne eigene Dependencies. Installation bedeutet Klonen und Symlinken. Deinstallation bedeutet ein Verzeichnis löschen. Es gibt keinen Daemon, keinen Build-Step, keinen Paketmanager.
Trotzdem löst es alle vier Probleme gleichzeitig — DNS, Zertifikate, Routing, Docker-Anbindung — und bleibt dabei framework-unabhängig. Ob Laravel, Nuxt, Rails oder ein Go-Service: Alles was auf einem Port lauscht oder in einem Container läuft, bekommt eine .test-Domain mit vertrauenswürdigem HTTPS.
Ein bewusster Designentscheid ist die nahtlose Koexistenz mit Laravel Valet. park valet enable erstellt einen Catchall, der alle nicht explizit verlinkten .test-Domains an Valet weiterleitet. In der Praxis heißt das: Man verschiebt Valet auf Port 8080, aktiviert den Catchall — und ab sofort bedient proxypark die Docker- und Non-PHP-Projekte, während Valet die Laravel-Projekte wie gewohnt ausliefert. Explizite park link-Einträge haben dabei immer Vorrang. Migration ist kein Alles-oder-nichts, sondern ein schrittweiser Prozess.
Fazit
proxypark entstand aus der täglichen Arbeit an mehreren Projekten gleichzeitig — mit unterschiedlichen Stacks, unterschiedlichen Runtimes und dem immer gleichen Infrastruktur-Overhead. Es ist bewusst minimal gehalten: ein Script, drei bewährte Tools, null eigene Abstraktion darüber.
Wer lokale Entwicklung mit sauberen Domains, vertrauenswürdigem HTTPS und ohne Portkonflikte betreiben will, braucht dafür keine komplexe Plattform. Ein Befehl reicht.
Call to Action
proxypark ist Open Source und auf GitHub verfügbar: https://github.com/McGo/proxypark
Wer Unterstützung beim Aufsetzen lokaler Entwicklungsumgebungen braucht — ob für ein einzelnes Team oder eine ganze Abteilung — kann sich gerne melden. Als Backend- & Solution Architect kenne ich die Stolpersteine, die zwischen „funktioniert auf meinem Rechner" und einer reproduzierbaren Entwicklungsumgebung liegen.