对话笔记直发:7.25 在 yun1 部署 new-api 并通过 Cloudflare 域名 HTTPS 访问 — 实操记录。分类:AI工程。
在 yun1 部署 new-api 并通过 Cloudflare 域名 HTTPS 访问 — 实操记录
服务器:yun1 (
你的服务器IP(已脱敏)),Ubuntu 6.8 / x86_64,Docker 28 项目:QuantumNous/new-api(LLM 网关,默认容器内端口 3000) 域名:new.oiob.cn(Cloudflare 代理) 记录日期:2026-07-25
一、目标
在 yun1 上用 Docker 部署 new-api,对外用二级域名 new.oiob.cn 走 HTTPS 访问;容器 3000 改为随机高位端口且不直接暴露公网。
二、环境关键事实(踩坑前提)
- SSH:
admin@你的服务器IP(已脱敏)“,sudo无密码。 - 出口受限:
github.com、registry-1.docker.io被墙;但ghcr.io可达,且 Docker 已配阿里云/DaoCloud/1ms 镜像源。- 拉镜像:
docker pull calciumion/new-api:latest(走镜像源),不能 git clone 源码构建。
- 拉镜像:
- 现有容器:
site80-nginx(nginx:alpine, 仅 80, 静态页)、ai-chat-*、ainovel。 site80-nginx原restart=no,只挂/opt/site80/index.html,无代理配置。- 安全组实测:放行 22 / 8181 / 3001;
443也放行;80 及 8080/8880/2052/2053/2082/2083/2086/2087/2095/2096/8443 全部被拦(外部探活超时)。
三、第一性原理架构决策
- CF 代理只回源 80/443(+少量白名单端口)。随机高位端口 CF 直接打不到 → 必须有反向代理收口。
- 选 443 而非 80:用户要求”不走 80”;443 是 CF 默认回源 HTTPS 端口,无需自定义源站端口;实测 443 安全组已放行。
- 443 上用自签证书 + CF SSL=Full:Full 模式接受任意证书(含自签)。浏览器看到的仍是 CF 签发的有效 HTTPS(绿锁),自签证书只在 CF↔源站这一段。
- SQLite + /data 卷:单节点、零运维。
数据流:
浏览器 →HTTPS→ CF(代理,橙云) →源站:443(自签, Full 接受) → nginx → new-api:3000(容器名, Docker 网络 web)
四、实施步骤
1. 准备目录与网络
ssh admin@`你的服务器IP(已脱敏)`
sudo mkdir -p /opt/new-api/data /opt/site80/conf.d /opt/site80/certs
sudo chown admin:admin /opt/new-api /opt/new-api/data /opt/site80/conf.d
docker network create web # 用户自定义桥, 启用容器名 DNS2. 拉取并启动 new-api(随机高位端口,仅绑回环)
docker pull calciumion/new-api:latest
SECRET=$(openssl rand -hex 32)
docker run -d --name new-api --restart always --network web \
-p 127.0.0.1::3000 \
-e TZ=Asia/Shanghai -e SESSION_SECRET="$SECRET" -e MEMORY_CACHE_ENABLED=true \
-v /opt/new-api/data:/data \
calciumion/new-api:latest-p 127.0.0.1::3000:Docker 分配随机高位宿主端口,但只绑127.0.0.1(公网不可达)。nginx 经容器名new-api:3000访问。- 验证:
docker port new-api 3000→127.0.0.1:xxxxx;curl -sS http://127.0.0.1:xxxxx/→ 200。
3. 生成自签证书
sudo openssl req -x509 -newkey rsa:2048 -nodes \
-keyout /opt/site80/certs/key.pem -out /opt/site80/certs/cert.pem \
-days 3650 -subj "/CN=new.oiob.cn" -addext "subjectAltName=DNS:new.oiob.cn"
sudo chown -R admin:admin /opt/site80/certs4. nginx 配置 /opt/site80/conf.d/new-api.conf
server {
listen 443 ssl;
server_name new.oiob.cn;
ssl_certificate /etc/nginx/certs/cert.pem;
ssl_certificate_key /etc/nginx/certs/key.pem;
location / {
proxy_pass http://new-api: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 https;
proxy_set_header X-Forwarded-Host $host;
proxy_read_timeout 300s; proxy_send_timeout 300s;
client_max_body_size 50m;
}
}(保留原 default.conf 静态页 server,server_name localhost。)
5. 重建 nginx(挂配置+证书,连 web 网络,restart always)
docker rm -f site80-nginx
docker run -d --name site80-nginx --restart always -p 443:443 \
-v /opt/site80/index.html:/usr/share/nginx/html/index.html:ro \
-v /opt/site80/conf.d:/etc/nginx/conf.d:ro \
-v /opt/site80/certs:/etc/nginx/certs:ro \
--network bridge nginx:alpine
docker network connect web site80-nginx
docker restart site80-nginx # 关键: 让 nginx 启动后能解析 new-api
docker exec site80-nginx nginx -t6. Cloudflare(API Token,需 DNS:Edit 权限)
ZONE=1802496ecd329134b10192a2543c98a9
# 建 A 记录(代理/橙云)
curl -X POST -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"type":"A","name":"new","content":"`你的服务器IP(已脱敏)`","proxied":true,"ttl":1}' \
https://api.cloudflare.com/client/v4/zones/$ZONE/dns_records- SSL 模式需人工在 CF 后台设为 Full(API 改 SSL 需
Zone:SSL/TLS:Edit权限,本会话 token 无此权限 → 返回 9109)。 - 自定义源站端口(8080 等)经 API 设不进去(返回
port=None),且非 80/443 CF 不会用 → 因此走默认 443。
五、验证结果
- 本地:
curl -ksS -H "Host: new.oiob.cn" https://127.0.0.1:443/→ 200。 - 经 CF:
curl -ksS -I https://new.oiob.cn→HTTP/2 200,响应头x-new-api-version: v1.0.0-rc.21,页面标题New API。 - 公网
32768探活:超时(已关闭,绑回环)。
六、踩坑清单(经验教训)
- CF 只允许回源 80/443(+白名单),随机高位端口必须靠反代收口。
- 端口 80 被安全组拦 → 访问报 521(Web server is down)。用户要求不走 80 → 改 443。
- 自定义源站端口经 API 设不进(
port=None);非 80/443 端口 CF 不会回源 → 直接用默认 443。 - nginx + Docker 网络 DNS:nginx 若在连入
web网络之前启动,解析不了容器名new-api→ 表现为Connection reset by peer。修复:docker network connect web后docker restart(或nginx -s reload)。 - 改 CF SSL 模式需
Zone:SSL/TLS:Edit权限的 token,否则只能在后台手动改。 - 出口受限:docker 镜像走国内镜像源,别 git clone 源码;github 直连不通。
- 测端口是否被安全组放行:从外部机器
curl http://公网IP:端口——超时=拦,拒绝=放行(无服务),200=通。本机ss/本地 curl 不能代表外部可达性(安全组在 VPC 边界)。
七、运维 & 安全
- 数据持久化:
/opt/new-api/data(SQLite)。 - 重启自拉起:
new-api、site80-nginx均--restart always。 - 公网已关闭明文高位端口(绑
127.0.0.1),仅经域名 HTTPS 可达。 - 首次登录
https://new.oiob.cn:默认root/123456,立即改密码。 - 想更严格:换 Cloudflare Origin Certificate + SSL 改
Full (strict)。 - 如要彻底禁止公网直连容器:
-p 127.0.0.1::3000(已采用)。
第二篇:在 WSL 建 claude 普通用户 + yolo 启动器,绕开 root 限制(并定位网关 Cloudflare 拦截)
环境:WSL2 Ubuntu 24.04(
/dev/sddext4,工作目录/mnt/vps、/mnt/demo),Claude Code 2.1.220 操作用户:root(WSL 内) 记录日期:2026-07-26 关联:本机还跑着 new-api 网关(new.oiob.cn),但 Claude 实际用的是另一个网关muyuan.do(见下)
〇、目标与原始问题
用户想实现”类 Codex —yolo”的体验:Claude Code 长时间连续、尽量无人值守地从头跑到尾执行复杂任务。
但 Claude CLI 有硬性安全限制:--dangerously-skip-permissions 禁止 root / sudo 用户执行。
因此规划:新建一个普通用户 claude,给它”接近 root”的权限,从该用户启动 Claude Code,从而既能用 yolo flag,又拥有足够权限。
一、先搞清楚限制到底拦什么(关键判断)
不确定 2.1.220 拦的是”uid==0”还是”有 sudo 能力”。这一点决定权限模型怎么设计,所以先实测。
环境探查(root 下)
whoami -> root
claude --version -> 2.1.220 (Claude Code)
which claude -> /usr/bin/claude (-> /usr/lib/node_modules/@anthropic-ai/claude-code/bin/claude.exe)
node --version -> v22.22.2 (claude 自带 runtime,用户无需另装 node)
docker group
---
> 注:本文涉及的服务器公网 IP / Tailnet / 局域网 IP 已脱敏,请替换为你自己的地址。
---
**相关**: [[00-索引-AI工程索引]] [[7.20 ainovel-cli 使用说明]]