FastGPT从开发到上线:一站式Docker化部署实战
1. 环境准备:为什么选择Docker全家桶?
如果你和我一样,是个喜欢折腾的开发者,肯定遇到过这种头疼事:在本地电脑上跑得好好的项目,一搬到服务器上就各种报错,数据库连不上、依赖版本冲突、环境变量不对…… 光是排查问题就能耗掉大半天。我之前部署一个稍微复杂点的Node.js应用就吃过这个亏,本地是Node 16,服务器是Node 18,一个不起眼的API行为差异就让整个服务挂了。
所以这次搞FastGPT,我铁了心要用Docker。Docker化部署的核心优势,说白了就是环境一致性。你在MacBook上开发用的镜像,和最终在Linux服务器上跑的镜像,是完全一样的。这就像你把整个应用,连同它需要的所有“家具”(数据库、运行时、配置文件),一起打包进了一个标准集装箱里。无论是在本地码头(开发机)还是远洋货轮(生产服务器),这个集装箱里的东西都不会变。
对于FastGPT这种技术栈比较丰富的项目(MySQL、MongoDB、PostgreSQL with pgvector、Node.js、OneAPI),Docker Compose更是神器。它让你用一个docker-compose.yml文件,就能定义和运行所有这些相互依赖的服务。你不用再手动一个个去安装、配置、启动,Compose帮你把网络打通、把依赖关系理清。开发的时候,一条命令就能拉起全套环境;上线的时候,几乎可以把同样的Compose文件(稍作调整)直接搬到服务器上。
在开始动手之前,你需要确保本地已经装好了这两样东西:
- Docker Engine:这是核心的容器运行时。去Docker官网下载对应你操作系统(Windows/macOS/Linux)的Docker Desktop安装就行,它自带Docker Compose。
- Git:用来拉取FastGPT的源代码。
你可以打开终端,用下面这两条命令验证一下安装是否成功:
docker --version
docker-compose --version
如果都能正确输出版本号,那么恭喜你,你的“造船厂”已经准备就绪,可以开始打造我们的FastGPT集装箱了。
2. 数据库先行:用Docker Compose搭建稳固的数据基石
数据库是任何应用的“记忆中枢”,FastGPT也不例外。它用到了三种数据库:MySQL给OneAPI用,MongoDB存储核心的业务数据,PostgreSQL(搭配pgvector扩展)则专门处理向量数据,用于AI模型的语义搜索。在Docker的世界里,我们第一步就是为这些数据库创建独立的、隔离的运行环境。
2.1 创建专属的Docker网络
首先,我们需要创建一个自定义的Docker网络,我习惯命名为fastgpt。这个网络就像一个私有的局域网,所有后续创建的数据库、OneAPI、FastGPT服务容器都会接入这个网络。在这个网络里,容器之间可以通过容器名称直接互相访问,比如FastGPT容器里配置MongoDB连接地址,直接写mongo:27017就能通,非常方便,也避免了端口冲突的麻烦。
创建网络的命令很简单:
docker network create fastgpt
执行后,你可以用docker network ls查看,应该能看到一个名为fastgpt的网络。
2.2 编写并启动数据库的Compose文件
接下来是重头戏,编写docker-compose-db.yml文件。我把这个文件的内容和关键解释放在下面,你可以直接复制保存。这里我选择使用Docker Hub的官方镜像,如果你在国内访问Docker Hub慢,可以把image那行注释掉,使用下面阿里云镜像加速地址的注释行,速度会快很多。
version: '3.3'
services:
mysql:
image: mysql:8.0.36
container_name: mysql
restart: always
ports:
- "3307:3306" # 主机端口3307映射到容器内3306,避免和本地可能已有的MySQL冲突
networks:
- fastgpt
command: --default-authentication-plugin=mysql_native_password
environment:
MYSQL_ROOT_PASSWORD: oneapimmysql # 初始root密码,务必记牢或修改
MYSQL_DATABASE: oneapi # 自动创建名为oneapi的数据库
volumes:
- ./mysql_data:/var/lib/mysql # 数据持久化到本地mysql_data目录
mongo:
image: mongo:5.0.18
container_name: mongo
restart: always
ports:
- "27017:27017"
networks:
- fastgpt
command: mongod --keyFile /data/mongodb.key --replSet rs0 # 以副本集模式启动,这是FastGPT的要求
environment:
MONGO_INITDB_ROOT_USERNAME: myusername
MONGO_INITDB_ROOT_PASSWORD: mypassword
volumes:
- ./mongo_data:/data/db
- ./mongo_init.js:/docker-entrypoint-initdb.d/mongo_init.js:ro # 初始化脚本
# 注意:生产环境强烈建议把端口映射去掉,仅通过内部网络访问,更安全。
pg:
image: pgvector/pgvector:0.7.0-pg15 # 这个镜像已经包含了pgvector扩展
container_name: pg
restart: always
ports:
- "5432:5432"
networks:
- fastgpt
environment:
POSTGRES_USER: username
POSTGRES_PASSWORD: password
POSTGRES_DB: postgres
volumes:
- ./pg_data:/var/lib/postgresql/data
networks:
fastgpt:
external: true # 使用我们之前创建的外部网络
这里有几个坑我提前帮你踩了:
- MongoDB副本集:FastGPT要求MongoDB以副本集模式运行,哪怕你是单机。上面配置里的
command参数和初始化脚本就是为了搞定这个。你需要额外创建一个mongo_init.js文件,内容如下:
这个文件会被MongoDB容器在首次启动时自动执行,完成副本集初始化。rs.initiate({ _id: "rs0", members: [ { _id: 0, host: "mongo:27017" } ] }) - 连接字符串参数:这是个大坑!当你的应用(比如本地开发的FastGPT)在Docker网络外部连接这个MongoDB时,必须在连接字符串末尾加上
?authSource=admin&directConnection=true。directConnection=true这个参数对于连接单节点副本集至关重要,不加的话Node.js驱动可能会报连接错误。 - 数据持久化:留意每个服务下面的
volumes配置,比如./mysql_data:/var/lib/mysql。这会把容器内的数据库文件保存到你当前目录下的mysql_data文件夹里。这样即使你删除了容器,数据也不会丢失。第一次启动前,记得先创建这些目录(mkdir mysql_data mongo_data pg_data)。
文件准备好后,在终端进入该文件所在目录,执行:
docker-compose -f docker-compose-db.yml up -d
-d参数是让它们在后台运行。用docker ps命令检查一下,应该能看到mysql、mongo、pg三个容器都处于“Up”状态。到这一步,你的数据基石就稳稳地打好了。
3. 本地开发:在Docker庇护下愉快地写代码
数据库跑起来了,现在我们可以把注意力放回代码本身。本地开发的目标是获得一个热重载、方便调试的环境,同时又能依赖我们刚部署好的Docker化数据库服务。
3.1 拉取代码与项目结构初探
首先,把FastGPT的代码克隆到本地:
git clone https://github.com/labring/FastGPT
cd FastGPT
项目结构稍微有点复杂,因为它是个Monorepo(多包仓库)。核心的前端和后端代码都在projects/app目录下。我们后续的配置和运行操作,基本都在这个目录里进行。
3.2 关键配置详解:环境变量与配置文件
FastGPT的配置主要通过两个文件管理,它们都在projects/app目录下。
第一个是环境变量文件。你需要复制.env.template为.env.local:
cp .env.template .env.local
然后编辑.env.local。这里面的参数很多,但初期你只需要重点关注和修改以下几项,确保它们和你的Docker数据库配置对上:
# MongoDB连接字符串,格式很重要!
MONGODB_URI=mongodb://myusername:mypassword@localhost:27017/fastgpt?authSource=admin&directConnection=true
# 注意这里主机是localhost,因为你的Node.js应用在宿主机运行,要连接Docker容器内的MongoDB。
# 端口是27017,密码是你之前设置的mypassword。
# PostgreSQL连接字符串
PG_URL=postgresql://username:password@localhost:5432/postgres
# OpenAI API的替代地址,我们先指向即将部署的OneAPI
OPENAI_BASE_URL=http://localhost:3000/v1
# 一个临时的测试Key,部署OneAPI后会修改
CHAT_API_KEY=sk-fastgpt
提示:
MONGODB_URI里的directConnection=true参数再次出现,对于本地开发连接Docker内的MongoDB副本集,这个参数通常是必须的,能避免很多奇怪的超时错误。
第二个是应用配置文件。复制data/config.json为data/config.local.json:
cp data/config.json data/config.local.json
这个文件定义了更多应用行为参数。对于刚开始,你大部分时候不需要动它。但可以了解一下其中两个和性能相关的参数,等应用跑起来后根据服务器情况调整:
systemEnv.vectorMaxProcess:控制向量生成的最大并发进程数。如果你的服务器是2核4G,建议设为10-15。systemEnv.qaMaxProcess:控制QA(问答对)生成的最大并发进程数。systemEnv.pgHNSWEfSearch:PostgreSQL向量索引的EF Search参数,值越大搜索精度越高但越慢,一般保持默认即可。
3.3 安装依赖与启动开发服务器
FastGPT项目使用pnpm作为包管理器,并且提供了自动化安装脚本。在项目根目录执行:
# 如果是Linux/macOS,先给脚本执行权限
chmod -R +x ./scripts/
# 然后运行安装脚本
bash ./scripts/postinstall.sh
这个脚本会遍历根目录、projects和packages下的所有子项目,统一安装依赖。如果脚本执行有问题(比如在Windows的Git Bash里),可以尝试手动安装:
pnpm store prune # 清理一下store
pnpm i # 安装所有依赖
依赖安装是个体力活,可能需要一点时间,喝杯咖啡等待一下。
安装完成后,就可以进入应用目录启动开发服务器了:
cd projects/app
pnpm dev
如果一切顺利,终端会输出编译成功的消息,并提示服务运行在http://localhost:3000(通常是3000端口,具体看输出)。打开浏览器访问这个地址,你应该能看到FastGPT的登录界面。用默认账号root和密码1234(这个密码在后续部署时可以改)试试看能不能登录。到这一步,你的本地开发环境就完全跑通了,可以开始探索和修改代码了。
4. 部署OneAPI:统一管理你的AI模型钥匙
FastGPT本身不产生AI能力,它需要一个“模型网关”来对接OpenAI、文心一言、通义千问等各种大模型。这个网关就是OneAPI。它帮你统一管理各个模型的API Key、设置额度、查看用量,让FastGPT通过一个统一的接口调用所有模型,非常方便。
4.1 编写OneAPI的Compose文件
我们在之前的数据网络里部署OneAPI。创建一个新文件docker-compose-oneapi.yml:
version: '3.3'
services:
oneapi:
container_name: oneapi
image: registry.cn-hangzhou.aliyuncs.com/fastgpt/one-api:v0.6.6 # 使用阿里云镜像加速
ports:
- "3001:3000" # 将容器的3000端口映射到主机的3001端口
networks:
- fastgpt
restart: always
environment:
# 指向我们之前启动的MySQL容器,注意这里用的是容器名`mysql`和内部端口3306
SQL_DSN: root:oneapimmysql@tcp(mysql:3306)/oneapi
# 会话加密密钥,可以改成任意复杂字符串
SESSION_SECRET: oneapisecretkey
# 启用内存缓存提升性能
MEMORY_CACHE_ENABLED: "true"
# 启用批量更新,减少数据库压力
BATCH_UPDATE_ENABLED: "true"
BATCH_UPDATE_INTERVAL: "10"
# 初始的root token,登录后务必修改!
INITIAL_ROOT_TOKEN: fastgpt
volumes:
- ./oneapi_data:/data # 持久化OneAPI的数据
networks:
fastgpt:
external: true
关键点解读:
SQL_DSN:这里连接的是Docker网络内的MySQL服务,所以主机名直接写mysql,端口是容器内的3306。密码oneapimmysql必须和之前启动MySQL容器时设置的MYSQL_ROOT_PASSWORD一致。INITIAL_ROOT_TOKEN:这是你首次登录OneAPI管理后台的“万能钥匙”,非常重要。部署成功后,务必第一时间在管理后台修改它。
4.2 启动与初始化配置
在终端运行:
docker-compose -f docker-compose-oneapi.yml up -d
等待片刻,访问 http://localhost:3001,你应该能看到OneAPI的登录界面。使用默认账号root和密码123456登录。
登录后第一件事,就是去“系统设置”里修改root账号的密码和那个INITIAL_ROOT_TOKEN,这是安全底线。
接着,你需要添加一个“渠道”。点击“渠道”->“添加渠道”,选择你想用的模型供应商,比如OpenAI。在表单里填入:
- 名称:随便起,比如“我的OpenAI”
- 分组:默认
- 模型类型:选择
OpenAI - 密钥:填入你从OpenAI官网获取的
sk-开头的API Key。 - 代理(可选):如果你的服务器访问OpenAI需要代理,可以在这里填写。
- 状态:勾选“自动禁用”和“自动启用”。
保存后,OneAPI会自动测试连接。状态显示为“已启用”就说明渠道添加成功了。
最后,你需要创建一个“令牌”(Token)给FastGPT用。点击“令牌”->“创建令牌”,额度可以设置一个很大的数或者直接不设限(用于测试),然后复制生成的令牌字符串(类似sk-xxx)。这个令牌就是FastGPT调用模型的凭证。
现在,回到你本地FastGPT的.env.local配置文件,把CHAT_API_KEY的值换成你刚刚在OneAPI创建的令牌,把OPENAI_BASE_URL改成http://localhost:3001/v1(注意端口是3001)。重启你的本地FastGPT开发服务器,理论上它现在就能通过OneAPI调用你配置的OpenAI模型了。你可以在FastGPT里创建一个简单的对话应用测试一下。
5. 上线部署:将完整的FastGPT栈迁移到服务器
本地一切都调试完毕后,就该考虑上线了。我们的目标是把这一整套服务(数据库、OneAPI、FastGPT)完整、稳定地部署到线上服务器。这里我提供两种最实用的方案,你可以根据实际情况选择。
5.1 方案一:使用官方镜像快速部署(推荐新手)
这是最简单直接的方式,适合想快速看到效果,或者对Docker镜像构建不熟悉的同学。你只需要在服务器上准备好docker-compose.yml文件,一键启动所有服务。
首先,在服务器上创建一个工作目录,比如/opt/fastgpt,然后把所有必要的配置和文件放进去。最关键的是一个整合的docker-compose-prod.yml文件:
version: '3.3'
services:
mysql:
image: mysql:8.0.36
container_name: mysql-prod
restart: unless-stopped # 生产环境推荐 unless-stopped
# 生产环境建议注释掉ports,不暴露数据库端口到公网,仅通过内部网络访问
# ports:
# - "3306:3306"
networks:
- fastgpt
command: --default-authentication-plugin=mysql_native_password
environment:
MYSQL_ROOT_PASSWORD: your_strong_production_password # 一定要改!
MYSQL_DATABASE: oneapi
volumes:
- /data/mysql:/var/lib/mysql # 建议映射到/data等独立存储目录
# 可添加健康检查
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 10s
timeout: 5s
retries: 3
mongo:
image: mongo:5.0.18
container_name: mongo-prod
restart: unless-stopped
# ports:
# - "27017:27017"
networks:
- fastgpt
command: mongod --keyFile /data/mongodb.key --replSet rs0
environment:
MONGO_INITDB_ROOT_USERNAME: prod_username
MONGO_INITDB_ROOT_PASSWORD: prod_strong_password
volumes:
- /data/mongo:/data/db
- ./mongo_init.js:/docker-entrypoint-initdb.d/mongo_init.js:ro
pg:
image: pgvector/pgvector:0.7.0-pg15
container_name: pg-prod
restart: unless-stopped
# ports:
# - "5432:5432"
networks:
- fastgpt
environment:
POSTGRES_USER: prod_pg_user
POSTGRES_PASSWORD: prod_pg_password
POSTGRES_DB: postgres
volumes:
- /data/pg:/var/lib/postgresql/data
oneapi:
container_name: oneapi-prod
image: registry.cn-hangzhou.aliyuncs.com/fastgpt/one-api:v0.6.6
ports:
- "3001:3000" # OneAPI管理后台端口
networks:
- fastgpt
restart: unless-stopped
depends_on:
mysql:
condition: service_healthy # 依赖MySQL健康状态
environment:
SQL_DSN: root:your_strong_production_password@tcp(mysql:3306)/oneapi
SESSION_SECRET: your_production_session_secret
MEMORY_CACHE_ENABLED: "true"
BATCH_UPDATE_ENABLED: "true"
INITIAL_ROOT_TOKEN: your_production_root_token # 务必修改!
volumes:
- /data/oneapi:/data
fastgpt:
container_name: fastgpt-prod
image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt:latest # 使用latest标签或指定稳定版本
ports:
- "3000:3000" # FastGPT主服务端口
networks:
- fastgpt
restart: unless-stopped
depends_on:
- mongo
- pg
- oneapi
environment:
DEFAULT_ROOT_PSW: your_fastgpt_admin_password # 修改默认管理员密码
OPENAI_BASE_URL: http://oneapi:3000/v1 # 注意这里用容器名,端口是3000
CHAT_API_KEY: sk-your-oneapi-token # 替换为在OneAPI创建的令牌
MONGODB_URI: mongodb://prod_username:prod_strong_password@mongo:27017/fastgpt?authSource=admin&directConnection=true
PG_URL: postgresql://prod_pg_user:prod_pg_password@pg:5432/postgres
SANDBOX_URL: http://sandbox:3000 # 如果需要代码执行沙箱
# 其他环境变量如日志级别等根据需要调整
LOG_LEVEL: info
volumes:
- ./config.prod.json:/app/data/config.json # 挂载生产环境配置文件
# 如果需要代码执行功能,部署sandbox
sandbox:
container_name: sandbox-prod
image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt-sandbox:latest
networks:
- fastgpt
restart: unless-stopped
# 通常sandbox不需要对外暴露端口
networks:
fastgpt:
external: false # 生产环境可以让Compose自己创建
name: fastgpt-network # 指定网络名称
这个文件把数据库、OneAPI、FastGPT主服务和沙箱(如果需要)都整合在了一起。部署前,你必须做以下几件事:
- 修改所有密码和密钥:把
your_strong_production_password、prod_strong_password、your_production_root_token、sk-your-oneapi-token等占位符全部替换成你自己生成的强密码和真实的令牌。 - 准备初始化脚本:在相同目录下创建
mongo_init.js文件,内容同开发环境。 - 准备生产配置:创建
config.prod.json,可以根据需要调整生产环境的参数,比如关闭调试信息、调整进程数等。 - 创建数据目录:在服务器上创建
/data/mysql,/data/mongo等目录,并确保Docker进程有读写权限(通常需要sudo chmod -R 777 /data或更精细的权限控制)。
在服务器上,进入该目录,先创建网络(如果使用外部网络):
docker network create fastgpt-network
然后启动所有服务:
docker-compose -f docker-compose-prod.yml up -d
使用docker-compose logs -f可以查看所有容器的日志,排查启动问题。访问服务器IP的3000端口,你应该就能看到线上版的FastGPT了。
5.2 方案二:打包自定义镜像部署(适合深度定制)
如果你在本地开发时对FastGPT源码做了大量定制修改,那么使用官方镜像就不合适了。你需要把自己修改后的代码打包成镜像,再部署到服务器。
第一步,在本地开发机打包镜像。 在FastGPT项目根目录执行:
docker build -f ./projects/app/Dockerfile -t mycompany/fastgpt:custom-v1 .
这个命令会根据projects/app/Dockerfile的指令,构建一个名为mycompany/fastgpt:custom-v1的镜像。构建过程会安装所有依赖并打包应用。
第二步,将镜像传输到服务器。 有两种常用方法:
- 方法A:推送到私有镜像仓库。如果你有Docker Hub账号或自建的Harbor等私有仓库,可以给镜像打tag然后
docker push上去,在服务器上docker pull下来。这是最规范的做法。 - 方法B:直接打包文件传输。对于临时或内网环境,可以用
docker save和docker load:# 在本地机器,将镜像保存为tar文件 docker save -o fastgpt-custom.tar mycompany/fastgpt:custom-v1 # 使用scp、rsync等工具将fastgpt-custom.tar上传到服务器 scp fastgpt-custom.tar user@your-server:/opt/fastgpt/ # 在服务器上加载镜像 docker load -i /opt/fastgpt/fastgpt-custom.tar
第三步,修改服务器上的Compose文件。 将fastgpt服务的image字段从官方镜像地址改为你自定义的镜像名:
fastgpt:
container_name: fastgpt-prod
image: mycompany/fastgpt:custom-v1 # 改为你的自定义镜像
# ... 其他配置保持不变
然后重新启动服务:
docker-compose -f docker-compose-prod.yml down
docker-compose -f docker-compose-prod.yml up -d
这样,服务器上运行的就是你定制化后的FastGPT应用了。
6. 避坑指南与进阶优化
走完上面的流程,一个完整的FastGPT应用应该已经跑在你的服务器上了。但根据我的经验,上线后总会遇到一些“惊喜”。这里分享几个常见的坑和对应的解决办法,以及一些让服务更稳健的优化思路。
坑1:MongoDB连接失败,提示“not authorized”或副本集问题。 这是最高频的问题。首先,检查连接字符串里的用户名、密码、数据库名(fastgpt)和认证源(authSource=admin)是否正确。其次,确保连接字符串包含了directConnection=true参数(对于Docker网络外或单节点副本集连接)。最后,可以进入MongoDB容器内部检查副本集状态:
docker exec -it mongo-prod mongosh -u prod_username -p prod_strong_password --authenticationDatabase admin
> rs.status()
如果状态不对,可以尝试重新初始化副本集。
坑2:OneAPI添加渠道后测试失败。 首先在OneAPI容器内测试网络连通性:
docker exec -it oneapi-prod curl https://api.openai.com
如果超时,说明服务器可能无法直接访问OpenAI,需要在OneAPI添加渠道时配置正确的代理地址。如果curl通但测试失败,检查API Key是否正确,以及是否有额度。
坑3:上传文件或处理大量数据时,服务内存飙升甚至崩溃。 FastGPT处理文件(特别是PDF解析)和向量生成比较耗资源。除了在config.prod.json中调低vectorMaxProcess和qaMaxProcess外,更根本的解决方法是限制容器的资源。在docker-compose-prod.yml中为fastgpt服务添加资源限制:
fastgpt:
# ... 其他配置
deploy:
resources:
limits:
memory: 4G # 限制最大内存
cpus: '2.0' # 限制最多使用2个CPU核心
reservations:
memory: 2G # 保证至少2G内存
这样可以防止单个容器吃光服务器内存。
进阶优化1:使用Nginx反向代理和SSL证书。 直接暴露3000和3001端口不优雅也不安全。建议在服务器上安装Nginx,配置反向代理和HTTPS。
# /etc/nginx/conf.d/fastgpt.conf
server {
listen 80;
server_name your-domain.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name your-domain.com;
ssl_certificate /path/to/your/fullchain.pem;
ssl_certificate_key /path/to/your/privkey.pem;
# ... 其他SSL优化配置
location / {
proxy_pass http://localhost:3000; # 代理到FastGPT
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 $scheme;
}
location /oneapi/ {
proxy_pass http://localhost:3001/; # 代理到OneAPI,注意尾随斜杠
proxy_set_header Host $host;
# ... 其他头信息
}
}
配置好后,用户通过https://your-domain.com访问FastGPT,通过https://your-domain.com/oneapi访问OneAPI管理后台,安全又规范。
进阶优化2:配置日志收集与监控。 生产环境不能没有监控。可以为每个服务配置JSON格式的日志,方便用ELK或Loki收集。同时,使用docker-compose logs --tail=100 -f可以实时跟踪日志。对于更重要的监控,可以暴露容器的健康检查端点(如果应用提供),或者使用Prometheus和Grafana来监控服务器和容器的资源使用情况。
最后的小建议:所有容器的重启策略我推荐使用restart: unless-stopped,这样容器会在异常退出时自动重启(除非你手动停止它),能提高服务的自愈能力。数据库的持久化卷一定要确保路径正确且有备份策略。环境变量中的密码、密钥等敏感信息,可以考虑使用Docker Secrets(在Swarm模式下)或通过文件注入的方式管理,而不是明文写在Compose文件里。
更多推荐




所有评论(0)