Docker-Container auf den Host zugreifen: Vollständiger Leitfaden zu host.docker.internal

Freitagnachmittag, 15 Uhr – ich starre auf die Fehlermeldung im Terminal: Connection refused.
Ehrlich gesagt war ich ziemlich frustriert. MySQL lief lokal einwandfrei, Navicat verband sich, die Kommandozeile funktionierte – nur die Anwendung im Container wollte nicht verbinden. Dreimal die Connection String geprüft: localhost:3306, alles korrekt. Benutzername und Passwort stimmten. Wo lag das Problem?
Am Ende war es das Wort localhost.
Wenn Ihnen das bekannt vorkommt – im Docker-Container schlägt die Verbindung zum Host über localhost oder 127.0.0.1 ständig fehl – ist dieser Artikel für Sie. Ich erkläre klar und direkt: Warum localhost im Container nicht das ist, was Sie erwarten, und wie Sie mit host.docker.internal elegant eine Lösung finden.
In diesem Artikel lernen Sie:
- Die wirkliche Ursache der Netzwerk-Isolation (ohne Fachjargon)
- Die richtige Konfiguration für Mac, Windows und Linux
- Eine praktische Troubleshooting-Checkliste zum Nachschlagen
Warum localhost nicht funktioniert
Kurz gesagt: Der Container hat seine eigene Netzwerk-Welt.
Klingt abstrakt? Stellen Sie sich den Container als separates kleines Haus vor – mit eigener Adresse, eigenem Briefkasten, allem drum und dran. Wenn Sie im Container „localhost“ rufen oder 127.0.0.1 ansprechen, suchen Sie dieses Haus selbst – nicht den Host außerhalb.
Konkret:
- Auf dem Host zeigt
localhostauf den Host selbst - Im Container zeigt
localhostauf den Container selbst - Zwei
localhost– völlig verschiedene Dinge
Als ich das zum ersten Mal hörte, war ich überrascht. MySQL lief doch auf meinem Rechner – warum konnte der Container nicht verbinden? Genau deshalb: Der Container sucht MySQL in seiner eigenen Welt und findet es natürlich nicht.
Netzwerk-Isolation des Containers
Docker erstellt für jeden Container einen eigenen „Netzwerk-Namespace“ (keine Sorge wegen des Begriffs). Vereinfacht:
Jeder Container hat seine eigene Netzwerkkarte, eigene IP und eigene Routing-Tabelle. Wie zwei Wohnungen im selben Gebäude – gleicher Standort, aber getrennte Netzwerke.
Container und Host sind über die virtuelle Bridge docker0 verbunden. Container-IPs sind meist 172.17.0.x; aus Sicht des Containers ist der Host 172.17.0.1 (Gateway der Bridge).
localhost im Container meint 127.0.0.1 des Containers – nicht des Hosts. Deshalb schlägt die Verbindung zur MySQL auf dem Host fehl.
Typische Fehlermeldungen:
Error: connect ECONNREFUSED 127.0.0.1:3306
oder:
Can't connect to MySQL server on 'localhost' (111)
Klassischer Fehler: localhost im Container, um Host-Dienste zu erreichen.
Was ist host.docker.internal?
Wenn localhost nicht geht – wie erreicht der Container den Host?
Docker bietet eine elegante Lösung: host.docker.internal. Das ist eine spezielle Domain, die automatisch zur Host-IP aufgelöst wird. Denken Sie daran als „Spitzname“ des Hosts – unabhängig von der echten IP.
Beispiel: MySQL lauscht auf dem Host auf Port 3306 – im Container verbinden Sie so:
mysql://user:[email protected]:3306/dbname
Egal ob der Host 192.168.1.100 oder 10.0.0.5 hat – host.docker.internal zeigt immer auf die richtige Adresse.
Praktisch, oder?
Versionen und Plattform-Unterstützung
Hier gibt es eine wichtige Einschränkung.
Mac und Windows (Docker Desktop)
Mit Docker Desktop (der Version mit GUI) wird host.docker.internal seit Version 18.03 (März 2018) nativ unterstützt. Out of the box, keine Extra-Konfiguration.
Einfach im Code host.docker.internal verwenden:
const mysql = require('mysql2');
const connection = mysql.createConnection({
host: 'host.docker.internal', // So einfach
port: 3306,
user: 'root',
password: 'your_password'
});
Linux (Docker Engine)
Auf Linux ist es anders. Docker läuft direkt auf dem System – ohne VM-Zwischenschicht wie auf Mac/Windows. host.docker.internal existiert standardmäßig nicht.
Ab Docker Engine 20.10 (Dezember 2020) lässt sich das manuell aktivieren. Wie genau, erkläre ich im nächsten Abschnitt.
Bei älteren Versionen gibt es Alternativen:
172.17.0.1(Standard-Gateway der Docker-Bridge)- Die tatsächliche Host-IP im Docker-Netzwerk
docker.for.mac.host.internal(nur ältere Mac-Versionen)
Konfiguration auf drei Plattformen
Hier die praxisnahen, kopierbaren Konfigurationen.
Mac/Windows (Docker Desktop)
Der einfachste Fall.
Methode 1: Direkt im Code
Keine Extra-Konfiguration nötig – einfach host.docker.internal verwenden:
# docker-compose.yml
version: '3'
services:
app:
image: myapp:latest
environment:
- DB_HOST=host.docker.internal # Direkt nutzen
- DB_PORT=3306
Methode 2: Explizit deklarieren (optional)
Nicht erforderlich, aber möglich mit extra_hosts:
version: '3'
services:
app:
image: myapp:latest
extra_hosts:
- "host.docker.internal:host-gateway"
environment:
- DB_HOST=host.docker.internal
host-gateway ist die Syntax ab Docker 20.10+ und bedeutet „Gateway-Adresse des Hosts“.
Mit docker run:
docker run -d \
--add-host=host.docker.internal:host-gateway \
-e DB_HOST=host.docker.internal \
myapp:latest
Linux (Docker Engine)
Auf Linux etwas mehr Aufwand – manuelle Konfiguration nötig.
Methode 1: Empfohlen – host-gateway
Allgemeinste Methode für Docker 20.10+ auf allen Plattformen:
# docker-compose.yml
version: '3'
services:
app:
image: myapp:latest
extra_hosts:
- "host.docker.internal:host-gateway" # Schlüssel-Konfiguration
environment:
- DB_HOST=host.docker.internal
- DB_PORT=3306
Mit docker run:
docker run -d \
--add-host=host.docker.internal:host-gateway \
-e DB_HOST=host.docker.internal \
myapp:latest
Vorteil: plattformübergreifend – dieselbe Konfiguration auf Mac, Windows und Linux.
Methode 2: Alternative – Docker-Bridge-IP
Wenn host-gateway nicht verfügbar ist (alte Docker-Version):
version: '3'
services:
app:
image: myapp:latest
extra_hosts:
- "host.docker.internal:172.17.0.1" # Standard-Gateway
environment:
- DB_HOST=host.docker.internal
172.17.0.1 ist das Standard-Gateway des Docker-Bridge-Netzwerks. In den meisten Fällen korrekt, sofern Sie die Standard-Netzwerk-Konfiguration nicht geändert haben.
Methode 3: Ultimative Lösung – Host-Netzwerkmodus
Wenn nichts anderes hilft:
docker run -d \
--network=host \
-e DB_HOST=localhost \ # Jetzt funktioniert localhost
myapp:latest
Oder in docker-compose:
version: '3'
services:
app:
image: myapp:latest
network_mode: "host" # Host-Netzwerk nutzen
environment:
- DB_HOST=localhost # localhost geht direkt
Vorteile: Einfach – der Container nutzt den Netzwerk-Stack des Hosts; localhost ist wirklich localhost.
Nachteile:
- Zerstört die Netzwerk-Isolation des Containers
- Gemeinsame Ports mit dem Host, Konflikte möglich (z. B. Port 8080)
- Nur auf Linux, nicht auf Mac/Windows
- In Produktion nicht empfohlen – nur für lokale Entwicklung
Plattformübergreifende Konfiguration (stark empfohlen)
Wenn im Team Mac und Linux gemischt sind oder der Code in verschiedenen Umgebungen läuft:
# docker-compose.yml
version: '3'
services:
app:
image: myapp:latest
extra_hosts:
- "host.docker.internal:host-gateway" # Auf allen Plattformen bekannt
environment:
- DB_HOST=host.docker.internal
- DB_PORT=3306
- DB_USER=root
- DB_PASSWORD=your_password
Diese Konfiguration funktioniert auf Docker 20.10+ (Ende 2020) auf allen Plattformen. Wenn Ihre Docker-Version älter ist – ehrlich gesagt, Zeit für ein Upgrade.
Wichtige Host-Dienst-Konfiguration
Die Container-Seite allein reicht nicht.
Auch die Dienste auf dem Host müssen richtig konfiguriert sein – sonst schlägt die Verbindung trotzdem fehl. Das übersehen viele.
Dienst muss auf der richtigen Adresse lauschen
Der häufigste Stolperstein.
Viele Dienste lauschen standardmäßig nur auf 127.0.0.1 – also nur lokale Verbindungen. Docker-Container gelten nicht als „lokal“; Anfragen über die Docker-Bridge werden abgelehnt.
Der Dienst muss auf 0.0.0.0 lauschen – „alle Netzwerkschnittstellen“.
MySQL-Konfiguration
MySQL-Konfigurationsdatei, typischerweise:
- Linux:
/etc/mysql/mysql.conf.d/mysqld.cnf - Mac (Homebrew):
/usr/local/etc/my.cnf - Windows:
C:\ProgramData\MySQL\MySQL Server 8.0\my.ini
bind-address anpassen:
[mysqld]
# Vorher oft so:
# bind-address = 127.0.0.1
# So ändern:
bind-address = 0.0.0.0
MySQL neu starten:
# Linux
sudo systemctl restart mysql
# Mac
brew services restart mysql
# Windows
# MySQL-Dienst im Dienst-Manager neu starten
Redis-Konfiguration
redis.conf bearbeiten (meist /etc/redis/redis.conf oder /usr/local/etc/redis.conf):
# Diese Zeile finden
bind 127.0.0.1 -::1
# Ändern zu
bind 0.0.0.0
Redis neu starten:
# Linux
sudo systemctl restart redis
# Mac
brew services restart redis
PostgreSQL-Konfiguration
postgresql.conf bearbeiten:
listen_addresses = '*' # Alle Adressen
Außerdem pg_hba.conf – Docker-Netzwerk erlauben:
# Zeile hinzufügen: 172.17.0.0/16 erlauben
host all all 172.17.0.0/16 md5
Benutzerrechte konfigurieren (MySQL)
Selbst wenn MySQL auf 0.0.0.0 lauscht, gibt es noch Benutzerrechte.
MySQL verwaltet Rechte nach „Benutzer@Quell-Host“. root@localhost und root@% sind unterschiedliche Benutzer.
Erlaubt der Benutzer nur localhost, schlägt die Container-Verbindung fehl. Berechtigung für das Docker-Netzwerk erteilen:
-- Option 1: Von jedem Host (einfach, weniger sicher)
GRANT ALL PRIVILEGES ON *.* TO 'your_user'@'%' IDENTIFIED BY 'your_password';
-- Option 2: Nur Docker-Netzwerk (sicherer)
GRANT ALL PRIVILEGES ON *.* TO 'your_user'@'172.17.0.%' IDENTIFIED BY 'your_password';
-- Rechte neu laden
FLUSH PRIVILEGES;
Bei MySQL 8.0+ etwas andere Syntax:
-- Benutzer anlegen
CREATE USER 'your_user'@'%' IDENTIFIED BY 'your_password';
-- Berechtigung erteilen
GRANT ALL PRIVILEGES ON *.* TO 'your_user'@'%';
FLUSH PRIVILEGES;
Firewall-Konfiguration
Manche System-Firewalls blockieren Container-Zugriff auf Host-Dienste.
Firewall-Status prüfen:
# Linux (ufw)
sudo ufw status
# Linux (firewalld)
sudo firewall-cmd --state
Docker-Netzwerk erlauben (Beispiel MySQL Port 3306):
# ufw
sudo ufw allow from 172.17.0.0/16 to any port 3306
# firewalld
sudo firewall-cmd --permanent --zone=public --add-rich-rule='rule family="ipv4" source address="172.17.0.0/16" port port="3306" protocol="tcp" accept'
sudo firewall-cmd --reload
Sicherheitshinweise
Lauschen auf 0.0.0.0 birgt Risiken – der Dienst ist im Netzwerk erreichbar.
In Produktion:
-
Nur bestimmte Schnittstelle: Wenn bekannt, welche Netzwerkkarte Docker nutzt
bind-address = 172.17.0.1 -
Mit Firewall kombinieren: Nur Docker-Netzwerk erlauben
-
Eigener Datenbank-Container: Datenbank nicht auf dem Host, sondern per Docker Compose im gleichen Netzwerk – sicherer
Lokale Entwicklung:
Ehrlich gesagt ist 0.0.0.0 für lokale Entwicklung meist unproblematisch. Ihr Rechner ist kein Server – von außen kommt niemand rein.
Troubleshooting-Checkliste
Verbindungsproblem? Schritt für Schritt durchgehen.
Problem 1: Connection refused (Verbindung abgelehnt)
Häufigster Fehler:
Error: connect ECONNREFUSED host.docker.internal:3306
oder:
Can't connect to MySQL server on 'host.docker.internal' (111)
Mögliche Ursachen und Schritte:
Schritt 1: Dienst auf dem Host prüfen
Auf dem Host:
# MySQL prüfen
sudo systemctl status mysql # Linux
brew services list # Mac
# Lauscht der Port?
netstat -an | grep 3306
# oder
lsof -i :3306
Wenn der Dienst nicht läuft – zuerst starten.
Schritt 2: Listen-Adresse prüfen
Auf dem Host:
# Auf welcher Adresse lauscht MySQL?
sudo netstat -tlnp | grep 3306
Erwartete Ausgabe:
tcp 0 0 0.0.0.0:3306 0.0.0.0:* LISTEN 1234/mysqld
Entscheidend ist die dritte Spalte. 0.0.0.0:3306 = alle Adressen, OK. 127.0.0.1:3306 = nur lokal – Container kommt nicht durch.
Lösung: bind-address auf 0.0.0.0 setzen (siehe Abschnitt „Host-Dienst-Konfiguration“).
Schritt 3: Firewall prüfen
Firewall temporär deaktivieren zum Testen:
# Linux (ufw)
sudo ufw disable
# Linux (firewalld)
sudo systemctl stop firewalld
# Mac
# Systemeinstellungen -> Sicherheit -> Firewall -> Aus
Wenn es ohne Firewall funktioniert – Firewall-Regeln setzen und wieder aktivieren.
Problem 2: Connection timeout (Verbindungs-Timeout)
Fehlermeldung:
Error: connect ETIMEDOUT host.docker.internal:3306
Timeout ist oft hartnäckiger – Pakete gehen raus, Antwort kommt nicht.
Schritte:
Schritt 1: host.docker.internal auflösbar?
Im Container:
# Container betreten
docker exec -it your_container sh
# Ping testen
ping host.docker.internal
Ping schlägt fehl oder „unknown host“ – host.docker.internal ist nicht konfiguriert.
Linux-Nutzer: Prüfen, ob --add-host=host.docker.internal:host-gateway in docker-compose oder docker run gesetzt ist.
Schritt 2: Portnummer korrekt?
Wirklich 3306? Vielleicht anderer MySQL-Port?
Auf dem Host prüfen:
# Tatsächlichen MySQL-Port anzeigen
sudo netstat -tlnp | grep mysqld
Schritt 3: Netzwerk vom Container zum Host
Im Container:
# Port erreichbar?
telnet host.docker.internal 3306
# Ohne telnet: nc
nc -zv host.docker.internal 3306
Port nicht erreichbar – Firewall und Dienst-Konfiguration erneut prüfen.
Problem 3: Unknown host (host.docker.internal nicht auflösbar)
Fehlermeldung:
getaddrinfo ENOTFOUND host.docker.internal
DNS-Auflösung schlägt fehl – der Container kennt die Domain nicht.
Lösung:
extra_hosts in der Container-Konfiguration:
services:
app:
extra_hosts:
- "host.docker.internal:host-gateway"
Oder bei docker run:
docker run --add-host=host.docker.internal:host-gateway ...
Problem 4: Authentifizierung fehlgeschlagen (Access denied)
Fehlermeldung:
Access denied for user 'root'@'172.17.0.2' (using password: YES)
Verbindung zu MySQL klappt – aber Benutzerrechte stimmen nicht.
Lösung:
MySQL-Benutzer berechtigen:
-- Aktuelle Benutzer anzeigen
SELECT user, host FROM mysql.user WHERE user='root';
-- Nur root@localhost vorhanden? root@% oder [email protected].% anlegen
CREATE USER 'root'@'%' IDENTIFIED BY 'your_password';
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%';
FLUSH PRIVILEGES;
Problem 5: Plattformübergreifende Konfiguration inkonsistent
Mac-Nutzer und Linux-Nutzer, dieselbe docker-compose.yml – auf Mac OK, auf Linux nicht.
Lösung:
Einheitlich host-gateway – auf allen Plattformen:
services:
app:
extra_hosts:
- "host.docker.internal:host-gateway"
Docker ≥ 20.10 voraussetzen. Bei veralteten Versionen im Team – Upgrade empfehlen.
Schnelle Merkregel
Bei Verbindungsproblemen in dieser Reihenfolge prüfen:
- Dienst läuft? →
systemctl status/brew services list - Lauscht richtig? →
netstat -tlnp,0.0.0.0oder127.0.0.1? - Container konfiguriert? →
extra_hostsoder--add-host? - DNS OK? → Im Container
ping host.docker.internal - Port erreichbar? → Im Container
telnetodernc - Firewall? → Temporär deaktivieren zum Testen
- Rechte OK? → MySQL-Benutzer
@localhostoder@%?
In neun von zehn Fällen liegt es an den ersten drei Punkten.
Praxisbeispiele
Theorie genug – zwei konkrete Beispiele.
Beispiel 1: Spring-Boot-App verbindet sich mit Host-MySQL
Szenario: Spring-Boot-Projekt in Docker, lokale MySQL-Datenbank auf dem Host.
Schritt 1: Spring Boot konfigurieren
application.yml:
spring:
datasource:
# host.docker.internal für Host-MySQL
url: jdbc:mysql://host.docker.internal:3306/mydb?useSSL=false&serverTimezone=UTC
username: root
password: your_password
driver-class-name: com.mysql.cj.jdbc.Driver
Schritt 2: Docker Compose
docker-compose.yml:
version: '3.8'
services:
app:
build: .
ports:
- "8080:8080"
extra_hosts:
- "host.docker.internal:host-gateway" # Schlüssel-Konfiguration
environment:
# Optional per Umgebungsvariable
SPRING_DATASOURCE_URL: jdbc:mysql://host.docker.internal:3306/mydb
SPRING_DATASOURCE_USERNAME: root
SPRING_DATASOURCE_PASSWORD: your_password
Schritt 3: Host-MySQL konfigurieren
/etc/mysql/mysql.conf.d/mysqld.cnf bearbeiten:
[mysqld]
bind-address = 0.0.0.0
MySQL neu starten:
sudo systemctl restart mysql
Benutzer berechtigen:
CREATE USER 'root'@'%' IDENTIFIED BY 'your_password';
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%';
FLUSH PRIVILEGES;
Schritt 4: Starten und testen
docker-compose up --build
Log HikariPool-1 - Start completed = Datenbankverbindung erfolgreich.
Troubleshooting aus der Praxis:
Beim ersten Mal Connection refused. Ablauf:
- MySQL läuft?
systemctl status mysql→ ja - Listen-Adresse?
netstat -tlnp | grep 3306→127.0.0.1:3306 bind-address = 0.0.0.0, MySQL neu starten- Erneut starten – Verbindung OK
Beispiel 2: Node.js-App verbindet sich mit Host-Redis
Szenario: Node.js-Projekt, Redis als Cache, Redis läuft lokal auf dem Host.
Schritt 1: Node.js-Code
// redis-client.js
const redis = require('redis');
const client = redis.createClient({
host: process.env.REDIS_HOST || 'host.docker.internal',
port: process.env.REDIS_PORT || 6379,
// Bei Redis-Passwort
password: process.env.REDIS_PASSWORD
});
client.on('connect', () => {
console.log('Redis connected successfully');
});
client.on('error', (err) => {
console.error('Redis error:', err);
});
module.exports = client;
Schritt 2: Docker Compose
docker-compose.yml:
version: '3.8'
services:
app:
build: .
ports:
- "3000:3000"
extra_hosts:
- "host.docker.internal:host-gateway"
environment:
NODE_ENV: development
REDIS_HOST: host.docker.internal
REDIS_PORT: 6379
Schritt 3: Host-Redis konfigurieren
/etc/redis/redis.conf oder /usr/local/etc/redis.conf:
# bind-Zeile finden
bind 127.0.0.1 ::1
# Ändern zu
bind 0.0.0.0
Bei protected-mode yes auch anpassen:
protected-mode no # OK für lokale Entwicklung, nicht in Produktion
Redis neu starten:
# Linux
sudo systemctl restart redis
# Mac
brew services restart redis
Schritt 4: Verifizieren
App starten:
docker-compose up
Redis connected successfully = alles OK.
Plattformübergreifend:
Früher musste man zwischen Mac und Linux unterscheiden – heute reicht host.docker.internal überall, solange docker-compose extra_hosts: ["host.docker.internal:host-gateway"] enthält.
Beispiel 3: Vollständige Entwicklungsumgebung
Praktisches Template – App-Container verbindet sich mit Host-MySQL und Redis:
# docker-compose.yml
version: '3.8'
services:
app:
build: .
ports:
- "8080:8080"
extra_hosts:
- "host.docker.internal:host-gateway"
environment:
# Datenbank
DB_HOST: host.docker.internal
DB_PORT: 3306
DB_NAME: myapp
DB_USER: root
DB_PASSWORD: your_password
# Redis
REDIS_HOST: host.docker.internal
REDIS_PORT: 6379
# App
NODE_ENV: development
PORT: 8080
volumes:
- .:/app
- /app/node_modules # node_modules nicht mounten
command: npm run dev # Hot Reload im Dev-Modus
Zugehörige Host-Konfiguration:
# MySQL
# /etc/mysql/mysql.conf.d/mysqld.cnf bearbeiten
bind-address = 0.0.0.0
# Neustart: sudo systemctl restart mysql
# Redis
# /etc/redis/redis.conf bearbeiten
bind 0.0.0.0
protected-mode no
# Neustart: sudo systemctl restart redis
# Firewall (falls nötig)
sudo ufw allow from 172.17.0.0/16 to any port 3306
sudo ufw allow from 172.17.0.0/16 to any port 6379
Diese Konfiguration funktioniert auf Mac und Linux – kopieren und loslegen.
Zusammenfassung
Kernpunkte in drei Sätzen:
1. Prinzip verstehen
Der Container hat sein eigenes Netzwerk – localhost im Container meint den Container, nicht den Host. Das ist Netzwerk-Namespace-Isolation by Design, kein Bug.
2. Die richtige Methode wählen
Je nach Umgebung:
| Umgebung | Empfohlene Lösung | Konfiguration |
|---|---|---|
| Mac/Windows (Docker Desktop) | host.docker.internal direkt | Keine Extra-Konfiguration |
| Linux (Docker Engine 20.10+) | extra_hosts: host-gateway | docker-compose oder —add-host |
| Plattformübergreifendes Team | extra_hosts: host-gateway | Einheitliche Konfiguration |
| Älteres Linux | 172.17.0.1 | extra_hosts mit fester IP |
| Letzter Ausweg | --network=host | Nur lokale Entwicklung |
3. Host-Dienste richtig konfigurieren
Container-Seite allein reicht nicht:
- Listen-Adresse auf
0.0.0.0 - MySQL-Benutzer für Docker-Netzwerk berechtigen
- Firewall für Docker-Netzwerk öffnen
Entscheidungsbaum
Bei Verbindungsproblemen:
Keine Verbindung zum Host?
↓
Mac/Windows oder Linux?
↓
Mac/Windows:
→ host.docker.internal direkt nutzen
→ Wenn nicht: Host-Dienst-Konfiguration prüfen
Linux:
→ Docker ≥ 20.10?
Ja → extra_hosts: host-gateway
Nein → extra_hosts: 172.17.0.1
→ Host-Dienst-Konfiguration prüfen
→ Firewall prüfen
Alles probiert?
→ Checkliste Schritt für Schritt
→ Letzter Ausweg: --network=host (nur Entwicklung)
Abschließend
Container-Entwicklung ist praktisch, aber das Netzwerk hat Fallstricke. Mit host.docker.internal und host-gateway lösen Sie die meisten Probleme.
Diesen Artikel bookmarken – beim nächsten Verbindungsproblem einfach nachschlagen. Wenn Kollegen dasselbe Problem haben, teilen Sie den Link.
Haben Sie seltsame Container-Netzwerk-Probleme erlebt oder bessere Lösungen? Schreiben Sie gerne in die Kommentare – vielleicht hilft es anderen.
Vollständiger Ablauf: Docker-Container auf Host-Dienste zugreifen
host.docker.internal nutzen, um Container-Zugriff auf Host-Dienste zu lösen – für Mac, Windows und Linux
⏱️ Estimated time: 15 min
- 1
Step 1: Ursache und Lösung verstehen
Ursache: localhost oder 127.0.0.1 im Container verbindet nicht zum Host, weil localhost im Container auf den Container selbst zeigt – nicht auf den Host. Spezielle Konfiguration ist nötig.
Lösung: host.docker.internal als „magische Domain“ nutzen; sie wird automatisch zur Host-IP aufgelöst.
Plattformen:
• Mac/Windows: Docker Desktop unterstützt nativ, keine Extra-Konfiguration
• Linux: Docker 20.10+, mit --add-host oder extra_hosts in docker-compose - 2
Step 2: Konfiguration auf Mac/Windows
Schritte auf Mac/Windows:
1. host.docker.internal direkt nutzen:
docker run -e DATABASE_URL=host.docker.internal:3306 my-app
2. localhost in der App-Konfiguration ersetzen:
• Connection String: host.docker.internal:3306
• Umgebungsvariable: DATABASE_HOST=host.docker.internal
3. Verbindung prüfen:
• Im Container: docker exec -it container-name ping host.docker.internal
• App-Verbindung direkt testen
Hinweis: Mac/Windows brauchen keine Extra-Konfiguration – Docker Desktop erledigt das automatisch. - 3
Step 3: Linux-Konfiguration und Troubleshooting
Konfiguration auf Linux:
1. Docker ≥ 20.10 (empfohlen):
docker run --add-host=host.docker.internal:host-gateway my-app
Oder in docker-compose.yml:
extra_hosts:
- "host.docker.internal:host-gateway"
2. Docker < 20.10:
docker run --add-host=host.docker.internal:172.17.0.1 my-app
3. Vollständige Checkliste:
• Dienst auf dem Host läuft (netstat -tuln | grep 3306)
• Port erreichbar (telnet host.docker.internal 3306)
• host.docker.internal statt localhost
• Auf Linux --add-host setzen
• Firewall prüfen (iptables -L)
• Dienst hört auf 0.0.0.0, nicht nur 127.0.0.1
FAQ
Warum verbindet localhost im Container nicht zum Host?
Analog zu zwei getrennten Häusern auf derselben Maschine – jedes hat seine eigene Adresse. localhost im Container meint das interne Netz des Containers, nicht das des Hosts.
Lösung: host.docker.internal nutzen – die Domain wird zur Host-IP aufgelöst.
Wird host.docker.internal auf allen Plattformen unterstützt?
• Mac/Windows (Docker Desktop): nativ, keine Konfiguration
• Linux (Docker 20.10+): --add-host manuell setzen
• Linux (Docker < 20.10): 172.17.0.1 als Host-IP
Für plattformübergreifende Teams: extra_hosts in docker-compose vereinheitlichen.
host.docker.internal konfiguriert, Verbindung schlägt trotzdem fehl?
1. Dienst auf dem Host prüfen:
netstat -tuln | grep PORT
2. Listen-Adresse prüfen:
Dienst muss auf 0.0.0.0 lauschen, nicht nur 127.0.0.1
3. Netzwerk testen:
docker exec -it container-name ping host.docker.internal
docker exec -it container-name telnet host.docker.internal PORT
4. Firewall:
iptables -L (Linux)
Windows-Firewall
5. Letzter Ausweg (nur Entwicklung):
--network=host (zerstört Container-Isolation)
Sollte man host.docker.internal in Produktion nutzen?
• Servicenamen (Docker-Compose-Netzwerk) oder Containernamen
• Explizite IP-Adressen
• Service Discovery (z. B. Consul, etcd)
host.docker.internal eignet sich für:
• Lokale Entwicklung
• Debugging und Tests
• Zugriff auf Host-Tools (Datenbank, Redis)
In Produktion führt es zu:
• Abhängigkeit von Host-Netzwerk
• Verlust von Container-Vorteilen
• Höherer Betriebskomplexität
12 Min. Lesezeit · Veröffentlicht am: 17. Dez. 2025 · Aktualisiert am: 14. Juli 2026
Docker Praxisleitfaden
Wenn du über die Suche hier gelandet bist, kommst du am schnellsten weiter, indem du zum vorherigen oder nächsten Beitrag dieser Serie springst.
Vorheriger
Docker Port Mapping: Lassen Sie sich von „Port bereits belegt" nicht den Freitagabend verderben
Von der Fehlersuche bei belegten Ports bis zur Performance-Optimierung: Docker Port Mapping systematisch meistern und „port already allocated" vermeiden
Teil 20 von 38
Nächster
Docker-Netzwerkmodi in der Praxis: Entscheidungsleitfaden für bridge, host und overlay
Vergleich von Performance, Einsatzszenarien und Konfiguration für die drei Docker-Netzwerkmodi – mit Entscheidungsfluss und Messdaten. Standard bridge, performancekritisch host, clusterübergreifend overlay.
Teil 22 von 38
Ähnliche Beiträge
Docker vs. virtuelle Maschine: Performance-Unterschiede und Szenario-Auswahl in 5 Minuten

Docker vs. virtuelle Maschine: Performance-Unterschiede und Szenario-Auswahl in 5 Minuten
Docker-Installation ohne Fallstricke (2025): Vollständige Lösungen von permission denied bis zum erfolgreichen Start


Kommentare
Melde dich mit GitHub an, um einen Kommentar zu hinterlassen