Arbeiten Sie mit Docker in einem Unternehmensnetzwerk, auf einem Server mit eingeschränktem Zugang oder möchten Sie, dass Ihre Container über eine bestimmte IP ins Internet gehen? Ohne die richtige Proxy-Konfiguration kann Docker einfach keine Images von Docker Hub oder einem anderen Registry herunterladen. In diesem Artikel werden wir alle Ebenen des Proxy-Setups durchgehen — vom Daemon bis zum einzelnen Container.
Warum braucht Docker überhaupt einen Proxy
Docker ist ein Tool, das ständig auf externe Ressourcen zugreift. Bei jedem docker pull oder docker build greift der Daemon auf Docker Hub, GitHub Container Registry, Google Container Registry oder Ihr privates Registry zu. Und hier beginnen die Probleme.
Situationen, in denen man nicht ohne Proxy auskommt:
- Unternehmensnetzwerk mit Firewall — der gesamte Datenverkehr muss über den Unternehmensproxy-Server laufen, sonst wird die Verbindung blockiert.
- Geo-Beschränkungen — Docker Hub oder bestimmte Registries sind aus Ihrem Land oder Rechenzentrum nicht erreichbar.
- Begrenzter Server ohne direkten Internetzugang — VPS in einem geschlossenen Netzwerk, wo Internet nur über ein Gateway verfügbar ist.
- Kontrolle des ausgehenden Datenverkehrs von Containern — Sie möchten, dass Anwendungen innerhalb von Containern über eine bestimmte IP ins Internet gehen, beispielsweise für Scraping, API-Anfragen oder das Testen geoabhängiger Inhalte.
- Anonymisierung von Anfragen — die echte IP des Servers bei Anfragen an externe Dienste aus dem Container verbergen.
- Rate Limiting — Docker Hub begrenzt die Anzahl der Pull-Anfragen für anonyme Benutzer (100 Pulls in 6 Stunden). Über einen Proxy mit IP-Rotation kann man diese Einschränkung umgehen.
Es ist wichtig zu verstehen, dass Docker nicht eine Anwendung ist, sondern ein System aus mehreren Komponenten. Der Daemon (dockerd) läuft auf dem Host und zieht Images. Container sind isolierte Prozesse mit eigenen Netzwerkeinstellungen. Daher ist die Proxy-Konfiguration für den Daemon und für Container zwei verschiedene Aufgaben, die unterschiedlich gelöst werden.
Drei Ebenen des Proxy-Setups in Docker
Bevor wir in die Konfigurationen eintauchen, müssen wir die Architektur verstehen. In Docker gibt es drei unabhängige Ebenen, von denen jede eine separate Proxy-Konfiguration erfordert:
| Ebene | Was macht sie | Wo wird sie konfiguriert |
|---|---|---|
| Docker Daemon | Lädt Images herunter (docker pull), greift auf Registries zu | systemd override oder daemon.json |
| Docker Build | Führt Befehle beim Erstellen des Images aus (RUN apt-get, pip install usw.) | ARG und ENV im Dockerfile oder --build-arg |
| Runtime Container | Laufende Anwendung, die HTTP-Anfragen stellt | ENV bei docker run oder in docker-compose.yml |
Ein typischer Fehler ist es, den Proxy nur auf einer Ebene zu konfigurieren und sich zu wundern, warum die Images trotzdem nicht heruntergeladen werden oder die Anwendung den Proxy nicht erkennt. Lassen Sie uns jede Ebene im Detail durchgehen.
Proxy für Docker Daemon einrichten (Pull von Images)
Dies ist die wichtigste Konfiguration, wenn Sie Images über einen Proxy herunterladen möchten. Der Docker Daemon ist ein Systemdienst, der über systemd gestartet wird. Die Umgebungsvariablen Ihres Benutzers oder sogar von root sieht er nicht. Der Proxy muss genau in die Umgebung des Dienstes übergeben werden.
Methode 1: über systemd override (empfohlen)
Erstellen Sie ein Verzeichnis für die Überschreibung der Dienstkonfiguration:
sudo mkdir -p /etc/systemd/system/docker.service.d
Erstellen Sie die Datei /etc/systemd/system/docker.service.d/http-proxy.conf mit folgendem Inhalt:
[Service] Environment="HTTP_PROXY=http://username:password@proxy-host:port" Environment="HTTPS_PROXY=http://username:password@proxy-host:port" Environment="NO_PROXY=localhost,127.0.0.1,::1,your-private-registry.example.com"
Wenn der Proxy ohne Authentifizierung ist, entfernen Sie einfach username:password@. Nach dem Erstellen der Datei laden Sie die systemd-Konfiguration neu und starten Docker neu:
sudo systemctl daemon-reload sudo systemctl restart docker
Überprüfen Sie, ob die Einstellungen angewendet wurden:
sudo systemctl show --property=Environment docker
In der Ausgabe sollten Ihre Variablen HTTP_PROXY und HTTPS_PROXY erscheinen.
Methode 2: über ~/.docker/config.json (Docker Desktop und neuere Versionen)
Seit Docker Engine 23.0 gibt es eine benutzerfreundlichere Methode — die Proxy-Konfiguration über die Client-Konfigurationsdatei. Erstellen oder bearbeiten Sie die Datei ~/.docker/config.json:
{
"proxies": {
"default": {
"httpProxy": "http://username:password@proxy-host:port",
"httpsProxy": "http://username:password@proxy-host:port",
"noProxy": "localhost,127.0.0.1,::1"
}
}
}
Diese Methode ist praktisch, da sie keine Root-Rechte erfordert und den Daemon nicht neu starten muss. Die Einstellungen werden automatisch an die Container beim Build als Build-Argumente übergeben. Für die Verwaltung von Pull-Anfragen des Daemons ist jedoch weiterhin die Methode über systemd erforderlich.
💡 Wichtig zu NO_PROXY
Fügen Sie immer die Adressen Ihrer internen Registries und Dienste zu NO_PROXY hinzu. Andernfalls wird Docker versuchen, auf sie über den Proxy zuzugreifen und Verbindungsfehler zu erhalten. Eine typische Liste: localhost,127.0.0.1,::1,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16
Proxy innerhalb des Containers beim Build (Build-Zeit)
Wenn Docker ein Image erstellt und Befehle wie RUN apt-get install, RUN pip install oder RUN npm install ausführt — diese Befehle werden innerhalb eines temporären Containers ausgeführt. Standardmäßig hat er keinen Zugriff auf den Host-Proxy. Der Proxy muss explizit über Build-Argumente übergeben werden.
Proxy über --build-arg übergeben
docker build \ --build-arg HTTP_PROXY=http://proxy-host:port \ --build-arg HTTPS_PROXY=http://proxy-host:port \ --build-arg NO_PROXY=localhost,127.0.0.1 \ -t my-image .
Konfiguration im Dockerfile
Wenn der Proxy nur während des Build-Vorgangs benötigt wird und Sie nicht möchten, dass er im finalen Image landet — verwenden Sie ARG anstelle von ENV:
FROM ubuntu:22.04 # Deklarieren Sie die Build-Argumente ARG HTTP_PROXY ARG HTTPS_PROXY ARG NO_PROXY # Verwenden Sie sie in den Befehlen RUN apt-get update && apt-get install -y curl wget # Nach diesem Block wird der Proxy nicht mehr in ENV des Containers sein
Wenn der Proxy jedoch auch im laufenden Container benötigt wird — verwenden Sie ENV:
FROM python:3.11 ENV HTTP_PROXY=http://proxy-host:port ENV HTTPS_PROXY=http://proxy-host:port ENV NO_PROXY=localhost,127.0.0.1 RUN pip install requests beautifulsoup4 CMD ["python", "app.py"]
⚠️ Achtung: Sicherheit
Hardcoden Sie den Benutzernamen und das Passwort des Proxys nicht direkt im Dockerfile, wenn das Image öffentlich ist oder in ein Repository gelangt. Verwenden Sie --build-arg und übergeben Sie die Werte aus Umgebungsvariablen des CI/CD-Systems. Der Befehl docker history kann die Werte von ARG anzeigen, daher verwenden Sie für Geheimnisse Docker BuildKit Secrets.
Proxy für laufende Container (Runtime)
Dies ist das häufigste Szenario für Anwendungen, die während der Ausführung HTTP-Anfragen stellen — Scraper, Bots, Microservices, die einen Ausgang über eine bestimmte IP benötigen. Hier ist die Konfiguration maximal einfach: Sie müssen die Umgebungsvariablen beim Start des Containers übergeben.
Über docker run
docker run \ -e HTTP_PROXY=http://username:password@proxy-host:port \ -e HTTPS_PROXY=http://username:password@proxy-host:port \ -e NO_PROXY=localhost,127.0.0.1 \ my-image
Die meisten beliebten HTTP-Bibliotheken erkennen automatisch die Variablen HTTP_PROXY und HTTPS_PROXY: Python requests, curl, wget, Go's net/http, Node.js https-proxy-agent und andere. Es ist nichts zusätzlich im Code zu schreiben.
Über die .env-Datei
Es ist bequemer, die Einstellungen in einer Datei .env zu speichern und sie ganz zu übergeben:
# .env Datei HTTP_PROXY=http://username:password@proxy-host:port HTTPS_PROXY=http://username:password@proxy-host:port NO_PROXY=localhost,127.0.0.1
docker run --env-file .env my-image
SOCKS5-Proxy im Container
Wenn Sie einen SOCKS5-Proxy verwenden (zum Beispiel residential proxies unterstützen meistens genau dieses Protokoll), ist die Syntax etwas anders:
docker run \ -e ALL_PROXY=socks5://username:password@proxy-host:port \ my-image
Bitte beachten Sie: Nicht alle Bibliotheken unterstützen SOCKS5 über Umgebungsvariablen ohne zusätzliche Abhängigkeiten. Python requests erfordert die Installation von requests[socks], curl muss mit Unterstützung für libcurl-socks kompiliert werden.
Proxy in Docker Compose
In realen Projekten wird selten reines docker run verwendet. Meistens arbeitet man mit Docker Compose, wo mehrere Dienste in einer Datei beschrieben sind. Die Proxy-Konfiguration erfolgt hier auf der Ebene jedes Dienstes oder über eine Variablen-Datei.
Option 1: environment in docker-compose.yml
version: '3.8'
services:
scraper:
image: my-scraper:latest
environment:
- HTTP_PROXY=http://username:password@proxy-host:port
- HTTPS_PROXY=http://username:password@proxy-host:port
- NO_PROXY=localhost,127.0.0.1
restart: unless-stopped
api:
image: my-api:latest
# Dieser Dienst ohne Proxy — greift nur auf interne Ressourcen zu
ports:
- "8080:8080"
Option 2: über die .env-Datei (empfohlen)
Erstellen Sie eine .env in dem Verzeichnis mit docker-compose.yml. Docker Compose erkennt diese Datei automatisch:
# .env PROXY_HOST=proxy-host PROXY_PORT=8080 PROXY_USER=username PROXY_PASS=password
version: '3.8'
services:
scraper:
image: my-scraper:latest
environment:
- HTTP_PROXY=http://${PROXY_USER}:${PROXY_PASS}@${PROXY_HOST}:${PROXY_PORT}
- HTTPS_PROXY=http://${PROXY_USER}:${PROXY_PASS}@${PROXY_HOST}:${PROXY_PORT}
- NO_PROXY=localhost,127.0.0.1
Proxy beim Build in Compose
Wenn in Compose ein Abschnitt build vorhanden ist und der Proxy während des Build-Vorgangs übergeben werden muss:
version: '3.8'
services:
app:
build:
context: .
dockerfile: Dockerfile
args:
HTTP_PROXY: http://${PROXY_USER}:${PROXY_PASS}@${PROXY_HOST}:${PROXY_PORT}
HTTPS_PROXY: http://${PROXY_USER}:${PROXY_PASS}@${PROXY_HOST}:${PROXY_PORT}
environment:
- HTTP_PROXY=http://${PROXY_USER}:${PROXY_PASS}@${PROXY_HOST}:${PROXY_PORT}
- HTTPS_PROXY=http://${PROXY_USER}:${PROXY_PASS}@${PROXY_HOST}:${PROXY_PORT}
Welchen Proxy-Typ für Docker wählen
Die Wahl des Proxy-Typs hängt von der Aufgabe ab. Für Docker-Umgebungen sind drei Haupttypen relevant, jeder hat seine eigene Nische:
| Proxy-Typ | Geschwindigkeit | Anonymität | Bestes Szenario für Docker |
|---|---|---|---|
| Rechenzentrum | ⚡ Hoch | Mittel | Pull von Images, CI/CD-Pipelines, Umgehung von Rate Limiting bei Docker Hub |
| Residential | 🔄 Mittel | Hoch | Scraping von Websites mit Schutz, APIs mit Geo-Beschränkungen, Tests |
| Mobile | 🔄 Mittel | Maximal | Anwendungen, die mit mobilen APIs arbeiten (Instagram, TikTok) |
Für Pull von Images und CI/CD sind Rechenzentrums-Proxys optimal — sie bieten maximale Geschwindigkeit beim Herunterladen großer Images (mehrere Gigabyte) und eine stabile Verbindung für lange Builds.
Für Scraper-Container, die den Schutz von Websites umgehen und wie ein normaler Benutzer erscheinen müssen, sind Residential Proxys besser geeignet. Sie haben IPs von echten Haushaltsnutzern, was die Wahrscheinlichkeit einer Blockierung selbst bei intensiven Anfragen verringert.
Für Anwendungen, die mit mobilen Plattformen arbeiten — Instagram Graph API, TikTok API, mobile Versionen von Diensten — sollten mobile Proxys in Betracht gezogen werden. Sie verwenden IPs von Mobilfunkanbietern und erwecken bei Anti-Bot-Systemen die geringsten Verdachtsmomente.
Protokolle: HTTP vs SOCKS5
Der Docker Daemon unterstützt nur HTTP/HTTPS-Proxys — SOCKS5 funktioniert nicht für Pull von Images. Wenn Sie einen SOCKS5-Proxy haben und Images herunterladen müssen, müssen Sie einen lokalen Konverter wie privoxy oder microsocks verwenden, der HTTP annimmt und über SOCKS5 proxiert.
Für Runtime-Container ist die Situation besser: Die meisten HTTP-Bibliotheken unterstützen SOCKS5 direkt über die Variable ALL_PROXY=socks5://....
Häufige Fehler und wie man sie behebt
Lassen Sie uns die häufigsten Probleme durchgehen, die bei der Proxy-Konfiguration in Docker auftreten:
Fehler 1: Proxy ist auf dem Host konfiguriert, aber Docker sieht ihn nicht
Symptom:
Error response from daemon: Get "https://registry-1.docker.io/v2/": dial tcp: connection refused
Ursache: Der Docker Daemon wird als Systemdienst gestartet und erbt nicht die Umgebungsvariablen des aktuellen Benutzers, selbst wenn Sie export HTTPS_PROXY=... im Terminal gesetzt haben.
Lösung: Konfigurieren Sie den Proxy über systemd override (Methode 1 aus dem obigen Abschnitt). Führen Sie unbedingt systemctl daemon-reload && systemctl restart docker aus.
Fehler 2: apt-get / pip / npm funktionieren nicht beim Build
Symptom:
Err:1 http://archive.ubuntu.com/ubuntu focal InRelease
Could not connect to archive.ubuntu.com:80
Ursache: Die Proxy-Konfiguration für den Daemon wird nicht automatisch auf die Befehle innerhalb von RUN im Dockerfile übertragen. Dies sind zwei verschiedene Kontexte.
Lösung: Übergeben Sie den Proxy über --build-arg oder verwenden Sie ~/.docker/config.json mit dem Abschnitt proxies (Docker 23.0+, überträgt automatisch Argumente beim Build).
Fehler 3: Interne Dienste sind über den Proxy nicht erreichbar
Symptom:
curl: (7) Failed to connect to internal-service.local port 8080: Connection refused
Ursache: Der Proxy versucht, Anfragen an interne Adressen zu proxieren, die von außen nicht erreichbar sind.
Lösung: Fügen Sie alle internen Domains und Subnetze zu NO_PROXY hinzu. Für Unternehmensnetzwerke ist eine typische Liste: localhost,127.0.0.1,::1,.internal,.local,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16
Fehler 4: Proxy-Authentifizierung funktioniert nicht — Sonderzeichen im Passwort
Wenn das Passwort Sonderzeichen enthält (@, #, %), wird die URL nicht korrekt geparst.
Lösung: Kodieren Sie das Passwort in URL-Encoding. Zum Beispiel, p@ss#word → p%40ss%23word. In Python können Sie schnell die kodierte Version erhalten:
python3 -c "from urllib.parse import quote; print(quote('p@ss#word', safe=''))"
# Ausgabe: p%40ss%23word
Fehler 5: Proxy funktioniert, aber SSL-Zertifikat wird nicht überprüft
Unternehmensproxys führen häufig eine SSL-Inspektion (MITM) durch und ersetzen Zertifikate. Docker gibt dabei einen Fehler aus:
x509: certificate signed by unknown authority
Lösung: Fügen Sie das Unternehmens-Root-Zertifikat zu den vertrauenswürdigen auf dem Host hinzu und starten Sie Docker neu. Auf Ubuntu/Debian:
sudo cp corporate-ca.crt /usr/local/share/ca-certificates/ sudo update-ca-certificates sudo systemctl restart docker
Fehler 6: Kubernetes / Docker Swarm — Proxy funktioniert nicht auf allen Nodes
In Cluster-Umgebungen muss der Proxy auf jeder Node separat konfiguriert werden. Für Kubernetes müssen zusätzlich Umgebungsvariablen in den Pod-Manifests oder über ConfigMap konfiguriert werden. Dies kann durch Ansible oder andere Konfigurationsmanagement-Tools automatisiert werden.
Fazit
Die Proxy-Konfiguration in Docker ist nicht eine einzige Einstellung, sondern drei unabhängige Ebenen: Daemon für Pull von Images, Build-Zeit für den Build und Runtime für laufende Container. Wenn Sie diese Architektur verstehen, können Sie flexibel steuern, welcher Datenverkehr über den Proxy und welcher direkt geht.
Eine kurze Checkliste für die richtige Konfiguration:
- ✅ Für Pull von Images — richten Sie systemd override mit den Variablen HTTP_PROXY und HTTPS_PROXY ein
- ✅ Für den Build — übergeben Sie den Proxy über
--build-argoder~/.docker/config.json - ✅ Für Runtime — verwenden Sie Umgebungsvariablen über
-eoder--env-file - ✅ Stellen Sie immer NO_PROXY für interne Adressen ein
- ✅ Speichern Sie keine Proxy-Passwörter im Dockerfile — verwenden Sie Build-Args und .env-Dateien
- ✅ Wählen Sie für CI/CD-Pipelines schnelle Rechenzentrums-Proxys
- ✅ Für Scraper-Container — Residential oder mobile Proxys
Wenn Ihre Containeranwendungen Anfragen an externe Dienste stellen, Daten scrapen oder mit APIs arbeiten, die Geo-Beschränkungen haben, empfehlen wir die Verwendung von Residential Proxys — sie bieten ein hohes Maß an Vertrauen seitens der Dienste und minimales Risiko von Blockierungen selbst bei intensiver Nutzung.