Skip to content

网络代理配置:让 Docker 容器正常访问 AI API

在中国大陆部署 OpenClaw 时,容器需要访问 api.anthropic.comapi.openai.com 等海外 AI API 端点。由于网络环境限制,这些端点在大陆网络中通常不可达或不稳定。本指南提供四种解决方案,帮助你在 Docker 容器内顺利访问 AI API。

前置阅读:本指南假设你已完成基本的 Docker Compose 部署。如尚未部署,请先参阅 Docker Compose + 飞书部署指南


方案概览

方案适用场景复杂度说明
A. Docker 守护进程代理宿主机上所有容器都需要代理系统级设置,影响所有容器
B. Compose 环境变量代理仅 OpenClaw 容器需要代理按容器配置,最常用
C. 反向代理 / API 网关需要集中管理 API 访问自建中转服务
D. 兼容镜像端点有可信的第三方镜像服务最低修改 Base URL 即可

如何选择:

  • 如果宿主机已有代理软件(如 Clash、V2Ray),优先选 方案 B(最简单、最常见)
  • 如果团队共享部署,需要统一管理 API 出口,选 方案 C
  • 如果有可信的国内 API 镜像服务或兼容端点(如 MiniMax),选 方案 D
  • 如果希望宿主机上所有 Docker 容器都走代理(包括镜像拉取),选 方案 A

方案 A:Docker 守护进程代理(系统级)

此方案为 Docker 守护进程(daemon)配置代理,影响镜像拉取和构建过程。

注意:守护进程代理主要影响 docker pulldocker build 等操作。容器运行时的网络请求不一定会继承守护进程代理设置,需结合方案 B 使用。

方法一:systemd override(推荐用于 Linux 服务器)

创建 systemd 配置覆盖文件:

bash
sudo mkdir -p /etc/systemd/system/docker.service.d

创建 /etc/systemd/system/docker.service.d/http-proxy.conf

ini
[Service]
Environment="HTTP_PROXY=http://127.0.0.1:7890"
Environment="HTTPS_PROXY=http://127.0.0.1:7890"
Environment="NO_PROXY=localhost,127.0.0.1,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16"

重新加载配置并重启 Docker:

bash
sudo systemctl daemon-reload
sudo systemctl restart docker

验证配置是否生效:

bash
sudo systemctl show --property=Environment docker

方法二:daemon.json(Docker 23.0+)

编辑 /etc/docker/daemon.json

json
{
  "proxies": {
    "http-proxy": "http://127.0.0.1:7890",
    "https-proxy": "http://127.0.0.1:7890",
    "no-proxy": "localhost,127.0.0.1,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16"
  }
}

重启 Docker:

bash
sudo systemctl restart docker

Docker Desktop 用户:在 Docker Desktop 的 Settings > Resources > Proxies 中可以直接配置代理,无需手动编辑文件。


方案 B:Docker Compose 环境变量代理(按容器)

这是最常用的方案。在宿主机已有代理软件(如 Clash、V2Ray、Shadowsocks 等)的情况下,只需将代理地址通过环境变量传给容器即可。

理解容器如何访问宿主机代理

容器访问宿主机上的代理服务时,代理地址取决于网络模式:

网络模式代理地址说明
network_mode: hosthttp://127.0.0.1:7890容器共享宿主机网络栈,直接用 localhost
桥接网络(默认) — macOS/Windowshttp://host.docker.internal:7890Docker Desktop 提供的特殊 DNS
桥接网络(默认) — Linuxhttp://172.17.0.1:7890Docker 默认网桥网关 IP

飞书部署默认使用 network_mode: host。如果你按照 Docker Compose + 飞书部署指南 部署,容器直接共享宿主机网络,代理地址使用 127.0.0.1 即可。

配置 .env 文件

.env 文件中添加代理变量:

bash
# .env

# === 现有配置 ===
OPENCLAW_GATEWAY_TOKEN=your-secure-gateway-token
FEISHU_APP_ID=cli_xxx
FEISHU_APP_SECRET=your-secret
ANTHROPIC_AUTH_TOKEN=your_api_token_here
ANTHROPIC_BASE_URL=https://api.anthropic.com

# === 代理配置(新增)===
# 根据你的代理软件实际端口修改(Clash 默认 7890,V2Ray 默认 10809)
HTTP_PROXY=http://127.0.0.1:7890
HTTPS_PROXY=http://127.0.0.1:7890
NO_PROXY=localhost,127.0.0.1,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16

配置 docker-compose.yml

docker-compose.yml 中传递代理环境变量:

yaml
services:
  openclaw:
    image: ghcr.io/openclaw/openclaw:latest
    container_name: openclaw_feishu
    restart: unless-stopped
    network_mode: host
    env_file:
      - .env
    environment:
      # 显式传递代理变量(确保容器内进程能读取)
      - HTTP_PROXY=${HTTP_PROXY}
      - HTTPS_PROXY=${HTTPS_PROXY}
      - NO_PROXY=${NO_PROXY}
      # Node.js 也会识别小写形式
      - http_proxy=${HTTP_PROXY}
      - https_proxy=${HTTPS_PROXY}
      - no_proxy=${NO_PROXY}
    volumes:
      - ./openclaw-data:/home/node/.openclaw

为什么同时设置大写和小写? 不同的 HTTP 客户端库对大小写的识别不一致。Node.js 的 undici(内置 fetch)识别大写 HTTPS_PROXY,而一些第三方库(如 node-fetch)优先识别小写 https_proxy。同时设置可以确保兼容性。

桥接网络模式下的配置

如果你不使用 network_mode: host(例如使用标准桥接网络),需要调整代理地址:

macOS / Windows(Docker Desktop):

bash
# .env
HTTP_PROXY=http://host.docker.internal:7890
HTTPS_PROXY=http://host.docker.internal:7890

Linux(桥接网络):

bash
# .env
HTTP_PROXY=http://172.17.0.1:7890
HTTPS_PROXY=http://172.17.0.1:7890

Linux 上查看网桥网关 IPdocker network inspect bridge | grep Gateway


方案 C:反向代理 / API 网关(自建中转)

当无法使用正向代理,或需要为多个服务集中管理 AI API 访问时,可以自建反向代理。

原理

在 Docker Compose 中额外运行一个 Nginx(或 Caddy)服务,将请求转发到 api.anthropic.com。OpenClaw 将 API 请求发往本地反向代理,由反向代理转发到上游。

OpenClaw 容器 → Nginx 反向代理容器 → (宿主机网络/代理) → api.anthropic.com

Nginx 配置

创建 nginx-proxy/nginx.conf

nginx
server {
    listen 8080;
    server_name _;

    # Anthropic API 反向代理
    location /anthropic/ {
        proxy_pass https://api.anthropic.com/;
        proxy_ssl_server_name on;
        proxy_set_header Host api.anthropic.com;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        # 传递所有原始请求头(包括 x-api-key 等认证头)
        proxy_pass_request_headers on;

        # 超时设置(AI API 响应可能较慢)
        proxy_connect_timeout 60s;
        proxy_send_timeout 120s;
        proxy_read_timeout 300s;

        # 支持流式响应(SSE)
        proxy_buffering off;
        proxy_cache off;
    }

    # OpenAI API 反向代理(可选)
    location /openai/ {
        proxy_pass https://api.openai.com/;
        proxy_ssl_server_name on;
        proxy_set_header Host api.openai.com;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass_request_headers on;
        proxy_buffering off;
        proxy_cache off;
        proxy_connect_timeout 60s;
        proxy_send_timeout 120s;
        proxy_read_timeout 300s;
    }

    # 健康检查
    location /health {
        return 200 'ok';
        add_header Content-Type text/plain;
    }
}

Docker Compose 配置

创建包含反向代理服务的 docker-compose.yml

yaml
services:
  openclaw:
    image: ghcr.io/openclaw/openclaw:latest
    container_name: openclaw_feishu
    restart: unless-stopped
    network_mode: host
    env_file:
      - .env
    volumes:
      - ./openclaw-data:/home/node/.openclaw
    depends_on:
      - api-proxy

  api-proxy:
    image: nginx:alpine
    container_name: api_proxy
    restart: unless-stopped
    network_mode: host
    volumes:
      - ./nginx-proxy/nginx.conf:/etc/nginx/conf.d/default.conf:ro

注意:上面两个服务都使用 network_mode: host,所以它们可以通过 127.0.0.1 互相访问。如果使用桥接网络,需要配置 Docker 网络并使用服务名访问。

配置 OpenClaw 使用反向代理

修改 .env,将 ANTHROPIC_BASE_URL 指向本地反向代理:

bash
# .env
ANTHROPIC_BASE_URL=http://127.0.0.1:8080/anthropic

openclaw.json 中的 ${ANTHROPIC_BASE_URL} 会在运行时自动解析为上面的值:

json5
{
  "models": {
    "providers": {
      "custom-claude": {
        "baseUrl": "${ANTHROPIC_BASE_URL}",  // 解析为 http://127.0.0.1:8080/anthropic
        "apiKey": "${ANTHROPIC_AUTH_TOKEN}",
        "api": "anthropic-messages",
        // ...
      }
    }
  }
}

Caddy 替代方案(更简洁)

如果偏好 Caddy,配置更简洁。创建 Caddyfile

:8080 {
    handle_path /anthropic/* {
        reverse_proxy https://api.anthropic.com {
            header_up Host api.anthropic.com
            transport http {
                tls_server_name api.anthropic.com
            }
        }
    }

    handle_path /openai/* {
        reverse_proxy https://api.openai.com {
            header_up Host api.openai.com
            transport http {
                tls_server_name api.openai.com
            }
        }
    }
}

对应的 docker-compose.yml 服务:

yaml
  api-proxy:
    image: caddy:alpine
    container_name: api_proxy
    restart: unless-stopped
    network_mode: host
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile:ro

反向代理的优势:如果你的服务器本身能访问海外(如部署在香港、新加坡的云服务器),反向代理是最干净的方案,无需任何代理软件。


方案 D:兼容镜像 / 第三方端点

最简单的方案 -- 如果有提供 Anthropic Messages API 兼容接口的第三方服务,只需修改 ANTHROPIC_BASE_URL 即可。

配置方法

修改 .env 文件:

bash
# .env
ANTHROPIC_BASE_URL=https://your-mirror-endpoint.example.com
ANTHROPIC_AUTH_TOKEN=your_api_token_here

OpenClaw 的 openclaw.json 通过 ${ANTHROPIC_BASE_URL} 引用此变量,无需修改配置文件:

json5
{
  "models": {
    "providers": {
      "custom-claude": {
        "baseUrl": "${ANTHROPIC_BASE_URL}",  // 运行时解析为镜像端点
        "apiKey": "${ANTHROPIC_AUTH_TOKEN}",
        "api": "anthropic-messages",
        "models": [
          {
            "id": "claude-sonnet-4-5-20250929",
            "name": "Claude Sonnet 4.5",
            "contextWindow": 200000,
            "maxTokens": 4096
          }
        ]
      }
    }
  }
}

国内兼容端点示例

部分国内服务商提供 Anthropic Messages API 兼容端点:

提供商Base URL说明
MiniMaxhttps://api.minimax.io/anthropic支持 Anthropic Messages API 格式

模型 ID 差异:不同端点支持的模型 ID 可能不同。例如 MiniMax 的兼容端点可能使用自己的模型 ID(如 MiniMax-M2.1)。请根据端点文档调整 openclaw.json 中的模型配置。

配置 MiniMax 作为后备提供商的示例:

json5
{
  "models": {
    "providers": {
      "minimax": {
        "baseUrl": "https://api.minimax.io/anthropic",
        "api": "anthropic-messages",
        "apiKey": "${MINIMAX_API_KEY}"
      }
    }
  },
  "agents": {
    "defaults": {
      "model": {
        "primary": "custom-claude/claude-sonnet-4-5-20250929",
        "fallbacks": ["minimax/MiniMax-M2.1"]
      }
    }
  }
}

安全注意事项

⚠️ 重要:使用第三方镜像端点时,你的 API 密钥和所有请求/响应数据都会经过该镜像服务。请务必:

  • 仅使用可信的镜像服务
  • 了解镜像服务的数据处理和隐私政策
  • 避免在镜像服务上使用与其他服务相同的 API 密钥
  • 如果处理敏感数据,优先考虑自建反向代理(方案 C)

测试容器内的网络连通性

配置完成后,务必在容器内验证连通性。

进入容器

bash
docker compose exec openclaw sh

检查代理环境变量

bash
env | grep -i proxy

预期输出(示例):

HTTP_PROXY=http://127.0.0.1:7890
HTTPS_PROXY=http://127.0.0.1:7890
NO_PROXY=localhost,127.0.0.1,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16

测试 API 端点连通性

直接测试(不通过代理):

bash
curl -v --max-time 10 https://api.anthropic.com/v1/messages 2>&1 | head -20

通过代理测试:

bash
curl -v --max-time 10 --proxy http://127.0.0.1:7890 https://api.anthropic.com/v1/messages 2>&1 | head -20

如果连通,会看到 HTTP 响应(即使是 401 未授权也说明网络可达)。

测试反向代理端点

如果使用方案 C:

bash
curl -v --max-time 10 http://127.0.0.1:8080/anthropic/v1/messages 2>&1 | head -20

DNS 解析测试

bash
nslookup api.anthropic.com

如果 DNS 无法解析,参见下方故障排除的 DNS 相关章节。

OpenClaw 健康检查

bash
node dist/index.js health --token "<your-gateway-token>"

请将 <your-gateway-token> 替换为 .envOPENCLAW_GATEWAY_TOKEN 的值。

OpenClaw Doctor 诊断

bash
node dist/index.js doctor

doctor 命令会检测模型提供商的连通性,帮助定位网络问题。


常见问题与故障排除

代理环境变量未被子进程继承

症状:容器主进程能访问代理,但 OpenClaw 生成的子进程无法联网。

原因:某些进程管理器在 spawn 子进程时不会自动继承父进程的环境变量。

解决方案:确保代理变量通过 docker-compose.ymlenvironment 字段显式设置(而非仅在 Dockerfile 中设置),这样 Docker 会在容器启动时注入到所有进程的环境中。

DNS 无法解析

症状nslookup api.anthropic.com 超时或返回 SERVFAIL

解决方案

  1. docker-compose.yml 中配置自定义 DNS:
yaml
services:
  openclaw:
    # ...(其他配置)
    dns:
      - 8.8.8.8
      - 114.114.114.114

注意dns 选项与 network_mode: host 不兼容。如果使用 host 网络模式,需在宿主机层面配置 DNS。

  1. 如果使用 network_mode: host,修改宿主机的 /etc/resolv.conf
nameserver 8.8.8.8
nameserver 114.114.114.114

或使用 systemd-resolved:

bash
sudo systemd-resolve --set-dns=8.8.8.8 --interface=eth0

证书错误(UNABLE_TO_VERIFY_LEAF_SIGNATURE)

症状:日志中出现 UNABLE_TO_VERIFY_LEAF_SIGNATURESELF_SIGNED_CERT_IN_CHAINERR_TLS_CERT_ALTNAME_INVALID

原因:企业网络环境中的 HTTPS 检测代理(MITM proxy)使用自签名证书替换了上游证书。

解决方案:将企业 CA 证书注入容器。

  1. 将 CA 证书文件放在宿主机上(例如 ./certs/corporate-ca.pem

  2. 修改 docker-compose.yml,挂载证书并设置 Node.js 环境变量:

yaml
services:
  openclaw:
    # ...(其他配置)
    environment:
      - NODE_EXTRA_CA_CERTS=/etc/ssl/certs/corporate-ca.pem
    volumes:
      - ./openclaw-data:/home/node/.openclaw
      - ./certs/corporate-ca.pem:/etc/ssl/certs/corporate-ca.pem:ro

不推荐的做法:不要设置 NODE_TLS_REJECT_UNAUTHORIZED=0,这会禁用所有 TLS 验证,存在严重安全风险。

network_mode: host 与桥接网络下代理地址不同

症状:代理配置后仍无法连接,或连接超时。

原因:使用了错误的代理地址。

排查方法

bash
# 在容器内查看网络模式
# host 模式下,容器的网络接口与宿主机一致
ip addr show

# 如果看到 docker0 或 veth 开头的接口,说明是桥接模式
# 如果看到 eth0、wlan0 等宿主机接口,说明是 host 模式
场景代理地址
host 模式,代理在宿主机http://127.0.0.1:<port>
桥接模式,macOS/Windowshttp://host.docker.internal:<port>
桥接模式,Linuxhttp://172.17.0.1:<port>

NO_PROXY 配置不当导致路由环路

症状:配置代理后,容器内部服务之间的通信也被发往代理,导致超时或错误。

解决方案:在 NO_PROXY 中排除所有内部地址:

bash
NO_PROXY=localhost,127.0.0.1,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,*.local

如果使用 Docker Compose 的服务名互相访问(桥接网络下),还需排除服务名:

bash
NO_PROXY=localhost,127.0.0.1,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,api-proxy,openclaw

代理需要认证

症状:通过代理访问时返回 407 Proxy Authentication Required

解决方案:在代理 URL 中包含用户名和密码:

bash
HTTP_PROXY=http://username:password@proxy-host:port
HTTPS_PROXY=http://username:password@proxy-host:port

特殊字符:如果密码中包含 @:/ 等特殊字符,需要进行 URL 编码。例如 p@ss 应写为 p%40ss


Claude Code 一键配置代理

将下方的完整指令复制给 claude --dangerously-skip-permissions,即可让 Claude Code 自动检测并配置代理。


使用方法

  1. 确保已完成 Docker Compose + 飞书部署,项目目录中已有 .envdocker-compose.yml
  2. 确保宿主机上的代理软件已启动并正常工作
  3. 在终端运行:
bash
claude --dangerously-skip-permissions
  1. 将下方完整指令粘贴给 Claude
  2. Claude 会自动检测代理环境并更新配置

完整指令

将以下内容直接复制,粘贴给 claude --dangerously-skip-permissions(无需修改任何内容):

markdown
请帮我为 OpenClaw Docker 部署配置网络代理,让容器能正常访问 AI API。按照以下步骤操作,在需要我确认的步骤**停下来等我**

## 操作步骤

### 1. 检测当前代理环境

检查宿主机上的代理设置:

```bash
env | grep -i proxy
```

检查常见代理端口是否有服务在监听:

```bash
# Clash 默认端口
lsof -i :7890 2>/dev/null | head -5
# V2Ray 默认端口
lsof -i :10809 2>/dev/null | head -5
# Shadowsocks 默认端口
lsof -i :1080 2>/dev/null | head -5
```

检查容器网络模式:

```bash
grep -A2 'network_mode' docker-compose.yml 2>/dev/null
```

将检测到的信息告诉我,然后问我选择哪种代理方案:
- **方案 B**:通过环境变量传递代理(宿主机有代理软件)
- **方案 C**:反向代理(无代理软件,但服务器可访问海外)
- **方案 D**:使用第三方兼容端点(如 MiniMax)

**等我选择后再继续。**

### 2. 根据我的选择配置代理

#### 如果我选方案 B(环境变量代理):

向我确认代理地址和端口(根据步骤 1 的检测结果给出建议值),然后:

1.`.env` 文件末尾追加代理变量:
```
HTTP_PROXY=http://127.0.0.1:<确认的端口>
HTTPS_PROXY=http://127.0.0.1:<确认的端口>
NO_PROXY=localhost,127.0.0.1,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16
```

2. 更新 `docker-compose.yml`,在 openclaw 服务下添加 environment 块传递代理变量:
```yaml
    environment:
      - HTTP_PROXY=${HTTP_PROXY}
      - HTTPS_PROXY=${HTTPS_PROXY}
      - NO_PROXY=${NO_PROXY}
      - http_proxy=${HTTP_PROXY}
      - https_proxy=${HTTPS_PROXY}
      - no_proxy=${NO_PROXY}
```

#### 如果我选方案 C(反向代理):

1. 创建 `nginx-proxy/nginx.conf`(Anthropic API 反向代理配置)
2.`docker-compose.yml` 中添加 `api-proxy` 服务
3. 更新 `.env` 中的 `ANTHROPIC_BASE_URL` 指向本地反向代理

#### 如果我选方案 D(兼容端点):

向我确认端点 URL,然后更新 `.env` 中的 `ANTHROPIC_BASE_URL`

### 3. 重启容器并测试

```bash
docker compose down
docker compose up -d
```

等待容器启动后,测试连通性:

```bash
# 检查代理变量是否注入
docker compose exec openclaw env | grep -i proxy

# 测试 API 连通性
docker compose exec openclaw curl -s --max-time 15 -o /dev/null -w "%{http_code}" https://api.anthropic.com/v1/messages
```

如果返回非零 HTTP 状态码(如 401),说明网络连通,告诉我成功。
如果超时或返回 000,分析可能的原因并给出修复建议。

### 4. 运行 OpenClaw 健康检查

```bash
docker compose exec openclaw node dist/index.js health --token "$(grep OPENCLAW_GATEWAY_TOKEN .env | cut -d= -f2)"
```

将健康检查结果告诉我。

## 注意事项

- .env 文件包含敏感信息,绝不要读取、打印或提交到 Git
- 不要修改 openclaw.json 中的 `${VAR_NAME}` 占位符,它们是 OpenClaw 运行时变量替换语法
- 如果我的 docker-compose.yml 使用桥接网络(非 host 模式),代理地址需改为 host.docker.internal(macOS/Windows)或 172.17.0.1(Linux)

相关文档

飞书部署系列

上游文档