Docker 容器中使用宿主机的代理

FreeGuideOnline 最新 2026-07-07

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.1192.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   # 应该直接连接,不走代理