Vous travaillez avec Docker dans un réseau d'entreprise, sur un serveur avec un accès limité ou vous souhaitez que vos conteneurs accèdent à Internet via une IP spécifique ? Sans une configuration correcte du proxy, Docker ne pourra tout simplement pas télécharger des images depuis Docker Hub ou tout autre registre. Dans cet article, nous examinerons tous les niveaux de proxy — du démon à un conteneur séparé.
Pourquoi Docker a-t-il besoin d'un proxy
Docker est un outil qui accède constamment à des ressources externes. À chaque docker pull ou docker build, le démon se connecte à Docker Hub, GitHub Container Registry, Google Container Registry ou à votre registre privé. Et c'est là que les problèmes commencent.
Situations où un proxy est indispensable :
- Réseau d'entreprise avec pare-feu — tout le trafic doit passer par le serveur proxy de l'entreprise, sinon la connexion est bloquée.
- Restrictions géographiques — Docker Hub ou certains registres ne sont pas accessibles depuis votre pays ou votre centre de données.
- Serveur limité sans accès direct à Internet — VPS dans un réseau fermé, où Internet est accessible uniquement via une passerelle.
- Contrôle du trafic sortant des conteneurs — vous souhaitez que les applications à l'intérieur des conteneurs accèdent au réseau via une IP spécifique, par exemple pour le scraping, les requêtes API ou les tests de contenu géo-dépendant.
- Anonymisation des requêtes — masquer l'IP réelle du serveur lors de l'accès à des services externes depuis le conteneur.
- Limitation de débit — Docker Hub limite le nombre de requêtes pull pour les utilisateurs anonymes (100 pulls en 6 heures). Un proxy avec rotation d'IP peut contourner cette limitation.
Il est important de comprendre que Docker n'est pas une seule application, mais un système composé de plusieurs composants. Le démon (dockerd) vit sur l'hôte et effectue des pulls d'images. Les conteneurs sont des processus isolés avec leurs propres paramètres réseau. Par conséquent, la configuration du proxy pour le démon et pour les conteneurs est une tâche distincte qui doit être abordée différemment.
Trois niveaux de proxy dans Docker
Avant de plonger dans les configurations, il est nécessaire de comprendre l'architecture. Dans Docker, il y a trois niveaux indépendants, chacun nécessitant une configuration de proxy distincte :
| Niveau | Ce qu'il fait | Où le configurer |
|---|---|---|
| Démon Docker | Télécharge des images (docker pull), accède aux registres | override systemd ou daemon.json |
| Docker build | Exécute des commandes lors de la construction de l'image (RUN apt-get, pip install, etc.) | ARG et ENV dans le Dockerfile ou --build-arg |
| Conteneur en cours d'exécution | Application en cours d'exécution qui effectue des requêtes HTTP | ENV lors de docker run ou dans docker-compose.yml |
Une erreur typique consiste à configurer un proxy uniquement à un niveau et à se demander pourquoi les images ne se téléchargent toujours pas ou pourquoi l'application ne voit pas le proxy. Examinons chaque niveau en détail.
Configuration du proxy pour le démon Docker (pull d'images)
C'est la configuration la plus importante si vous souhaitez tirer des images via un proxy. Le démon Docker est un service système qui s'exécute via systemd. Les variables d'environnement de votre utilisateur ou même de root ne sont pas visibles. Vous devez transmettre le proxy précisément dans l'environnement du service.
Méthode 1 : via override systemd (recommandé)
Créez un répertoire pour remplacer les paramètres du service :
sudo mkdir -p /etc/systemd/system/docker.service.d
Créez un fichier /etc/systemd/system/docker.service.d/http-proxy.conf avec le contenu suivant :
[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"
Si le proxy n'a pas d'authentification, il suffit de retirer username:password@. Après avoir créé le fichier, rechargez la configuration de systemd et redémarrez Docker :
sudo systemctl daemon-reload sudo systemctl restart docker
Vérifiez que les paramètres ont été appliqués :
sudo systemctl show --property=Environment docker
Dans la sortie, vos variables HTTP_PROXY et HTTPS_PROXY devraient apparaître.
Méthode 2 : via ~/.docker/config.json (Docker Desktop et nouvelles versions)
À partir de Docker Engine 23.0, une méthode plus pratique est apparue — la configuration du proxy via le fichier de configuration du client. Créez ou éditez le fichier ~/.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"
}
}
}
Cette méthode est pratique car elle ne nécessite pas de droits root ni de redémarrage du démon. Les paramètres sont automatiquement transmis aux conteneurs lors de la construction en tant qu'arguments de build. Cependant, pour gérer les requêtes pull du démon lui-même, une méthode via systemd est toujours nécessaire.
💡 Important concernant NO_PROXY
Ajoutez toujours dans NO_PROXY les adresses de vos registres et services internes. Sinon, Docker essaiera d'y accéder via le proxy et obtiendra des erreurs de connexion. Liste typique : localhost,127.0.0.1,::1,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16
Proxy à l'intérieur du conteneur lors de la construction (build-time)
Lorsque Docker construit une image et exécute des commandes telles que RUN apt-get install, RUN pip install ou RUN npm install — ces commandes s'exécutent à l'intérieur d'un conteneur temporaire. Par défaut, il n'a pas accès au proxy de l'hôte. Vous devez explicitement transmettre le proxy via des arguments de build.
Transmission du proxy via --build-arg
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 .
Configuration dans le Dockerfile
Si le proxy est nécessaire uniquement lors de la construction et que vous ne souhaitez pas qu'il soit inclus dans l'image finale — utilisez ARG au lieu de ENV :
FROM ubuntu:22.04 # Déclaration des arguments de construction ARG HTTP_PROXY ARG HTTPS_PROXY ARG NO_PROXY # Utilisation dans les commandes RUN apt-get update && apt-get install -y curl wget # Après ce bloc, le proxy ne sera plus dans ENV du conteneur
Si le proxy est également nécessaire dans le conteneur en cours d'exécution — utilisez 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"]
⚠️ Attention : sécurité
Ne hardcodez pas le nom d'utilisateur et le mot de passe du proxy directement dans le Dockerfile, si l'image sera publique ou sera placée dans un dépôt. Utilisez --build-arg et passez les valeurs à partir des variables d'environnement du système CI/CD. La commande docker history peut afficher les valeurs ARG, donc pour les secrets, utilisez les secrets de Docker BuildKit.
Proxy pour un conteneur en cours d'exécution (runtime)
C'est le scénario le plus courant pour les applications qui effectuent des requêtes HTTP pendant leur exécution — parseurs, bots, microservices qui ont besoin d'accéder via une IP spécifique. Ici, la configuration est très simple : il suffit de transmettre les variables d'environnement lors du démarrage du conteneur.
Via 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
La plupart des bibliothèques HTTP populaires récupèrent automatiquement les variables HTTP_PROXY et HTTPS_PROXY : Python requests, curl, wget, Go's net/http, Node.js https-proxy-agent et d'autres. Rien d'autre à écrire dans le code.
Via le fichier .env
Il est plus pratique de stocker les paramètres dans un fichier .env et de le transmettre dans son intégralité :
# fichier .env 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
Proxy SOCKS5 dans le conteneur
Si vous utilisez un proxy SOCKS5 (par exemple, les proxies résidentiels supportent souvent ce protocole), la syntaxe est légèrement différente :
docker run \ -e ALL_PROXY=socks5://username:password@proxy-host:port \ my-image
Notez que toutes les bibliothèques ne prennent pas en charge SOCKS5 via une variable d'environnement sans dépendances supplémentaires. Python requests nécessite l'installation de requests[socks], curl doit être compilé avec le support de libcurl-socks.
Proxy dans Docker Compose
Dans les projets réels, on utilise rarement le simple docker run. On travaille le plus souvent avec Docker Compose, où plusieurs services sont décrits dans un seul fichier. La configuration du proxy se fait ici au niveau de chaque service ou via un fichier de variables.
Option 1 : environment dans 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
# Ce service sans proxy — accède uniquement aux ressources internes
ports:
- "8080:8080"
Option 2 : via le fichier .env (recommandé)
Créez un fichier .env dans le répertoire contenant docker-compose.yml. Docker Compose récupère automatiquement ce fichier :
# .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 lors de la construction dans Compose
Si dans Compose il y a une section build et que vous devez transmettre le proxy lors de la construction :
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}
Quel type de proxy choisir pour Docker
Le choix du type de proxy dépend de la tâche. Pour les environnements Docker, trois types principaux sont pertinents, chacun ayant sa propre niche :
| Type de proxy | Vitesse | Anonymat | Meilleur scénario pour Docker |
|---|---|---|---|
| Centre de données | ⚡ Élevée | Moyenne | Pull d'images, pipelines CI/CD, contournement de la limitation de débit de Docker Hub |
| Résidentiels | 🔄 Moyenne | Élevée | Scraping de sites protégés, API avec restrictions géographiques, tests |
| Mobiles | 🔄 Moyenne | Maximale | Applications travaillant avec des API mobiles (Instagram, TikTok) |
Pour les pulls d'images et CI/CD, les proxies de centre de données sont optimaux — ils offrent la vitesse maximale lors du téléchargement de grandes images (plusieurs gigaoctets) et une connexion stable pour les longues constructions.
Pour les conteneurs scrapeurs, qui doivent contourner la protection des sites et avoir l'air d'un utilisateur normal, les proxies résidentiels sont les mieux adaptés. Ils ont des IP d'utilisateurs domestiques réels, ce qui réduit la probabilité de blocage même avec des requêtes intensives.
Pour les applications travaillant avec des plateformes mobiles — Instagram Graph API, TikTok API, versions mobiles des services — envisagez d'utiliser des proxies mobiles. Ils utilisent des IP d'opérateurs de téléphonie mobile et suscitent le minimum de soupçons auprès des systèmes anti-bots.
Protocoles : HTTP vs SOCKS5
Le démon Docker ne prend en charge que les proxies HTTP/HTTPS — SOCKS5 ne fonctionne pas pour les pulls d'images. Si vous avez un proxy SOCKS5 et que vous devez télécharger des images, vous devrez utiliser un convertisseur local comme privoxy ou microsocks, qui acceptera HTTP et le proxy via SOCKS5.
Pour les conteneurs en cours d'exécution, la situation est meilleure : la plupart des bibliothèques HTTP prennent en charge SOCKS5 directement via la variable ALL_PROXY=socks5://....
Erreurs fréquentes et comment les corriger
Examinons les problèmes les plus courants rencontrés lors de la configuration du proxy dans Docker :
Erreur 1 : Le proxy est configuré sur l'hôte, mais Docker ne le voit pas
Symptôme :
Error response from daemon: Get "https://registry-1.docker.io/v2/": dial tcp: connection refused
Cause : Le démon Docker s'exécute en tant que service système et n'hérite pas des variables d'environnement de l'utilisateur actuel, même si vous avez défini export HTTPS_PROXY=... dans le terminal.
Solution : Configurez le proxy via l'override systemd (méthode 1 de la section ci-dessus). Assurez-vous d'exécuter systemctl daemon-reload && systemctl restart docker.
Erreur 2 : apt-get / pip / npm ne fonctionnent pas lors de la construction
Symptôme :
Err:1 http://archive.ubuntu.com/ubuntu focal InRelease
Could not connect to archive.ubuntu.com:80
Cause : La configuration du proxy pour le démon ne s'applique pas automatiquement aux commandes à l'intérieur de RUN dans le Dockerfile. Ce sont deux contextes différents.
Solution : Transmettez le proxy via --build-arg ou utilisez ~/.docker/config.json avec la section proxies (Docker 23.0+, transmet automatiquement les arguments lors de la construction).
Erreur 3 : Les services internes ne sont pas accessibles via le proxy
Symptôme :
curl: (7) Failed to connect to internal-service.local port 8080: Connection refused
Cause : Le proxy essaie de proxyfier les requêtes vers des adresses internes qui ne sont pas accessibles de l'extérieur.
Solution : Ajoutez tous les domaines et sous-réseaux internes dans NO_PROXY. Pour les réseaux d'entreprise, une liste typique : localhost,127.0.0.1,::1,.internal,.local,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16
Erreur 4 : L'authentification du proxy ne fonctionne pas — caractères spéciaux dans le mot de passe
Si le mot de passe contient des caractères spéciaux (@, #, %), l'URL est mal analysée.
Solution : Encodez le mot de passe en URL-encoding. Par exemple, p@ss#word → p%40ss%23word. En Python, vous pouvez rapidement obtenir la version encodée :
python3 -c "from urllib.parse import quote; print(quote('p@ss#word', safe=''))"
# Sortie : p%40ss%23word
Erreur 5 : Le proxy fonctionne, mais le certificat SSL n'est pas vérifié
Les proxies d'entreprise effectuent souvent une inspection SSL (MITM) et remplacent les certificats. Docker génère alors une erreur :
x509: certificate signed by unknown authority
Solution : Ajoutez le certificat racine d'entreprise aux certificats de confiance sur l'hôte et redémarrez Docker. Sur Ubuntu/Debian :
sudo cp corporate-ca.crt /usr/local/share/ca-certificates/ sudo update-ca-certificates sudo systemctl restart docker
Erreur 6 : Kubernetes / Docker Swarm — le proxy ne fonctionne pas sur tous les nœuds
Dans les environnements de cluster, il est nécessaire de configurer le proxy sur chaque nœud séparément. Pour Kubernetes, il est également nécessaire de configurer les variables d'environnement dans les manifestes des pods ou via ConfigMap. Cela peut être automatisé via Ansible ou d'autres outils de gestion de configuration.
Conclusion
La configuration du proxy dans Docker n'est pas une seule configuration, mais trois niveaux indépendants : le démon pour les pulls d'images, le build-time pour la construction et le runtime pour les conteneurs en cours d'exécution. En comprenant cette architecture, vous pourrez gérer de manière flexible quel trafic passe par le proxy et quel trafic passe directement.
Liste de contrôle rapide pour une configuration correcte :
- ✅ Pour les pulls d'images — configurez l'override systemd avec les variables HTTP_PROXY et HTTPS_PROXY
- ✅ Pour la construction — transmettez le proxy via
--build-argou~/.docker/config.json - ✅ Pour le runtime — utilisez des variables d'environnement via
-eou--env-file - ✅ Configurez toujours NO_PROXY pour les adresses internes
- ✅ Ne stockez pas les mots de passe du proxy dans le Dockerfile — utilisez des build-args et des fichiers .env
- ✅ Pour les pipelines CI/CD, choisissez des proxies de centre de données rapides
- ✅ Pour les conteneurs scrapeurs — proxies résidentiels ou mobiles
Si vos applications conteneurisées effectuent des requêtes vers des services externes, analysent des données ou travaillent avec des API ayant des restrictions géographiques, nous vous recommandons d'utiliser des proxies résidentiels — ils offrent un niveau de confiance élevé de la part des services et un risque minimal de blocage même lors d'un travail intensif.