对话笔记直发: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 全部被拦(外部探活超时)。

三、第一性原理架构决策

  1. CF 代理只回源 80/443(+少量白名单端口)。随机高位端口 CF 直接打不到 → 必须有反向代理收口。
  2. 选 443 而非 80:用户要求”不走 80”;443 是 CF 默认回源 HTTPS 端口,无需自定义源站端口;实测 443 安全组已放行。
  3. 443 上用自签证书 + CF SSL=Full:Full 模式接受任意证书(含自签)。浏览器看到的仍是 CF 签发的有效 HTTPS(绿锁),自签证书只在 CF↔源站这一段。
  4. 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        # 用户自定义桥, 启用容器名 DNS

2. 拉取并启动 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/certs

4. 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 -t

6. 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 探活:超时(已关闭,绑回环)。

六、踩坑清单(经验教训)

  1. CF 只允许回源 80/443(+白名单),随机高位端口必须靠反代收口。
  2. 端口 80 被安全组拦 → 访问报 521(Web server is down)。用户要求不走 80 → 改 443。
  3. 自定义源站端口经 API 设不进(port=None);非 80/443 端口 CF 不会回源 → 直接用默认 443。
  4. nginx + Docker 网络 DNS:nginx 若在连入 web 网络之前启动,解析不了容器名 new-api → 表现为 Connection reset by peer。修复:docker network connect web 后 docker restart(或 nginx -s reload)。
  5. 改 CF SSL 模式需 Zone:SSL/TLS:Edit 权限的 token,否则只能在后台手动改。
  6. 出口受限:docker 镜像走国内镜像源,别 git clone 源码;github 直连不通。
  7. 测端口是否被安全组放行:从外部机器 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/sdd ext4,工作目录 /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 使用说明]]