====== NewAPI Docker 部署指南 ======
本文记录在 VPS 上使用 Docker 部署 NewAPI,并通过 nginx + Cloudflare Origin CA 证书配置 HTTPS 反向代理的完整流程。该流程具有通用性,可供任何人复现。
===== 环境准备 =====
前期需要准备:
- 一台 VPS(本文以 Debian 12 为例)
- 一个托管在 Cloudflare 的域名
- 服务器已安装 Docker 和 Docker Compose
- 服务器已安装 nginx
===== 第一步:创建项目目录 =====
在服务器上创建 NewAPI 的数据目录:
mkdir -p /root/newapi/data
===== 第二步:编写 Docker Compose 配置 =====
创建 `/root/newapi/docker-compose.yml`:
services:
new-api:
image: calciumion/new-api:v1.0.0-rc.21-amd64
container_name: new-api
restart: always
environment:
- TZ=Asia/Shanghai
- SESSION_SECRET=<生成一个64位随机十六进制字符串>
ports:
- "127.0.0.1:3000:3000"
volumes:
- ./data:/data
**关键说明**:
- **镜像版本**:`v1.0.0-rc.21-amd64` 为本文撰写时的最新版,请根据实际检查获取最新版本号
- **SESSION_SECRET**:用于会话加密,必须自行生成。在终端执行 `openssl rand -hex 32` 生成一个 64 位十六进制字符串
- **端口映射**:绑定到 `127.0.0.1`,避免容器端口直接暴露到公网。外部访问通过 nginx 反向代理
- **数据持久化**:`./data:/data` 将 SQLite 数据库映射到宿主机目录,容器重启数据不丢失
===== 第三步:配置 Nginx 反向代理 =====
创建 `/etc/nginx/sites-enabled/newapi`:
# HTTP → HTTPS 自动跳转
server {
listen 80;
listen [::]:80;
server_name your-domain.example.com;
return 301 https://$host$request_uri;
}
# HTTPS
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name your-domain.example.com;
ssl_certificate /etc/ssl/your-cert.crt;
ssl_certificate_key /etc/ssl/your-cert.key;
ssl_protocols TLSv1.2 TLSv1.3;
client_max_body_size 20M;
proxy_read_timeout 120;
proxy_send_timeout 120;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
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;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
配置完成后测试并重载 nginx:
nginx -t # 测试配置语法
nginx -s reload # 重载配置
===== 第四步:开放防火墙 =====
如果服务器启用了 ufw 防火墙,放行 80 和 443 端口:
ufw allow 80/tcp comment 'HTTP'
ufw allow 443/tcp comment 'HTTPS'
===== 第五步:配置 Cloudflare SSL 证书 =====
本文使用 **Cloudflare Origin CA** 证书实现 HTTPS。步骤如下:
- 登录 Cloudflare Dashboard,进入目标域名的 **SSL/TLS → Origin Server**
- 点击 **Create Certificate**
- 私钥类型选择 **RSA(2048)**,主机名保持默认(包含裸域和通配符)
- 有效期选择 **15 年**
- 点击 **Create**
- 将显示的 Origin Certificate 保存为 `your-cert.crt`,Private Key 保存为 `your-cert.key`
**注意**:私钥只展示一次,务必及时保存。
上传证书到服务器:
scp your-cert.crt user@your-server:/etc/ssl/
scp your-cert.key user@your-server:/etc/ssl/
设置私钥权限:
chown root:www-data /etc/ssl/your-cert.key
chmod 640 /etc/ssl/your-cert.key
回到 Cloudflare Dashboard → **SSL/TLS**,将加密模式设为 **Full (Strict)**。
===== 第六步:配置 Cloudflare WAF(避免下游客户端被拦截)=====
NewAPI 部署完成后,下游客户端使用 OpenAI 官方 Python 库连接时可能遇到 HTTP 403「Your request was blocked」错误。原因是该库发出的 HTTP 请求默认使用 ''User-Agent: OpenAI/Python ...'',会被 Cloudflare WAF 的托管规则集拦截。
在 Cloudflare 仪表盘中添加一条 WAF 自定义规则即可解决:
- 登录 **dash.cloudflare.com** → 选择域名 → **Security** → **WAF** → **Custom rules**
- 点击 **Create rule**
- Rule name:可填写「Allow OpenAI Python client」
- 条件:字段 **User Agent**,运算符 **contains**,值 **OpenAI/Python**
- (可选)如果只想对该 NewAPI 子域名生效,再添加一行条件:**Hostname** **equals** **your-domain.example.com**
- Action:选择 **Skip**
- 在「WAF components to skip」中勾选 **All managed rules**
- 点击 **Deploy**
注意表达式中的 ''OpenAI/Python'' 前面不要加空格,否则规则无法匹配。部署后立即生效。
**替代方案**:如果无法修改 Cloudflare 配置,也可以在客户端侧解决。以 Hermes Agent 为例,通过自定义请求头将 User-Agent 改为非 SDK 默认值:
hermes config set model.extra_headers.User-Agent "curl/7.86.0"
修改后所有调用都会使用 ''User-Agent: curl/7.86.0'',不再被 WAF 拦截。
===== 第七步:启动容器 =====
cd /root/newapi
docker compose pull
docker compose up -d
验证容器运行状态:
docker ps --filter name=new-api --format 'table {{.Names}}\t{{.Status}}'
===== 第八步:验证 =====
通过 curl 测试 HTTPS 是否正常工作:
curl -sI https://your-domain.example.com | grep -i 'HTTP/'
应返回 **HTTP/2 200** 或 **301**。
浏览器访问 ''https://your-domain.example.com'',应看到 NewAPI 的初始化页面。
===== 常见问题排查 =====
^ 错误 ^ 原因 ^ 解决方法 ^
| 容器反复重启 | 数据目录权限问题 | 检查 `./data` 目录的权限,执行 `chown -R 1000:1000 ./data` |
| 521 Web 服务器拒绝连接 | 端口未放行或 nginx 未运行 | 确认 ufw 放行了 80/443,`nginx -t` 检查配置 |
| 526 无效的 SSL 证书 | Full (Strict) 模式下使用了自签名证书 | 改用 Origin CA 证书,或将 CF 模式降级为 Full |
| 容器启动后无法访问 | SESSION_SECRET 未设置或为空 | 检查 docker-compose.yml 中 SESSION_SECRET 是否正确 |
| 403 Your request was blocked | CF WAF 拦截了 OpenAI Python 库的 User-Agent | 按第六步添加 WAF Skip 规则 |
{{tag>NewAPI Docker 部署 nginx Cloudflare 反向代理}}
~~DISCUSSION~~