這是一篇關於 Docker 容器配置外部代理的實戰教程。
在內網開發、跨國業務或需要訪問受限資源(如 pip/npm/maven 源、GitHub)時,配置容器走代理是後端開發的必修課。很多開發者容易混淆 “Docker Pull 走代理” 和 “容器內部程序走代理”,這兩者是完全隔離的配置體系。
本文將分層級為您解析,從守護進程到容器運行時,徹底打通網絡任督二脈。
Docker 容器網絡代理全攻略:從宿主機到外部服務器
📚 前置摘要 (TL;DR)
- 分清對象: 給
docker pull加速需配置 Daemon(守護進程);給容器內的curl/apt加速需配置環境變量。 - 關鍵地址: 如果代理在宿主機上,容器內不能填
127.0.0.1,請使用host.docker.internal(Mac/Win) 或172.17.0.1(Linux)。 - 關鍵設置: 務必確保你的daili軟件(Clash/V2rxx/Squid)開啓了 “允許局域網連接 (Allow LAN)”,否則容器連不上。
1\. 網絡拓撲與準備工作
在配置之前,必須明確代理服務器在哪裏:
- 場景 A - 代理在局域網另一台機器: IP 為
192.168.1.100,端口7890。
- 直接使用該 IP 即可。
- 場景 B - 代理在宿主機(本機):
- 容器內的
localhost指向的是容器自己,不是宿主機。 - Docker Desktop (Mac/Win): 使用 DNS 別名
host.docker.internal。 - Linux: 使用默認網關 IP
172.17.0.1(需驗證網絡模式)。
2\. 第一層:配置 Docker Daemon (解決 docker pull 慢)
這層配置隻影響 拉取鏡像 的速度,不會 影響容器內部運行的程序。
Linux (Systemd)
創建或修改 systemd 配置目錄:
sudo mkdir -p /etc/systemd/system/docker.service.d
sudo vim /etc/systemd/system/docker.service.d/http-proxy.conf
寫入如下內容(替換為你的代理地址):
[Service]
Environment="HTTP_PROXY=http://192.168.1.100:7890"
Environment="HTTPS_PROXY=http://192.168.1.100:7890"
# NO_PROXY 列表中的地址不走代理,通常要把私有倉庫放進去
Environment="NO_PROXY=localhost,127.0.0.1,docker-registry.somecorporation.com"
應用並重啓:
sudo systemctl daemon-reload
sudo systemctl restart docker
macOS / Windows (Docker Desktop)
- 點擊 Docker 圖標 -\> Settings -\> Resources -\> Proxies。
- 開啓 Manual proxy configuration,填入
http://host.docker.internal:7890。 - 點擊 Apply & Restart。
3\. 第二層:全局容器配置 (所有容器自動生效)
如果你希望本機啓動的所有容器默認都自動注入代理配置,可以修改用户級配置。
編輯 ~/.docker/config.json:
{
"proxies": {
"default": {
"httpProxy": "http://192.168.1.100:7890",
"httpsProxy": "http://192.168.1.100:7890",
"noProxy": "localhost,127.0.0.1,*.internal.domain"
}
}
}
效果: 之後執行 docker run 啓動的任何容器,都會自動帶有 HTTP_PROXY 等環境變量,無需手動指定。
4\. 第三層:單容器臨時配置 (最靈活,推薦)
在生產環境或調試時,我們通常只想讓特定的容器走代理。可以通過環境變量 -e 傳入。
命令行啓動 (Docker Run)
假設代理在宿主機 (macOS) 上:
docker run -it --rm \
-e http_proxy=http://host.docker.internal:7890 \
-e https_proxy=http://host.docker.internal:7890 \
-e all_proxy=socks5://host.docker.internal:7890 \
curlimages/curl \
curl -I https://www.google.com
注意: 環境變量建議同時設置全小寫 (
http_proxy) 和全大寫 (HTTP_PROXY),因為不同的軟件(如aptvspipvsgo)對大小寫敏感度不同。
Docker Compose (推薦)
在 docker-compose.yml 中配置:
version: '3.8'
services:
app:
image: python:3.9
environment:
- HTTP_PROXY=http://host.docker.internal:7890
- HTTPS_PROXY=http://host.docker.internal:7890
command: pip install -r requirements.txt
5\. 第四層:構建時代理 (Docker Build)
這是最容易踩坑的地方。docker build 過程是隔離的,它不會繼承宿主機的網絡配置,也不會讀取 ~/.docker/config.json。
如果你的 Dockerfile 裏有 RUN apt-get update 或 RUN pip install,必須通過 build-arg 傳入代理。
Dockerfile:
FROM ubuntu:22.04
# 定義參數,但不賦予默認值,避免硬編碼 IP 導致由於環境不同而構建失敗
ARG HTTP_PROXY
ARG HTTPS_PROXY
# 將參數轉為環境變量,以便後續 RUN 指令能讀到
ENV http_proxy=$HTTP_PROXY
ENV https_proxy=$HTTPS_PROXY
RUN apt-get update && apt-get install -y curl
構建命令:
docker build \
--build-arg HTTP_PROXY=http://host.docker.internal:7890 \
--build-arg HTTPS_PROXY=http://host.docker.internal:7890 \
-t my-image .
6\. 驗證與排查
進入容器內部進行測試是驗證配置是否生效的唯一標準。
- 檢查環境變量:
docker exec -it <container_id> env | grep -i proxy
- 測試連通性:
# 測試能否通過代理訪問外網
docker exec -it <container_id> curl -v https://www.google.com
- 常見報錯:
Connection refused: 代理軟件沒開,或者沒開“允許局域網連接”,或者 IP 填錯了。Could not resolve host: DNS 問題,嘗試配置 Docker 的 DNS 為8.8.8.8。
結語
Docker 的代理配置本質上就是環境變量注入。
- Daemon 配置是為了讓 Docker 引擎下載鏡像快。
- Build-arg 是為了讓
apt/pip/npm在構建時能聯網。 - Run -e 是為了讓容器內的業務邏輯能訪問外部 API。
明確你的需求屬於哪個階段,就能精準配置。
下一步建議: 如果您正在使用 Docker Compose 編排微服務,並希望實現多個容器共享同一個網絡代理配置(而不是在每個 service 下面重複寫 environment),我可以為您展示如何利用 .env 文件或 YAML 錨點 來優雅地管理這些配置。需要看看嗎?