Docker 容器中使用宿主机的代理
bash
docker run --rm --network host
-e HTTP_PROXY=http://127.0.0.1:7890
-e HTTPS_PROXY=http://127.0.0.1:7890
alpine wget https://example.com
**优点**:配置简单,无需转发。
**缺点**:仅支持 Linux;容器会暴露所有宿主机的网络端口,存在安全隐患;不能映射端口(`-p` 会失效)。
## 方法二:使用 `host.docker.internal`(通用推荐)
### 在 Docker Desktop(Mac / Windows)上运行容器
Docker Desktop 自动解析 `host.docker.internal`,直接使用即可。
```bash
docker run --rm \
-e HTTP_PROXY=http://host.docker.internal:7890 \
-e HTTPS_PROXY=http://host.docker.internal:7890 \
alpine wget https://example.com
在 Linux 宿主机上运行容器
需要显式添加 --add-host 参数将名称映射到宿主机网关。
docker run --rm \
--add-host host.docker.internal:host-gateway \
-e HTTP_PROXY=http://host.docker.internal:7890 \
-e HTTPS_PROXY=http://host.docker.internal:7890 \
alpine wget https://example.com
这里的 host-gateway 是一个特殊值,Docker 会将其替换为宿主机的地址(通常是 172.17.0.1 或 192.168.65.2 等,取决于设置),从而屏蔽底层差异。
方法三:手动传递宿主机 IP
如果你知道宿主机的固定 IP(例如局域网 IP 或 docker0 的网关),也可以直接使用。这种方式的缺点是需要根据环境调整,可移植性差。
获取宿主机 IP 的典型方式:
- 在宿主机执行
ip addr show docker0查看inet地址(如172.17.0.1)。 - 或使用
hostname -I获取宿主机的实际网卡 IP(多网卡时需确认)。 - 对于 WSL2 + Docker Desktop,宿主机 IP 往往是 Windows 主机的 IP,可以通过
cat /etc/resolv.conf | grep nameserver查看(通常为192.168.x.1)。
# 假设宿主机在 docker0 上的 IP 是 172.17.0.1
docker run --rm \
-e HTTP_PROXY=http://172.17.0.1:7890 \
-e HTTPS_PROXY=http://172.17.0.1:7890 \
alpine wget https://example.com
在容器中配置代理环境变量
无论使用哪种方式找到宿主机地址,接下来都是让容器内的应用识别代理。最常见的方法是设置环境变量。
常用环境变量
HTTP_PROXY/http_proxy:HTTP 流量所使用的代理。HTTPS_PROXY/https_proxy:HTTPS 流量所使用的代理(注意:HTTPS 代理仍然是 HTTP 协议的 CONNECT 方法,地址也应以http://开头)。NO_PROXY/no_proxy:排除不走代理的地址,多个用逗号分隔(如localhost,127.0.0.1,.local)。- 对于 SOCKS5 代理,应用需要单独支持(例如
ALL_PROXY=socks5://...或工具本身的配置)。
注意:许多 Linux 工具(如 curl、wget、apt、yum)都会自动识别这些环境变量,但某些程序可能需要大小写兼容或额外的配置,建议同时设置大写和小写版本。
export HTTP_PROXY=http://host.docker.internal:7890
export http_proxy=http://host.docker.internal:7890
export HTTPS_PROXY=http://host.docker.internal:7890
export https_proxy=http://host.docker.internal:7890
export NO_PROXY=localhost,127.0.0.1,.example.com
export no_proxy=$NO_PROXY
持久化配置:Dockerfile 和 Docker Compose
将代理配置写入容器的构建或运行配置,可以实现复用和自动化。
在 Dockerfile 中使用 ARG/ENV
构建镜像时可能需要下载依赖,此时也需要走代理。可以用构建参数传递。
FROM ubuntu:22.04
# 声明构建参数,可被 --build-arg 覆盖
ARG HTTP_PROXY
ARG HTTPS_PROXY
ARG NO_PROXY
ENV HTTP_PROXY=${HTTP_PROXY}
ENV HTTPS_PROXY=${HTTPS_PROXY}
ENV NO_PROXY=${NO_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 .
在 Docker Compose 中配置代理
对于多容器应用,可以使用 docker-compose.yml 统一管理。
version: '3.8'
services:
my-service:
image: my-image
environment:
- HTTP_PROXY=http://host.docker.internal:7890
- HTTPS_PROXY=http://host.docker.internal:7890
- NO_PROXY=localhost,127.0.0.1,.local
extra_hosts:
- "host.docker.internal:host-gateway" # Linux 下需要此配置
# network_mode: host # 也可用 host 模式,但会忽略 ports
如果是用 network_mode: host,不需要 host.docker.internal,直接用 127.0.0.1 作为代理地址即可。
验证代理连接
配置完成后,可以在容器内运行以下命令测试代理是否生效。
使用 curl 测试
# 显示请求头,查看是否通过代理
curl -I https://www.google.com
# 直接查看当前使用的代理(curl 7.55+)
curl -v https://www.google.com 2>&1 | grep -i "Proxy\|Connected"
如果连接成功,应能看到类似 * Connected to host.docker.internal (192.168.65.2) port 7890 的信息。
测试 HTTPS 代理
注意 HTTPS 代理仍然使用 HTTP CONNECT 隧道。如果你的代理只支持 HTTP 而不处理 CONNECT,HTTPS 请求会失败。确认代理服务器具备 HTTPS 代理功能。
测试排除规则
curl http://localhost:8080 # 应该直接连接,不走代理