直接聊结论:New-API 是目前管理 AI 大模型接口绕不开的一个开源项目。它把 OpenAI、Claude、Gemini、DeepSeek、智谱、通义这类几十家模型渠道集中到一个面板里统一管理,你要做的只是在后台添加渠道、生成令牌,然后所有客户端拿着同一个 base_url 和一个令牌去请求就行。不用再每个项目单独配 Key,额度、倍率、日志、分组全都能在一个界面里看明白。
这篇文章不扯虚的,专门讲怎么把 New-API 跑起来。默认你至少听过 Docker,但不要求精通。我会把在线和离线两套方案完整写出来,包括 MySQL 的配置细节、docker-compose 怎么写、镜像怎么导出导入、内网机器怎么装、渠道和令牌怎么配,最后附上我踩过的坑和排查思路。无论是自己折腾玩,还是帮公司内网搭一套统一网关,这篇文章都够用。
1. 先搞清楚 New-API 到底在解决什么问题
1.1 一句话解释 New-API 是什么
New-API 是开源项目 one-api 的一个深度二次开发分支,本质上是一个 API 网关加管理系统。你手头可能有好几个模型平台的 Key,比如 OpenAI 的、Claude 的、国产模型的,分散在各个账号里。开发的时候每种模型都要单独接 SDK,测试的时候每个 Key 都要单独配环境变量,对账的时候更是全靠手工,非常痛苦。
New-API 的做法很直接:把后端所有渠道统一接进来,对外只暴露一个 OpenAI 兼容接口。也就是说,不管你后端接的是哪家模型,客户端永远只需要知道一个地址加一个令牌。这个思路相当于给所有模型接口装了一个交换机,所有请求先到交换机,再由它转发到真正的上游渠道。
1.2 部署方案选型:为什么是 Docker + MySQL
New-API 本身是个 Go 项目,发布物是一个单一二进制文件,理论上直接跑二进制也能启动。但实际部署我几乎无脑选 Docker,原因有三点。
第一,环境隔离。Go 项目虽然静态编译,但跑起来还是要考虑系统依赖、端口占用、日志目录权限这些问题。Docker 容器里面一把梭,宿主机只需要有 Docker 环境。
第二,版本管理方便。镜像标签对应版本号,升级就是拉新镜像重启容器,回滚就是重新指定旧标签。这对生产环境来说太重要了,我在线上升级翻车过,直接改回旧镜像秒恢复。
第三,离线部署友好。内网机器不能访问公网的情况下,二进制方案需要手动带上一堆依赖,Docker 镜像只需要 docker save 带进去即可,后面第三节单独讲。
数据库选型这里要稍微展开一下。New-API 默认支持 SQLite,单机自己玩直接 SQLite 足够。但只要是正经使用场景,比如多个人共用、数据量大、需要定时备份,我建议一步到位上 MySQL。原因也很现实:SQLite 在并发写入时会有锁竞争,日志表数据量大了之后读写都会变慢,而且备份恢复不方便。MySQL 8.0 用 Docker 启动也就一两分钟的事,没有理由不选。
我遇到过一些朋友图省事直接 SQLite,结果跑了一个月,请求日志几万条,后台页面打开都有延迟。换 MySQL 之后体感完全不一样。所以这篇文章的默认方案就是 MySQL 8.0 + New-API 最新稳定版,两个容器通过 Docker Compose 统一编排。
2. 在线环境部署:从拉取镜像到首次启动
2.1 部署前的环境检查清单
在线部署看着简单,但很多人一上来就 docker compose up -d,然后报一堆错,其实大部分问题出在准备工作上。我建议先把以下三项检查做完再动手。
Docker 版本。New-API 镜像基于 Linux 容器,对 Docker 版本要求不高,但 Docker Compose 插件请确保存在。新版 Docker Desktop 默认自带 compose 插件,可以用 docker compose version 确认。如果是老版本,可能需要单独安装 docker-compose。
端口占用情况。New-API 默认监听 3000 端口,MySQL 默认 3306 端口。这两个端口如果被其他程序占了,容器会起不来或者端口映射失败。启动之前先跑一下:
lsof -i :3000 lsof -i :3306如果有输出,说明端口被占用,需要先停掉对应进程,或者后面改端口映射。
磁盘空间。镜像本身加起来一两个 GB,MySQL 的数据文件会随使用时间增长,日志表如果开了记录功能增长更快。建议至少预留 20GB 空间,避免运行两个月后磁盘写满导致 MySQL 崩溃。这个坑我踩过,磁盘满了之后 MySQL 容器直接进入只读模式,查了半天才发现是硬盘满了。
2.2 编写 docker-compose.yml:每个参数都说清楚
新建一个工作目录,比如 ~/new-api,在里面创建 docker-compose.yml。下面这份配置我实测可跑,直接抄作业没问题:
version: '3.8' services: mysql: image: mysql:8.0 container_name: newapi-mysql restart: always environment: MYSQL_ROOT_PASSWORD: change_me_root_password MYSQL_DATABASE: newapi MYSQL_USER: newapi MYSQL_PASSWORD: change_me_db_password volumes: - ./mysql-data:/var/lib/mysql ports: - "3306:3306" command: --default-authentication-plugin=mysql_native_password new-api: image: calciumion/new-api:latest container_name: new-api restart: always depends_on: - mysql environment: SQL_DSN: "newapi:change_me_db_password@tcp(mysql:3306)/newapi?charset=utf8mb4&parseTime=True&loc=Local" TZ: Asia/Shanghai ports: - "3000:3000" volumes: - ./new-api-logs:/app/logs这里有几个关键点需要解释清楚。
SQL_DSN 是 New-API 连接 MySQL 的核心配置,格式是 用户名:密码@tcp(数据库容器名:端口)/数据库名?参数。其中 mysql 不是 IP,而是 Docker Compose 网络内的服务名,Compose 会自动做 DNS 解析,所以 new-api 容器里可以直接通过 mysql 这个主机名连到 MySQL 容器。如果你手动分开启动容器,这个位置就要改成 MySQL 所在机器的 IP。
charset=utf8mb4 必须保留。MySQL 8 默认字符集虽然是 utf8mb4,但连接串里显式指定可以避免某些驱动默认使用 latin1 导致中文和 emoji 乱码。AI 接口返回的内容里经常有各种特殊符号,这一行省掉后面必定后悔。
default-authentication-plugin=mysql_native_password 是给 MySQL 8.0 加的兼容参数。MySQL 8 默认的 caching_sha2_password 认证方式在部分旧版客户端和驱动下会有兼容问题,显式指定 native 认证最省心。如果你用 MySQL 5.7,这一行不需要加。
端口映射这里,3306 端口要不要暴露给宿主机需要想清楚。如果只是 New-API 容器内部连数据库,其实不需要映射 3306,可以把 ports 删掉只留 internal。但为了方便用 Navicat 之类的工具连进去看数据、排查问题,我建议还是暴露出来,生产环境再按需收紧。
2.3 启动容器并验证服务状态
配置写好之后,切换到 docker-compose.yml 所在目录执行:
docker compose up -d第一次执行会拉取两个镜像,网络正常情况下几分钟内完成。之后用 docker compose ps 查看状态,两个容器都应该是 Up 状态。接着验证 New-API 是否正常监听:
curl http://localhost:3000/api/status如果返回一段 JSON,里面有 success 和 version 字段,说明服务已经起来了。此时打开浏览器访问 http://服务器IP:3000,会看到 New-API 的登录页面。第一次访问时页面会提示注册,第一个注册的账号会自动成为管理员。这一步很多人忽略,以为注册完就是个普通用户,后来要改系统设置找不到入口。务必记住:第一个注册的人就是管理员。
MySQL 这边的验证也很重要,不要等到日志写满才发现连不上。进入容器确认数据库和账号是否正常:
docker exec -it newapi-mysql mysql -unewapi -pchange_me_db_password -e "SHOW DATABASES;"能看到 newapi 这个库就说明数据库侧没问题。到这里在线部署的核心流程已经走完,比想象中简单。
3. 离线环境部署:内网机器也能一键跑起来
3.1 离线部署的整体思路
内网部署最大的问题是环境隔离,机器不能访问外网,docker pull 拉不了镜像,docker compose up 直接卡死在拉取阶段。但思路其实很简单:在一台能联网的机器上把需要的镜像和安装包全部准备好,再通过 U 盘或内网文件服务器拷贝到目标机器上。具体要准备三样东西:New-API 镜像、MySQL 镜像、Docker 安装包。如果你是 Windows 内网机器,可能还要准备 Docker Desktop 安装包。
离线环境里最先要解决的问题不是镜像,而是 Docker 本身。目标机器没有 Docker 的话,镜像再齐全也白搭。
3.2 在联网机器上导出镜像和下载安装包
先准备镜像文件。在任意一台能联网、装有 Docker 的机器上执行:
docker pull mysql:8.0 docker pull calciumion/new-api:latest docker save -o mysql-8.0.tar mysql:8.0 docker save -o new-api.tar calciumion/new-api:latest这里有个细节:docker save 和 docker export 的区别。save 保存的是镜像的完整结构,包括层信息、标签、启动配置,load 回来之后可以直接用原标签启动。export 是导出容器的文件系统,相当于把运行中的容器打包成一个普通文件,load 回来还需要手动配置启动参数。离线部署一定要用 save + load,不要用 export。
Docker 安装包方面,Linux 机器建议下载官方静态二进制包,比如 docker-27.x.x.tgz,解压后放到 /usr/local/bin 就能用,不依赖系统包管理器。Ubuntu/Debian 机器也可以下载对应的 deb 包,但静态二进制更省事,一个包拷贝过去解压就行。
如果目标机器是 Windows,情况复杂一些。Docker Desktop 的安装包是 exe 格式,直接拷贝过去双击安装即可。但 Windows 上跑 Docker 依赖 WSL2 或者 Hyper-V,目标机器需要在 BIOS 里开启虚拟化支持。这一步在离线环境里如果没提前确认,很容易卡住。下面会详细说。
3.3 目标机器导入镜像并启动
以常见的内网 Linux 服务器为例。先把 Docker 安装好:
tar -xzf docker-27.x.x.tgz cp docker/* /usr/local/bin/然后启动 Docker 守护进程。用 systemd 管理的机器可以直接写一个 service 文件,或者简单点直接后台执行 dockerd。验证一下:
docker version能正常输出版本号就说明 Docker 环境就绪。
接下来把镜像文件上传到目标机器,执行导入:
docker load -i mysql-8.0.tar docker load -i new-api.tar导入完成后用 docker images 确认两个镜像标签是否正确。镜像没问题之后,把 2.2 节那份 docker-compose.yml 原样拷贝过去,所有的环境变量保持不变,然后 docker compose up -d。
这里要注意一点:离线机器上 Docker Compose 插件可能不存在。如果 docker compose 命令报错,先装 compose 插件,或者直接把两个容器用 docker run 手动启动。手动启动的命令如下,效果和 compose 一样:
docker network create newapi-network docker run -d --name newapi-mysql \ --network newapi-network \ -e MYSQL_ROOT_PASSWORD=change_me_root_password \ -e MYSQL_DATABASE=newapi \ -e MYSQL_USER=newapi \ -e MYSQL_PASSWORD=change_me_db_password \ -v $(pwd)/mysql-data:/var/lib/mysql \ --restart always \ mysql:8.0 --default-authentication-plugin=mysql_native_password docker run -d --name new-api \ --network newapi-network \ -e SQL_DSN="newapi:change_me_db_password@tcp(newapi-mysql:3306)/newapi?charset=utf8mb4&parseTime=True&loc=Local" \ -e TZ=Asia/Shanghai \ -p 3000:3000 \ -v $(pwd)/new-api-logs:/app/logs \ --restart always \ calciumion/new-api:latest注意网络一定要自己创建并把两个容器放到同一个网络里,否则 new-api 容器解析不到 newapi-mysql 这个主机名。
Windows 离线部署多说一句。安装 Docker Desktop 时如果提示 virtualization support not detected,先重启进 BIOS 打开 Intel VT-x 或 AMD-V。有些办公电脑出厂默认关闭虚拟化,这是离线部署最常见的卡点。另外 Docker Desktop 首次启动会初始化 WSL2 内核,这个组件在离线环境也需要提前下载好 wsl_update_x64.msi 并安装,否则 Docker Desktop 会一直卡在 starting 界面。
3.4 离线环境下的版本选择和依赖陷阱
离线部署有个容易被忽略的问题:镜像版本一旦固定,后面想升级就得重新走一遍 save 和 load 流程。所以离线环境一定要选择稳定的版本,不要用 latest 标签。latest 是指向最新版的动态标签,你在一台机器上 pull 到的 latest 和另一台机器上 pull 到的可能是不同版本,这会导致离线环境复现困难。
建议的做法是在联网机器上先 docker images 查看镜像的完整 ID,然后再 docker tag 打一个明确版本的标签:
docker tag calciumion/new-api:latest calciumion/new-api:v0.1.0 docker save -o new-api-v0.1.0.tar calciumion/new-api:v0.1.0这样离线机器上导入的镜像就有明确的版本号标记,后续排查问题也知道自己在跑哪个版本。
另外要注意,MySQL 镜像的数据目录版本敏感。同一套 mysql-data 目录在 MySQL 8.0 不同小版本之间基本能兼容,但如果你原来用的是 MySQL 5.7,想升级到 8.0,直接挂载旧数据目录会报错。离线升级数据库这类操作一定要先备份数据,再用 mysqldump 导出再导入,不要直接替换数据目录。
4. 初始化配置:渠道、令牌、模型一个都不能少
4.1 登录后台先做这三件事
部署完成后打开浏览器进入后台,第一步是注册管理员账号。注意,这个页面的注册不像普通网站是开放给所有人的,第一个注册的账号自动成为管理员,拥有全部权限。我用 New-API 搭建过好几个环境,这个坑几乎每次都有人踩:注册完发现自己是普通用户,后台很多菜单看不到,必须手动修改数据库或重新部署才能解决。
登录进去之后先不要急着加渠道,按顺序处理以下几项。第一,在"设置-运营设置"里修改系统名称和站点地址,站点地址影响分享链接和部分回调功能。第二,在"设置-模型设置"里确认是否启用模型映射,默认值按需调整。第三,顺手把系统管理员的密码改掉或者绑定邮箱,避免初始密码遗忘导致进不去后台。
注意:如果是内网部署,站点地址建议直接写内网访问地址,比如 http://192.168.1.100:3000。写公网地址反而会让后端生成的链接在内网环境不可访问。
4.2 添加渠道:以 OpenAI 兼容接口为例
这是核心操作。点击左侧"渠道"菜单,然后"添加渠道",会看到一个渠道配置表单。以国内最常见的 OpenAI 兼容第三方平台为例:
- 类型选 "OpenAI"
- 名称随便填,比如"某某中转"
- 代理地址填第三方平台提供的 base_url,注意结尾不要带 /v1
- 密钥填你在第三方平台申请的 API Key
- 模型列表填该渠道支持的模型名,逗号分隔,比如 gpt-4o,gpt-4o-mini,claude-3-5-sonnet
填写完之后点"测试",系统会发一个测试请求过去。如果返回正常,说明渠道连通。如果测试失败,大概率是以下三个原因:代理地址格式不对,尾部多了 /v1;密钥里带了多余的空格或其他不可见字符;模型名和渠道侧实际支持的名称不一致。
我自己在配渠道时踩过最典型的坑是代理地址问题。有些平台文档里写的是 https://api.xxx.com/v1,New-API 表单里也要求填 base_url,不填 /v1,两者叠加导致请求路径变成 https://api.xxx.com/v1/v1/chat/completions,必然 404。理解了这个机制,以后不管对接什么平台都不会再犯。
4.3 创建令牌并接入客户端
渠道配好后,还要创建一个令牌才能真正对外提供服务。在"令牌"菜单里"添加令牌",设置好额度倍率,比如 1 表示按原价 1 倍计费,不限模型的话模型倍数留空即可。令牌生成之后会显示一串 sk- 开头的字符串,这个就是客户端要用的 API Key。
客户端接入时,base_url 填写 New-API 的地址加 /v1,比如 http://192.168.1.100:3000/v1,api_key 填写刚才生成的令牌。以 Python 的 openai 库为例:
from openai import OpenAI client = OpenAI( api_key="sk-你的令牌", base_url="http://192.168.1.100:3000/v1" ) resp = client.chat.completions.create( model="gpt-4o", messages=[{"role": "user", "content": "你好"}] ) print(resp.choices[0].message.content)请求发出后,去 New-API 后台的"日志"菜单里查看记录。能看到请求详情、消耗额度、响应耗时,说明整条链路已经打通。到这一步,New-API 的核心部署和接入流程就算真正完成了。
5. 常见问题与排查技巧实录
5.1 容器一直重启,日志刷屏
新部署的环境最常见的问题就是 new-api 容器起来了又挂,循环重启。先看日志:
docker logs new-api --tail 200如果日志里出现 failed to connect to database 或 access denied,说明 SQL_DSN 连接串有问题。重点检查数据库密码是否正确、MySQL 容器是否有 newapi 这个库、用户名是否有权限。如果想快速验证,可以进 MySQL 容器手动用连接串里的账号密码登录一下,能登录说明数据库侧没问题,问题大概率出在环境变量转义上。
SQL_DSN 里密码如果包含特殊字符,比如 @、:、/ 等,需要做 URL 编码,否则连接串解析会错位。我建议部署时直接用纯字母数字的密码,省去转义的麻烦。数据库密码这种内部系统的密码,也没有必要设置过分复杂,不暴露公网就行。
5.2 日志表增长过快导致数据库膨胀
New-API 默认会记录所有请求日志,高并发环境下日志表增长非常快。我跑过一个日请求量上万的环境,没做任何处理,一个月后数据库占了 40 多 GB。后台"设置-日志设置"里可以配置日志保留天数,建议按需设置 7 到 30 天,把超期日志自动清理打开。
如果日志已经膨胀得很厉害,可以直接去 MySQL 里手动清理:
docker exec -it newapi-mysql mysql -unewapi -pchange_me_db_password newapi -e "DELETE FROM logs WHERE created_at < DATE_SUB(NOW(), INTERVAL 7 DAY);"清理之后执行 OPTIMIZE TABLE logs 释放表空间。这个操作在线环境不会有太大影响,但建议在低峰期执行。
5.3 渠道测试通过但客户端请求报 404
这个问题的根源几乎都是 base_url 路径不对。客户端请求经历的过程是:客户端访问 New-API 的 /v1/chat/completions,New-API 再请求上游渠道的对应路径。如果客户端 base_url 写成了 http://ip:3000(没带 /v1),请求会打到 New-API 的根路径,而不是 OpenAI 兼容接口路径,自然 404。
另外,如果你用的是 One API 生态的其他客户端,比如某些开源前端项目,注意区分它期望的 base_url 是带 /v1 还是不带。以 New-API 为例,兼容 OpenAI 协议的统一都是 base_url 加 /v1。这一条记住就不用反复试错了。
5.4 问题排查速查表
| 现象 | 可能原因 | 处理方式 |
|---|---|---|
| 容器一直重启 | SQL_DSN 连接串错误 | 检查密码、数据库名、特殊字符转义 |
| 端口无法访问 | 容器没起来或端口映射不对 | docker compose ps 查看状态;宿主机防火墙放行 3000 |
| 后台日志空白 | 渠道配置错误或密钥无效 | 渠道页点测试,看具体报错信息 |
| 请求报 401 | 令牌错误或已过期 | 重新生成令牌,确认客户端填的是令牌而非渠道密钥 |
| 数据库连接超时 | MySQL 容器内存不足 | 查看 docker stats,增加宿主机内存或限制 MySQL 内存参数 |
| 页面加载慢 | 请求日志表过大 | 清理日志,配置自动留存天数 |
| 离线导入镜像报错 | 用的是 export 导出文件 | 必须用 docker save + docker load |
5.5 容器内时区问题的处理
部署在内网或云服务器上,如果宿主机的时区不是 Asia/Shanghai,New-API 后台显示的时间可能跟本地时间差好几个小时。解决方式就是 compose 文件里那两个环境变量 TZ=Asia/Shanghai 和 MySQL 连接串里的 loc=Local,缺一不可。MySQL 容器里也需要同步设置时区,可以在 environment 里加 TZ=Asia/Shanghai,或者在 MySQL 配置里指定 default-time-zone = '+08:00'。
5.6 Docker 侧的内存和重启策略
New-API 作为常驻服务,restart: always 是必须的,否则机器重启后服务不会自动拉起。内存方面,New-API 本身占用很小,200MB 以内,但 MySQL 8.0 默认内存占用偏大,1G 内存的小机器跑起来会有点吃力。如果 VPS 内存只有 1G,建议给 MySQL 容器加内存限制:
deploy: resources: limits: memory: 512M不过要注意,限制过小会导致 MySQL 频繁 OOM。生产环境优先保证 2G 以上内存,小内存机器能用但体验不好。
最后分享一个我的习惯:每次配置文件改完、容器启动成功之后,先把 docker-compose.yml 复制一份到备份目录。这个文件本身就是项目的一个核心交付物,丢了就得重新回忆所有配置。另外 MySQL 数据目录 mysql-data 也建议定期压缩备份,用 cron 脚本每天打一次 tar 包,成本很低,但崩溃恢复时能救命。踩过几次数据目录损坏的坑之后,我才意识到,配置文件和数据的备份,和大模型网关本身一样重要。