NewAPI Docker 部署怎么做:镜像、编排与数据持久化

2026-08-31

数据截至 2026-08,价格与限额以各官网为准。本文只讲计费与接入机制,不列具体价格数字。

先把结论说完:NewAPI 的 Docker 部署有三种形态——单容器、文档里那份”标准编排”、以及只留网关自己的”简化编排”,官方对这三者的定位分别是个人使用、生产环境和测试。真正决定你会不会翻车的不是选哪种,而是数据持久化写没写对。 官方这套编排里数据其实散落在三个地方:应用数据目录、日志目录、数据库的数据目录,三者的挂载写法还不一样。再加上一条容易被跳过的事实:仓库根目录的 docker-compose.yml 和官方文档里贴的”标准配置”并不是同一份,两者在网络定义、缓存鉴权、日志开关上都有出入。这篇把镜像、编排、持久化这三块按官方原文逐一拆开。

本文所有配置项、命令与参数说明均出自项目官方文档站与官方仓库文件(QuantumNous/new-api),我们没有实际运行过这些命令,具体取值以官方文档当前版本为准。想先了解六种部署方式怎么选、以及部署前后的整体检查项,可以看NewAPI 部署教程的完整步骤那篇,本文只深挖 Docker 这一条线。

三种形态先分清楚:单容器、标准编排、简化编排

官方文档在 Docker 单容器那一章开头放了一个醒目提示,态度非常明确:强烈建议使用 Docker Compose 安装方式,而不是手动启动 Docker 容器;理由是 Compose 在配置管理、服务编排和部署体验上都更好。

但官方同时又在 Compose 配置指南里给了两份编排文件:

  • 标准配置,官方标注”推荐用于生产环境”,包含网关本体、PostgreSQL、Redis 三个服务,另外把 MySQL 以注释形式留成备选(ClickHouse 不在这份里,它出现在仓库那份编排文件中)
  • 简化配置,官方标注”适合测试”,整份文件只有一个 new-api 服务,环境变量只留时区,卷只挂一个数据目录

这三种形态的分界线其实是你需不需要独立的数据库和缓存。简化编排跑起来会落到默认的 SQLite 上;标准编排则把数据库拆成独立服务。官方在数据库选型上的口径是一致的:生产优先 PostgreSQL,MySQL 保持兼容可用,SQLite 适合本地评估和临时测试。

如果你要从标准编排切到 MySQL,官方在文件头部写清楚了四步:注释掉 postgres 服务和那行 PostgreSQL 的 SQL_DSN、取消注释 mysql 服务和对应的 MySQL SQL_DSN、在 depends_on 里取消注释 mysql、在 volumes 段落里取消注释 mysql_data。四处漏一处都起不来,这也是为什么官方要把它写成一份带行号的操作清单。

镜像:名字、标签,以及升级回滚都靠它

官方编排文件和单容器命令里用的镜像名都是 calciumion/new-api:latest

这里有个容易让人愣一下的地方:镜像名和仓库路径并不同名。仓库是 QuantumNous/new-api,镜像是 calciumion/new-api。不必纠结,按官方给的镜像名写就是了,不要自己按仓库路径去拼一个镜像名。

latest 标签意味着每次 pull 都会拿到当前最新版本。官方在系统更新指南里给出的升级路径,本质上就是”换一次镜像再重建容器”:

# Docker Compose 部署的更新
docker compose pull
docker compose down
docker compose up -d

官方也给了更简洁的一行写法,把三条串起来。而单容器部署的更新要麻烦一些——拉镜像、停容器、删容器、再用同样的参数重新 run 一遍。官方在这一步专门加了警告:启动新容器时必须使用与原容器相同的参数,尤其是数据卷挂载和环境变量配置。这句警告的分量在于,单容器路线下这些参数只存在于你当初敲的那条命令里,没有文件记录,隔几个月再来升级很容易漏掉一两项。这也是官方推荐 Compose 的现实理由之一:配置沉淀在文件里,升级时不需要凭记忆重建。

回滚同理。官方给的回滚做法是拉一个带具体版本号标签的镜像(形如 calciumion/new-api:v1.x.x),停掉并删除当前容器,再用旧版本镜像重新创建。因为数据在卷里,容器本身是可替换的——这正是持久化写对了才有的底气。

官方还给了更新前后的两份清单。更新前:备份数据库和重要配置文件、查看 GitHub Releases 上的更新内容、确认新版本与你现有的集成和自定义配置兼容、挑一个低峰时段。更新后:确认能正常登录管理界面、检查系统日志有无报错、测试若干 API 调用、确认数据库结构更新成功、检查各渠道连接状态。

编排文件到底编排了什么

标准编排里 new-api 这个服务的字段,官方给了一张逐项说明表:image 指定镜像、container_name 自定义容器名、restart 官方建议设为自动重启、command 自定义启动参数、ports 默认把容器端口映射到宿主同名端口、volumes 做数据持久化、environment 配置行为、depends_on 保证启动顺序、healthcheck 监控服务状态。

其中两项值得单独说。

command 不是摆设。 两份编排里它的值都是把日志目录指到容器内的一个路径,而这个路径恰好又被下面的 volumes 挂了出来——两者是配套的。只改一边,日志要么写进容器里随删随丢,要么挂了个空目录出来。

healthcheck 用的是网关自己的状态接口。 官方的检查命令是请求容器内的 /api/status,然后在返回里抓 success 字段是否为真,抓不到就退出非零:

healthcheck:
  test: ["CMD-SHELL", "wget -q -O - http://localhost:3000/api/status | grep -o '\"success\":\\s*true' || exit 1"]

后面还跟着检测间隔、单次超时、判定失败前重试次数三个参数,具体取值以你手上那份文件为准。这个写法有个实际用处:它验证的是应用层是否真的健康,而不只是端口有没有监听。端口通了但数据库连不上的状态,用端口探活是发现不了的。

仓库里的那份和文档里的那份,不一样

这是本文最需要提醒的一条:别把文档里贴的”标准配置”当成仓库里 docker-compose.yml 的原样复制。把两份文件放在一起对照,至少有这些差异:

  • 仓库版定义了一个 bridge 类型的自定义网络,并把所有服务都放了进去;文档版没有 networks 段落
  • 仓库版给 Redis 设了访问密码,连接串里也带上了凭证;文档版的 Redis 服务没有鉴权,连接串是最简形式
  • 仓库版显式写了错误日志开关、批量更新开关和节点名,其中节点名官方注明是用于在审计日志里标识节点身份、多节点或多容器部署时建议设置
  • 两份都把日志目录挂了出来并配了对应的启动参数(这一项两边一致,不是差异)
  • 仓库版以注释形式预留了 ClickHouse 作为独立日志库的选项,以及一批会话安全、可信代理相关的变量;文档版只留了少数几项

★ 更要注意的是默认值口径:官方环境变量文档的表格里,错误日志和批量更新这两个开关在不配置时是关闭的(默认值以官方文档当前版本为准),而两份编排文件都把它们显式写成了开启。所以别拿文档里的默认值去倒推你实际跑起来的行为——你跑的是编排文件里那份显式值。这类地方不要凭印象判断,直接看你手上文件里有没有写那一行。

数据持久化:三个落点,两种挂载写法

这是 Docker 部署最容易一笔带过、事后最难补救的部分。官方那份标准编排里,需要活过容器生命周期的数据其实分布在三处:

  1. 应用数据目录——网关自身的数据,挂载写法是把宿主当前目录下的一个文件夹映射进容器的数据路径
  2. 日志目录——与前面说的启动参数配套,同样映射到宿主目录
  3. 数据库数据目录——PostgreSQL 服务把它的数据路径挂到了一个命名卷上;如果换成 MySQL,官方注释里对应的是另一个命名卷

前两处用的是宿主路径映射,第三处用的是 Docker 命名卷。区别在于,前者的位置由你写在编排文件里的相对或绝对路径决定,后者由 Docker 自己管理。官方在单容器命令的说明里专门提示过:请把示例里的数据路径替换成你自己希望用来存放数据的本地路径。用相对路径的隐患是它依赖你执行命令时所在的目录,长期服务更建议用绝对路径,避免哪天在别的目录下敲了一次命令就写到了意外的位置。

数据库这一侧还有两个官方明确给出的选项,都跟”数据放哪”有关:

  • LOG_SQL_DSN:给日志表单独指定一个数据库连接串。官方对这一项的说明只有「给日志表单独指定数据库连接串」,至于什么场景下值得拆,官方文档没有展开
  • ClickHouse 作为日志库:仓库版编排里以注释形式给了一个 ClickHouse 的连接串写法,并配了一个日志保留天数的变量。官方注释说明:不设置或设为 0 表示关闭自动删除,设成具体天数则按天保留

另外,未设置 SQL_DSN 时系统会落到 SQLite,路径可以用 SQLITE_PATH 覆盖。测试阶段这样最省事,但它意味着你的全部数据都在挂载目录里的一个文件上——卷没挂对,删容器就等于删库

上生产前:默认密码和端口暴露

官方在编排文件头部用了一条醒目提示,要求在部署到生产环境之前更改所有默认密码。这条提示在文件里还被重复标注在每一处出现密码的位置:网关的数据库连接串、Redis 的启动参数、PostgreSQL 服务的密码变量,以及注释中的 MySQL 和 ClickHouse 服务。所以贴配置的时候不要照搬这一类字段:

environment:
  - SQL_DSN=postgresql://root:<改成你自己的强密码>@postgres:5432/new-api
  - REDIS_CONN_STRING=redis://:<改成你自己的强密码>@redis:6379
  - TZ=Asia/Shanghai

官方原文在这两处给的都是示例密码,且都紧跟着一句”生产环境务必修改”。数据库名同理,按你自己的命名规划改就行。

端口暴露是另一个容易被忽略的点。官方编排里,PostgreSQL 和 MySQL 的 ports 段落默认是注释掉的,注释文字写的是”如果你需要从 Docker 外部访问才取消注释”。这个默认值本身就是一条安全建议:同一个 Compose 网络内的服务之间靠服务名互相访问就够了,把数据库端口映射到宿主机等于给它开了一个对外的入口。ClickHouse 的两个端口同理。

会话与代理相关的几个变量也属于这一类。官方文档给了一条很硬的规则:会话密钥不能设置成官方示例里那个占位字符串,否则程序会拒绝启动;多机部署时所有节点必须使用同一个会话密钥。另有可信代理变量,官方说明是:不配置时会信任回环地址、私网地址并打印启动告警,填 none 为严格模式,填显式列表则完全替代默认值。凭证与密钥的管理思路,可以参考API 密钥安全管理那篇的通用做法。

多节点时,编排文件要改哪几行

官方给的主从两份编排片段,差异集中在几处:从节点的宿主端口映射换一个(容器内端口不变)、数据目录换一个、节点类型标成从节点。(前端基础地址这一项出自官方另一处多机部署的环境变量样例,不在这两份片段里。)而必须保持一致的是数据库连接串和会话密钥——官方明确写了两个节点必须指向同一个数据库、用同一个会话密钥;共享 Redis 时,缓存键的 HMAC 密钥也必须一致。

Redis 拓扑官方列了三种,各自的后果不同:

  • 共享 Redis:所有节点用同一个连接串和一致的密钥,会话吊销通常即时生效,限流配额在节点间共享
  • 每节点独立 Redis:会话状态回落到数据库,在同步频率决定的窗口内收敛;限流配额按节点各算,集群整体的放行量可能随节点数放大
  • 不用 Redis:会话校验直接读共享数据库,每个节点用各自的内存限流器

三种模式下数据库都是会话状态的权威来源。官方还提到一个细节:使用独立 Redis 时,刚轮换过的访问凭证在收敛窗口内可能会短暂收到 401。另外,连接串只接受一个 Redis 兼容端点,官方明确说明它不会原生解析 Redis 集群或哨兵的节点列表,要做高可用得用能对外暴露单一端点的托管服务或代理。

多节点的更新顺序官方也定死了:先更新主节点,因为只有主节点会执行数据库结构迁移;确认主节点启动日志正常、服务稳定之后,再逐个更新从节点。顺序反了,从节点可能在新代码遇上旧表结构。

最后几句

Docker 部署 NewAPI 真正需要你动脑的只有三件事:镜像标签决定你升级和回滚有多顺手,编排文件决定你的配置是沉淀在文件里还是散在命令历史里,数据卷决定你删容器的时候手会不会抖。

还有一个和编排无关但值得提前知道的变量:官方对中转请求超时那个变量给了警告,说设得太短可能出现上游已经完成请求并计费、而本地因超时未能完成计费的情况,导致账务不一致;官方的建议是除非清楚自己在做什么,否则不要动它。自建网关之后怎么把各方用量和费用管起来,可以看API 成本监控;自建这条路线整体的安全面,API 中转的安全考量那篇讨论得更全。

想系统学会用 AI?报名体系课或加入会员,照着学、照着用。

留言讨论

评论发布后会被人工复核,违规内容将被删除。

    还没有人评论,来说说你的看法

    如果发表没有反应,可以前往联系我们告诉我们。

    这个页面有问题?

    提交时会附带当前页面地址和浏览器信息,帮助我们定位问题。不填联系方式即为匿名。