← 返回资讯

New API 部署实操:从 docker run 到生产可用

2026-08-07

有人在群里发了一句话:New API 我 docker run 一行就起来了,浏览器打开 3000 端口能进后台,是不是就算部署完了?

从”能用”的角度算是。从”能给团队用”的角度,差得还远。那条命令跑出来的是一个演示形态:数据落在 SQLite 里、没有 HTTPS、没有反向代理、只有一个进程、秘钥全写在命令行里躺在 shell history 中。它的价值是让你花五分钟确认这套东西是不是你想要的,而不是让你直接把团队的上游 Key 灌进去。

我把这篇拆成两段:先用最短路径跑起来,再把它改成能上生产的样子。中间那些”改什么、为什么改、不改会出什么事”,才是真正花时间的地方。所有命令和环境变量都以官方仓库 README 当次为准——这类项目迭代快,本文写下的形态和你看到的可能已经有出入。

一、先选安装方式:三条路,各有各的适用人群

New API 官方给了三种装法,区别不在”难不难”,而在你后面要不要改配置

方式大致操作适合谁
Docker Compose(官方推荐)git clone 仓库后 docker-compose up -d打算长期跑、要改数据库/环境变量/要升级的人
Docker 命令一条 docker run 起容器只想先试试、验证完就删的人
宝塔面板应用商店面板里一键安装已经在用宝塔管服务器、不想碰命令行的人

我的建议很明确:除非你只是试试水,否则直接从 Compose 起步。原因不是 Compose 更”高级”,而是它把配置沉淀成了一个可以进版本库、可以 diff、可以交接的文件。用 docker run 起的服务,三个月后你想加一个环境变量,得先从 shell history 里考古当初那条命令长什么样——而且大概率已经被冲掉了。宝塔那条路同理,一键装完之后的配置在面板里,迁移和交接时你得靠截图传递知识。

Compose 的另一个隐性好处是升级。镜像更新之后,Compose 能保证你用完全相同的参数重建容器;手敲命令重建时,漏一个 -e 就是一次故障。

二、最短路径:一条命令先跑起来

如果你就是想先看一眼,官方给的 SQLite 版命令是这条:

docker run -p 3000:3000 -v ./data:/data calciumion/new-api:latest

这行很短,但每一段都值得说清楚。

-p 3000:3000 —— New API 的默认端口是 3000。冒号左边是宿主机端口,右边是容器内端口。容器内那个 3000 是程序自己监听的,别动;左边的可以随便换,比如宿主机 3000 已经被占了就写 -p 8080:3000注意这一步会把服务直接暴露在服务器的公网 IP 上,如果你的云服务器安全组开了 3000,那么这个还没配置好的后台此刻是全网可见的。试水阶段的正确做法是:安全组不放行 3000,走 SSH 端口转发从本地访问;或者干脆写成 -p 127.0.0.1:3000:3000,只绑回环地址。

-v ./data:/data —— 这是整条命令里最不能省的一段。容器的文件系统是临时的,容器一删,里面写过的东西全没。SQLite 的数据库文件就落在 /data 目录下,不挂载出来意味着:你辛辛苦苦配的渠道、发的令牌、攒的用量记录,在你下次 docker rm 重建容器时会一起消失,而且没有任何提示。我见过不止一次这种事故——升级镜像时习惯性 docker rmdocker run,回来发现后台变成了全新的初始状态。挂载目录不是优化项,是保命项。

另外,./data 这种相对路径写法不是所有 Docker 环境都认。如果执行时报路径相关的错,换成绝对路径,比如 /opt/new-api/data,同时确认宿主机上这个目录的属主和权限允许容器进程写入。

calciumion/new-api:latest —— 镜像地址。latest 意味着你每次 pull 都可能拿到不同的东西,试水期无所谓,正式环境的取舍我放在第六节讲。

关于首次登录

容器起来之后打开 http://<你的地址>:3000,按页面提示完成初始账号的创建。这里我不会给你任何默认账号密码——官方 README 里没有明确写出这一项,网上流传的各种”默认账号”我无法核实,照抄一个错的进来是安全事故级别的后果。请以官方文档和你启动后页面上的实际提示为准。

顺带一句实操纪律:初始管理员账号建立之后,第一件事是把密码改成强密码,第二件事是确认这个后台没有裸奔在公网。网关后台里躺着的是你所有上游服务商的 Key,它的安全等级等同于你的密码库。这一层的完整思路可以看 网关安全加固

三、什么时候必须从 SQLite 换成 MySQL

SQLite 版能撑住的场景比很多人以为的要多——单机、几个人用、请求量不大,它不会成为瓶颈。但有三条线一旦越过,就必须换:

第一条线:你要跑多个节点。 SQLite 是一个本地文件,两个容器各写各的文件,等于两套互不相干的数据。这不是”性能不够”的问题,是逻辑上根本跑不起来。只要你打算做多副本、做滚动升级、做多机高可用,第一步就是把数据库外置。

第二条线:数据量和写入频率上来了。 网关的日志和用量记录是持续高频写入的,这类负载在单文件数据库上会越来越吃力,而且表变大之后你想在后台查历史用量会明显变慢。

第三条线:你需要正经的备份和恢复能力。 SQLite 也能备份(复制文件),但要做到不停服的一致性快照、按时间点恢复、备份自动校验,成熟数据库的工具链要省心得多。

换法很简单,在启动参数里加一个环境变量:

docker run -p 3000:3000 -v ./data:/data \
  -e SQL_DSN="root:password@tcp(host:3306)/db" \
  calciumion/new-api:latest

SQL_DSN 就是数据库连接串,MySQL 和 PostgreSQL 都走这一个变量。版本要求要留意:远程数据库需要 MySQL 5.7.8 及以上,或 PostgreSQL 9.6 及以上。如果你用的是云厂商的托管数据库,实例创建时选的版本基本都够;真正容易翻车的是从老服务器上拿来的存量实例。

两个实操提醒。一是那串 root:password 是示例,别真用 root 账号跑业务——给 New API 单独建一个库、单独建一个只对这个库有权限的账号,出问题时炸不到别的东西。二是即使换了 MySQL,/data 的挂载也别急着删,程序在本地目录还可能存放其他运行时文件,删挂载是给自己埋雷。

四、多节点部署:两个 secret 必须统一,这是本文最值钱的一节

这一节讲的坑,特点是症状轻微、极难复现、找错方向能烧掉一整天

单机跑的时候你可以完全不管这两个变量。一旦你在负载均衡后面挂了两个及以上的 New API 节点,它们就是必答题。

SESSION_SECRET:不一致的表现是”用户时不时被登出”

官方说得很直白:多节点部署必须设置 SESSION_SECRET,且所有节点必须一致

为什么?会话状态需要用一个 secret 来签名或加密。你在节点 A 登录,A 用自己的 secret 签发了会话凭据;下一个请求被负载均衡分到节点 B,B 拿自己的 secret 去校验,对不上,于是判定这个会话无效——你就被踢回登录页了。

这个故障之所以难查,是因为它不是稳定复现的。负载均衡把你分回 A 时一切正常,分到 B 时就掉线。用户的描述会是”有时候好好的突然要重新登录""刷新一下又好了”,你自己在测试环境(单节点)怎么点都复现不出来。等你终于想到去看是不是多节点会话问题时,通常已经在浏览器缓存、Cookie 域名、反向代理配置这些方向上白折腾了半天。

所以:上多节点之前,先生成一个足够长的随机字符串,写进所有节点的环境变量,一个字符都不能差。 这个值属于机密,它的泄露等价于会话可被伪造。

CRYPTO_SECRET:缓存键的 HMAC secret

CRYPTO_SECRET 是缓存键的 HMAC secret,默认取 SESSION_SECRET 的值

这个默认行为很友好:单机也好、多机也好,只要你把 SESSION_SECRET 统一了,CRYPTO_SECRET 会跟着统一,你可以完全不显式配置它。反过来说,如果你出于密钥分离的考虑要显式设置 CRYPTO_SECRET,那么按同样的道理,所有共享同一份缓存的节点也得把它设成同一个值——否则各节点算出的缓存键对不上,共享缓存就退化成了各写各的。

REDIS_CONN_STRING:多节点共享缓存的前提

REDIS_CONN_STRING 是 Redis 缓存的连接串。单机起步时不接 Redis 也能跑(前面那条最短命令里就没有它)。但多节点场景下,如果每个节点各缓存各的,节点之间的状态就会出现不一致的窗口,配置改动的生效时间也会变得不可预期。要上多节点,Redis 和数据库一样属于必须外置的共享组件

三个变量在两种形态下该怎么配,一张表说清:

变量单机多节点
SESSION_SECRET可不设,但建议显式设置,方便日后扩节点必须设置,所有节点完全一致
CRYPTO_SECRET通常不用管,默认取 SESSION_SECRET不显式设则跟随 SESSION_SECRET;显式设则所有节点一致
REDIS_CONN_STRING可不配指向同一个 Redis 实例
SQL_DSN可不配(用 SQLite)必须配,所有节点指向同一个库

一个能省事的做法:哪怕你现在只跑单机,也把 SESSION_SECRET 显式设好。将来扩到第二个节点时,你只需要复制一份环境变量文件,不用回头补课,也不会因为”忘了当初有没有设”而制造一次线上会话大面积失效。

五、生产化清单:把演示形态改成能上线的样子

以下都是通用运维实践,不涉及 New API 特有的配置项。凡是你在官方文档里找不到的配置名,都不要照着任何文章(包括这篇)凭印象写。

1)前面加反向代理,全站 HTTPS。 让容器只监听回环地址,公网入口交给 Nginx / Caddy 这类反向代理,由它终结 TLS 并转发到 3000。理由不只是加密:后台登录态、API Key 都在这条链路上传输,明文 HTTP 等于把令牌广播出去。同时在代理层顺手做两件事——把管理后台路径限制到办公网 IP 或加一层基础认证,以及为长响应调大超时(模型流式输出会持续很久,代理默认超时经常不够)。

2)数据库外置,并且真的做备份。 备份的判断标准只有一个:你有没有在另一台机器上,把备份文件成功还原过一次。 没演练过的备份不算备份。恢复演练要覆盖”表结构和数据都在""还原后网关能正常启动并读到渠道配置”这两点。

3)密钥不进镜像、不进 git。 上游服务商的 Key、数据库密码、SESSION_SECRET,都通过环境变量注入,用 Compose 的环境变量文件承载,并把那个文件加进 .gitignore。同时把它的文件权限收紧到只有部署账号可读。命令行里直接写密码的方式要避免——它会留在 shell history 里,也会出现在同机其他用户可见的进程列表中。

4)日志接出来,别只靠 docker logs 容器重建日志就没了。至少做到:容器日志按大小滚动、有留存上限(否则磁盘写满是迟早的事);关键错误有告警。最基础的存活监控是定时探测网关地址,异常时能通知到人。

5)升级流程固化成三步:备份数据库 → 拉新镜像 → 用相同参数重建容器。 顺序不能颠倒。另外,正式环境是否继续用 latest 需要你自己权衡:跟着 latest 走省心但不可控,某次 pull 可能带来你没预期的变化;固定到具体版本更可控,但要主动跟进更新。具体有哪些可用的版本标签,请查官方仓库,不要凭猜测填。

6)先在预发环境走一遍完整流程。 尤其是首次从 SQLite 迁到 MySQL、首次从单机扩到多节点这两次变更,都属于”改完当时看着好像正常,一周后才暴露问题”的类型。

如果你还在纠结要不要自己扛这套运维,自建网关与托管服务的对比 那篇把成本和责任边界算得更细;想横向看看其他自部署网关的部署差异,可以对照 OneAPI 部署与配置实战;对 New API 这个项目本身的定位还不清楚的,先看 New API 是什么

六、上线前自查清单

  1. 后台管理端口没有裸露在公网,公网入口只有反向代理,且已启用 HTTPS。
  2. 数据目录已挂载到宿主机(或已换成外置数据库),确认过删掉容器再重建,数据还在。
  3. 若用远程数据库,版本满足 MySQL ≥ 5.7.8 或 PostgreSQL ≥ 9.6,且用的是专库专账号,不是 root。
  4. SESSION_SECRET 已显式设置为足够长的随机值;多节点部署时,逐个节点核对过它们完全一致。
  5. 多节点场景下,REDIS_CONN_STRINGSQL_DSN 指向同一套共享组件,缓存不是各写各的。
  6. 所有密钥通过环境变量文件注入,该文件已进 .gitignore、权限已收紧,没有出现在命令行和提交记录里。
  7. 已在另一台机器上完整还原过一次数据库备份,并确认还原后网关能正常启动。
  8. 升级动作已写成固定步骤(先备份、再拉镜像、用相同参数重建),并且团队里不止一个人知道怎么执行。

最后提醒一句:本文涉及的命令、环境变量和数据库版本要求,均以官方仓库 README 当次内容为准。这类项目更新频繁,动手前花两分钟对一眼官方文档,比事后排查一个下午划算得多。

相关阅读