Zeltro › Mehrere Projekte lokal ausführen, ohne Portkonflikte

Ein Dutzend Projekte lokal ausführen, ohne Portkonflikte

Jedes Projekt will Port 3000, jede Compose-Datei will 3306, und nichts kann mit irgendetwas reden. Hier ist der Aufbau, der das Problem beseitigt, statt es zu verwalten – gemeinsame Dienste und eine Adresse für jedes Projekt, die Sie nie selbst wählen müssen.

Das Problem kommt ungefähr beim fünften Projekt. Jedes Framework will Port 3000 oder 8000. Jede docker-compose.yaml, die Sie klonen, will 3306 oder 5432 belegen. Sie fangen an, sich zu notieren, welches Projekt auf welchem Port läuft, und dann müssen zwei Projekte miteinander reden, und Sie entdecken host.docker.internal.

Das ist alles beherrschbar. Es ist aber auch vermeidbar – nicht, indem Sie sich einen besseren Satz Ports merken, sondern indem Sie nie einen wählen.

Die Zeltro-App: eine Seitenleiste mit Projekten, jedes mit Statusanzeige, lokaler und LAN-Adresse sowie Buttons zum Starten, Stoppen, Bearbeiten und Öffnen
Alle Projekte in einer Liste, jedes mit einer lokalen und einer LAN-Adresse, die Zeltro vergeben hat. Nichts auszuwählen.

Der Aufbau#

Jedes Projekt bekommt eine eigene Adresse in einem privaten Docker-Netzwerk, vergeben beim Anlegen des Projekts. Sie wählen sie nie selbst, und zwei Projekte können nicht kollidieren:

LOCAL  http://10.247.177.168        # from this machine
LAN    http://192.168.1.6:168       # from anything else on the network

zeltro status gibt beide für jedes Projekt aus. Die lokale Adresse ist die eigene IP des Containers, also gibt es dort überhaupt keinen Port; die LAN-Adresse ist die IP dieses Rechners plus der veröffentlichte Port des Projekts, damit Sie es vom Handy oder einem anderen Laptop aus erreichen.

Darunter teilen sich alle Projekte auf dem Rechner einen Satz Dienste:

Dienst Container Aus einem Projekt erreichbar als
MariaDB zeltro-mariadb zeltro-mariadb:3306
Postgres zeltro-postgres zeltro-postgres:5432
Redis zeltro-redis zeltro-redis:6379
MongoDB zeltro-mongo zeltro-mongo:27017
Memcached zeltro-memcached zeltro-memcached:11211

Zehn Projekte, von jedem einer. Aus sieben doppelten Postgres-Containern, die zusammen rund 700 MB belegen, wird einer mit etwa 100.

~700 MBfür sieben doppelte Postgres-Container
~100 MBfür das eine gemeinsame zeltro-postgres
0Ports zum Auswählen, Vergeben oder Merken

Was das behebt#

Port-RouletteNichts zu merken, nichts zu vergeben, keine Kollisionen, wenn zwei Projekte standardmäßig 3000 wollen. Die Vergabe ist Zeltros Problem, nicht Ihres.

Projektübergreifende ArbeitAlle Projekte hängen im selben Docker-Netzwerk und sind dort über ihren Namen erreichbar, also funktioniert fetch('http://client-api/') aus einem anderen Projekt ohne jede Netzwerkkonfiguration. Wenn eine Laravel-App die Datenbank eines Django-Projekts liest, ist das ein Connection-String, keine Bastelaufgabe.

Geklonte Repos, die sich wehrenEine Upstream-Compose-Datei, die 5432:5432 oder 80:80 belegt, wird beim Einrichten auf die gemeinsamen Dienste umverdrahtet, und das Original bleibt als docker-compose.upstream.yaml erhalten.

RechnerlastEin Datenbankprozess pro Engine statt einer pro Projekt. Das ist der Unterschied zwischen einem Laptop, der Ihre ganze Arbeit stemmt, und einem, der es nicht schafft.

Zeltros Einstellungen, Tab Dienste: zeltro-mariadb, zeltro-redis, zeltro-memcached und phpMyAdmin laufen, jeweils mit ihrer Adresse
Die gemeinsamen Dienste, die jedes Projekt nutzt, jeweils in einer einzigen Instanz.

So geht's#

zeltro new laravel barber-shop      # scaffold, wire up, start
zeltro setup existing-project       # adapt a project you already have
zeltro up barber-shop               # start it
zeltro status                       # what is running, and its two addresses

Adressen werden für Sie vergeben und ausgegeben. Nichts wird in /etc/hosts geschrieben, und Zeltro fragt nie nach sudo, um ein Projekt zu verwalten.

Gemeinsame Dienste heißen gemeinsame Versionen: eine Postgres-Hauptversion für alles. Die meisten Projekte merken davon nie etwas. Brauchen zwei wirklich unterschiedliche Hauptversionen, ist das der eine Fall, in dem Werkzeuge pro Projekt wie DDEV oder Lando weiter die Nase vorn haben, und genau der Kompromiss, den dieser Aufbau bewusst eingeht.

Warum das mit einem KI-Agenten noch wichtiger ist#

Ein Agent, der in einem Verzeichnis arbeitet, weiß nicht, was sonst noch auf dem Rechner läuft. Sich selbst überlassen, wählt er einen Port, fügt der Compose-Datei einen Datenbank-Container hinzu und kollidiert still mit etwas, das bei Ihnen schon lief. Eine feste Umgebung – vergebene Adressen, bekannte Dienste, eine geschriebene AGENTS.md – sorgt dafür, dass das nicht passiert, und ist ein großer Teil des Grundes, warum Zeltro so aufgebaut ist.

Weil die Projekte sich ein Netzwerk teilen, können sich auch ihre Agenten abstimmen. Ändert ein Projekt seine API, kann sein Agent den Agenten der Projekte Bescheid geben, die davon abhängen.

Die Zeltro-App: Eine Nachricht vom Agenten eines Projekts kommt in der Sitzung eines anderen Projekts an und meldet, dass seine API umgezogen ist
Der Agent eines Projekts sagt einem anderen, dass seine API umgezogen ist.

Fragen

Muss ich irgendwo einen Port wählen?

Nein. Jedes Projekt bekommt beim Anlegen eine Container-IP und einen veröffentlichten Port. zeltro status gibt für jedes die lokale Adresse und die LAN-Adresse aus.

Was ist der Unterschied zwischen den beiden Adressen?

Die lokale ist die eigene IP des Containers im Docker-Netzwerk – ohne Port, weil sonst nichts unter dieser Adresse liegt. Die LAN-Adresse ist die IP Ihres Rechners plus der veröffentlichte Port des Projekts, und über sie muss ein anderes Gerät gehen.

Unter macOS und Windows hält Docker Container in einer virtuellen Maschine, und die Container-IP ist vom Host aus nicht erreichbar, deshalb lautet die lokale Adresse dort http://localhost:<port>. Zeltro erkennt das und gibt die Adresse aus, die tatsächlich funktioniert.

Können sich Projekte über ihren Namen erreichen?

Ja, aus Containern heraus. Alle Projekte hängen im selben Docker-Netzwerk, und das eingebaute DNS von Docker löst dort Projekt- und Dienstnamen auf. Genau das macht projektübergreifende Aufrufe und gemeinsame Datenbanken so einfach.

Ihr Browser ist nicht in diesem Netzwerk, deshalb nutzt er die Adresse oben statt eines Namens.

Was, wenn zwei Projekte unterschiedliche Postgres-Versionen brauchen?

Das geht nicht – eine gemeinsame Instanz ist der Kompromiss. Ist das eine harte Anforderung, nutzen Sie für diese Projekte Werkzeuge pro Projekt, oder lassen Sie den Ausreißer auf einem eigenen Stack laufen.

Funktioniert das mit einem Projekt, das eine eigene docker-compose.yaml hat?

Ja. Mitgebrachte Datenbankdienste werden entfernt, und die App wird auf die gemeinsamen umgestellt, mit den Zugangsdaten in der .env. Die Originaldatei bleibt als docker-compose.upstream.yaml erhalten.

Und die Datenbanken selbst – sehen Projekte gegenseitig ihre Daten?

Sie teilen sich den Server, nicht die Datenbank. Jedes Projekt bekommt seine eigene Datenbank und eigene Zugangsdaten. Projektübergreifender Zugriff ist bewusst möglich, was ein Microservice-artiges Setup einfach macht, aber nichts wird aus Versehen geteilt.

Probieren Sie Zeltro auf Ihrem eigenen Rechner aus

Kostenlos für den privaten Gebrauch, ohne Konto. Entwickeln Sie mit der KI, für die Sie schon bezahlen, und behalten Sie App, Daten und Code auf Ihrem eigenen Rechner.

Zeltro installieren Warum ein eigener Schlüssel

Lieber nicht selbst einrichten? Ich übernehme das für Sie.

Geprüft am 2026-08-22. Andere Produkte ändern sich oft – wenn hier etwas nicht mehr stimmt, sagen Sie uns Bescheid und wir korrigieren es.