网络代理配置:让 Docker 容器正常访问 AI API
在中国大陆部署 OpenClaw 时,容器需要访问 api.anthropic.com、api.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 pull、docker build等操作。容器运行时的网络请求不一定会继承守护进程代理设置,需结合方案 B 使用。
方法一:systemd override(推荐用于 Linux 服务器)
创建 systemd 配置覆盖文件:
sudo mkdir -p /etc/systemd/system/docker.service.d创建 /etc/systemd/system/docker.service.d/http-proxy.conf:
[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:
sudo systemctl daemon-reload
sudo systemctl restart docker验证配置是否生效:
sudo systemctl show --property=Environment docker方法二:daemon.json(Docker 23.0+)
编辑 /etc/docker/daemon.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:
sudo systemctl restart dockerDocker Desktop 用户:在 Docker Desktop 的 Settings > Resources > Proxies 中可以直接配置代理,无需手动编辑文件。
方案 B:Docker Compose 环境变量代理(按容器)
这是最常用的方案。在宿主机已有代理软件(如 Clash、V2Ray、Shadowsocks 等)的情况下,只需将代理地址通过环境变量传给容器即可。
理解容器如何访问宿主机代理
容器访问宿主机上的代理服务时,代理地址取决于网络模式:
| 网络模式 | 代理地址 | 说明 |
|---|---|---|
network_mode: host | http://127.0.0.1:7890 | 容器共享宿主机网络栈,直接用 localhost |
| 桥接网络(默认) — macOS/Windows | http://host.docker.internal:7890 | Docker Desktop 提供的特殊 DNS |
| 桥接网络(默认) — Linux | http://172.17.0.1:7890 | Docker 默认网桥网关 IP |
飞书部署默认使用
network_mode: host。如果你按照 Docker Compose + 飞书部署指南 部署,容器直接共享宿主机网络,代理地址使用127.0.0.1即可。
配置 .env 文件
在 .env 文件中添加代理变量:
# .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 中传递代理环境变量:
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):
# .env
HTTP_PROXY=http://host.docker.internal:7890
HTTPS_PROXY=http://host.docker.internal:7890Linux(桥接网络):
# .env
HTTP_PROXY=http://172.17.0.1:7890
HTTPS_PROXY=http://172.17.0.1:7890Linux 上查看网桥网关 IP:
docker network inspect bridge | grep Gateway
方案 C:反向代理 / API 网关(自建中转)
当无法使用正向代理,或需要为多个服务集中管理 AI API 访问时,可以自建反向代理。
原理
在 Docker Compose 中额外运行一个 Nginx(或 Caddy)服务,将请求转发到 api.anthropic.com。OpenClaw 将 API 请求发往本地反向代理,由反向代理转发到上游。
OpenClaw 容器 → Nginx 反向代理容器 → (宿主机网络/代理) → api.anthropic.comNginx 配置
创建 nginx-proxy/nginx.conf:
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:
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 指向本地反向代理:
# .env
ANTHROPIC_BASE_URL=http://127.0.0.1:8080/anthropicopenclaw.json 中的 ${ANTHROPIC_BASE_URL} 会在运行时自动解析为上面的值:
{
"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 服务:
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 文件:
# .env
ANTHROPIC_BASE_URL=https://your-mirror-endpoint.example.com
ANTHROPIC_AUTH_TOKEN=your_api_token_hereOpenClaw 的 openclaw.json 通过 ${ANTHROPIC_BASE_URL} 引用此变量,无需修改配置文件:
{
"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 | 说明 |
|---|---|---|
| MiniMax | https://api.minimax.io/anthropic | 支持 Anthropic Messages API 格式 |
模型 ID 差异:不同端点支持的模型 ID 可能不同。例如 MiniMax 的兼容端点可能使用自己的模型 ID(如
MiniMax-M2.1)。请根据端点文档调整openclaw.json中的模型配置。
配置 MiniMax 作为后备提供商的示例:
{
"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)
测试容器内的网络连通性
配置完成后,务必在容器内验证连通性。
进入容器
docker compose exec openclaw sh检查代理环境变量
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 端点连通性
直接测试(不通过代理):
curl -v --max-time 10 https://api.anthropic.com/v1/messages 2>&1 | head -20通过代理测试:
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:
curl -v --max-time 10 http://127.0.0.1:8080/anthropic/v1/messages 2>&1 | head -20DNS 解析测试
nslookup api.anthropic.com如果 DNS 无法解析,参见下方故障排除的 DNS 相关章节。
OpenClaw 健康检查
node dist/index.js health --token "<your-gateway-token>"请将
<your-gateway-token>替换为.env中OPENCLAW_GATEWAY_TOKEN的值。
OpenClaw Doctor 诊断
node dist/index.js doctordoctor 命令会检测模型提供商的连通性,帮助定位网络问题。
常见问题与故障排除
代理环境变量未被子进程继承
症状:容器主进程能访问代理,但 OpenClaw 生成的子进程无法联网。
原因:某些进程管理器在 spawn 子进程时不会自动继承父进程的环境变量。
解决方案:确保代理变量通过 docker-compose.yml 的 environment 字段显式设置(而非仅在 Dockerfile 中设置),这样 Docker 会在容器启动时注入到所有进程的环境中。
DNS 无法解析
症状:nslookup api.anthropic.com 超时或返回 SERVFAIL。
解决方案:
- 在
docker-compose.yml中配置自定义 DNS:
services:
openclaw:
# ...(其他配置)
dns:
- 8.8.8.8
- 114.114.114.114注意:
dns选项与network_mode: host不兼容。如果使用 host 网络模式,需在宿主机层面配置 DNS。
- 如果使用
network_mode: host,修改宿主机的/etc/resolv.conf:
nameserver 8.8.8.8
nameserver 114.114.114.114或使用 systemd-resolved:
sudo systemd-resolve --set-dns=8.8.8.8 --interface=eth0证书错误(UNABLE_TO_VERIFY_LEAF_SIGNATURE)
症状:日志中出现 UNABLE_TO_VERIFY_LEAF_SIGNATURE、SELF_SIGNED_CERT_IN_CHAIN 或 ERR_TLS_CERT_ALTNAME_INVALID。
原因:企业网络环境中的 HTTPS 检测代理(MITM proxy)使用自签名证书替换了上游证书。
解决方案:将企业 CA 证书注入容器。
将 CA 证书文件放在宿主机上(例如
./certs/corporate-ca.pem)修改
docker-compose.yml,挂载证书并设置 Node.js 环境变量:
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 与桥接网络下代理地址不同
症状:代理配置后仍无法连接,或连接超时。
原因:使用了错误的代理地址。
排查方法:
# 在容器内查看网络模式
# host 模式下,容器的网络接口与宿主机一致
ip addr show
# 如果看到 docker0 或 veth 开头的接口,说明是桥接模式
# 如果看到 eth0、wlan0 等宿主机接口,说明是 host 模式| 场景 | 代理地址 |
|---|---|
| host 模式,代理在宿主机 | http://127.0.0.1:<port> |
| 桥接模式,macOS/Windows | http://host.docker.internal:<port> |
| 桥接模式,Linux | http://172.17.0.1:<port> |
NO_PROXY 配置不当导致路由环路
症状:配置代理后,容器内部服务之间的通信也被发往代理,导致超时或错误。
解决方案:在 NO_PROXY 中排除所有内部地址:
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 的服务名互相访问(桥接网络下),还需排除服务名:
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 中包含用户名和密码:
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 自动检测并配置代理。
使用方法
- 确保已完成 Docker Compose + 飞书部署,项目目录中已有
.env和docker-compose.yml - 确保宿主机上的代理软件已启动并正常工作
- 在终端运行:
claude --dangerously-skip-permissions- 将下方完整指令粘贴给 Claude
- Claude 会自动检测代理环境并更新配置
完整指令
将以下内容直接复制,粘贴给 claude --dangerously-skip-permissions(无需修改任何内容):
请帮我为 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)相关文档
飞书部署系列
- Claude Code 一键部署 -- 复制指令给 Claude Code 自动完成部署
- Docker Compose + 飞书部署指南 -- 完整部署步骤
- 飞书应用配置详解 -- 飞书开放平台配置
- 配置参考与故障排除 -- 环境变量参考与故障排除