Files
JuYou/文档/部署文档.md
T
2026-08-25 17:59:42 +08:00

16 KiB
Raw Blame History

剧核工厂生产环境部署文档

本文档适用于在 Windows 本地构建项目,并一键部署到 Linux AMD64 服务器。 这里的“一键部署”是指服务器上的 one_click_deployment.sh 会一次完成环境初始化、数据库迁移、服务注册、Nginx 和 HTTPS 配置。 完整发布分为两个明确阶段:本地构建并上传、服务器执行一键部署。push.bat 只上传文件,不会自动修改数据库或重启线上服务。

1. 最短操作流程

首次部署,在 Windows 项目根目录执行:

.\API\deploy\push.bat root@服务器IP with-env
ssh root@服务器IP
sudo bash /opt/juyou_ai/deploy/one_click_deployment.sh

日常更新,在 Windows 项目根目录执行:

.\API\deploy\push.bat root@服务器IP
ssh root@服务器IP
sudo bash /opt/juyou_ai/deploy/one_click_deployment.sh

首次部署使用 with-env,将本地正式环境配置送到服务器;日常更新不使用 with-env,继续保留服务器已有的生产配置。 上传和服务器部署是两个独立步骤,便于在执行数据库迁移和重启前安排备份与维护窗口。

2. 固定路径与服务

项目 固定值
服务器项目目录 /opt/juyou_ai
API 二进制 /opt/juyou_ai/bin/jcf-api
部署脚本 /opt/juyou_ai/deploy/one_click_deployment.sh
WEB 静态目录 /opt/juyou_ai/static/web
ADMIN 静态目录 /opt/juyou_ai/static/admin
数据库迁移目录 /opt/juyou_ai/migrations
systemd 服务名 juyou_ai
API 内部监听地址 127.0.0.1:8123
生产环境文件 /etc/juyou_ai/juyou_ai.env
临时环境文件 /tmp/juyou_ai.env
Whisper 离线模型 /opt/juyou_ai/models/faster-whisper-small
Whisper 运行缓存 /var/cache/juyou_ai/huggingface
Nginx 配置 /etc/nginx/conf.d/juyou_ai.conf
SSL 证书目录 /etc/nginx/ssl

API 仅监听服务器本机地址,公网请求统一通过 Nginx 进入。

3. 首次部署

3.1 准备本地环境

本地需要安装:

  • Node.js 和 npm
  • Go
  • Python 3;服务器缺少离线模型时,本机还需要 faster-whisper
  • tar
  • OpenSSH Clientsshscp

在终端确认命令可用:

npm --version
go version
python --version
tar --version
ssh -V

首次在本机下载 Whisper 模型前安装 Python 依赖:

python -m pip install faster-whisper==1.2.1

push.bat 不会自动安装前端依赖。首次构建或 package-lock.json 发生变化后,先执行:

npm --prefix WEB ci
npm --prefix ADMIN ci

首次部署使用的正式环境配置保存在本地:

API/.env

至少确认以下字段使用正式值,不能保留 replace-withchange-meexample.com 或开发环境默认值:

DATABASE_NAME=juchuang_factory
DATABASE_USER=jcf
DATABASE_PASSWORD=数据库强密码

JWT_SECRET_KEY=随机长密钥
ADMIN_BOOTSTRAP_USERNAME=admin
ADMIN_BOOTSTRAP_PASSWORD=管理员初始强密码

CONFIG_ENCRYPTION_KEY_VERSION=v1
CONFIG_ENCRYPTION_KEY=正式加密密钥

COS_SECRET_ID=腾讯云子账号SecretId
COS_SECRET_KEY=腾讯云子账号SecretKey
COS_BUCKET=juyouai-1451538162
COS_REGION=ap-chengdu
COS_ENDPOINT=https://cos.ap-chengdu.myqcloud.com
COS_PUBLIC_BASE_URL=https://cos.youjuhui.xyz

COS 媒体使用独立域名时,还必须在腾讯云控制台进入 对象存储 COS → 对应存储桶 → 安全管理 → 跨域访问 CORS 设置,添加以下规则。将域名替换为实际访问 WEB 的域名;多个 WEB 域名需要全部列出。

[
  {
    "AllowedOrigins": [
      "https://juhefactory.com",
      "https://www.juhefactory.com"
    ],
    "AllowedMethods": [
      "GET",
      "HEAD"
    ],
    "AllowedHeaders": [
      "*"
    ],
    "ExposeHeaders": [
      "Accept-Ranges",
      "Content-Length",
      "Content-Range",
      "Content-Type",
      "ETag"
    ],
    "MaxAgeSeconds": 3600
  }
]

保存策略后,确认媒体响应包含与当前 WEB 域名一致的 Access-Control-Allow-Origin。否则视频可以播放,但浏览器会禁止导出静帧和通过 Blob 直接下载。

可以使用以下命令生成随机密钥:

openssl rand -hex 32

3.2 准备服务器

目标服务器需要满足:

  • Linux AMD64/x86_64,使用 Debian 或 Ubuntu 最稳妥
  • 使用 systemd
  • SSH 登录用户具备 sudo 权限,推荐使用 root
  • 云安全组及防火墙已放行 TCP 80、443
  • 启用 HTTPS 时,域名已经解析到服务器公网 IP

脚本虽然包含 apt-getdnfyum 的安装分支,但服务账户固定使用 www-data。使用非 Debian/Ubuntu 发行版前,需要先确认系统存在 www-data 用户和用户组,并确认 PostgreSQL、Redis 的 systemd 服务名与脚本兼容。

3.3 本地构建并上传

在 Windows 项目根目录执行:

.\API\deploy\push.bat root@服务器IP with-env

示例:

.\API\deploy\push.bat root@192.168.1.1 with-env

命令完成并显示以下内容后,才进入服务器执行部署:

Deployment push complete.

本地上传完成只表示文件已经同步到 /opt/juyou_ai,此时不会自动安装依赖、迁移数据库或重启服务。

3.4 登录服务器并执行首次部署

本地另行登录服务器:

ssh root@服务器IP

服务器上执行:

bash /opt/juyou_ai/deploy/one_click_deployment.sh

如果当前不是 root 用户,执行:

sudo bash /opt/juyou_ai/deploy/one_click_deployment.sh

首次运行会询问两项配置。

域名:

juhefactory.com

多个域名使用空格分隔:

juhefactory.com www.juhefactory.com

不申请 SSL 时输入:

_

然后输入 SSL 证书邮箱;不申请 SSL 时直接回车。域名和邮箱会保存到:

/opt/juyou_ai/deploy/.deploy.conf

首次部署完成后,将该文件复制到本地:

scp root@服务器IP:/opt/juyou_ai/deploy/.deploy.conf .\API\deploy\.deploy.conf

后续上传不会携带本地 .deploy.conf;服务器会继续使用 /opt/juyou_ai/deploy/.deploy.conf,不会被本地文件覆盖。

3.5 验证首次部署

查看服务状态:

systemctl status juyou_ai --no-pager
systemctl status nginx --no-pager
systemctl status postgresql --no-pager
systemctl status redis-server --no-pager

检查 API

curl -i http://127.0.0.1:8123/health

启用 HTTPS 后检查公网入口:

curl -i https://你的域名/health

页面地址:

https://你的域名/
https://你的域名/admin/

4. 更新部署

每次更新都分为本地上传和服务器部署两步,不能只执行其中一步。

4.1 本地重新构建并上传

在 Windows 项目根目录执行:

.\API\deploy\push.bat root@服务器IP

等待出现:

Deployment push complete.

4.2 服务器应用更新

登录服务器:

ssh root@服务器IP

执行:

bash /opt/juyou_ai/deploy/one_click_deployment.sh

更新部署会:

  • 继续使用服务器现有的 /etc/juyou_ai/juyou_ai.env
  • 执行尚未执行的数据库迁移
  • 更新 systemd 与 Nginx 配置
  • 重启 systemd 服务 juyou_ai

4.3 只更新已上传文件但暂不部署

只执行本地 push.bat 即可。上传完成后不要在服务器运行 one_click_deployment.sh

此时:

  • /opt/juyou_ai 中已经是新文件
  • /etc/juyou_ai/juyou_ai.env 保持不变
  • 当前运行中的 API 进程仍可能使用旧二进制
  • 数据库迁移、Nginx 更新和服务重启均未执行

需要正式应用更新时,再执行服务器部署命令。

5. 推送参数说明

命令 是否上传 API/.env 是否自动执行服务器部署 使用场景
push.bat root@服务器IP 日常增量更新
push.bat root@服务器IP stage-only 与默认推送行为相同,用于明确表达“只暂存”
push.bat root@服务器IP with-env 首次部署或明确替换整套生产环境配置

三种命令都只负责构建、打包和上传。stage-only 当前是语义标记,执行行为与不传第二个参数相同。只有随后在服务器运行 one_click_deployment.sh,才会执行迁移、更新服务配置并重启应用。

6. 常用维护命令

服务管理:

systemctl restart juyou_ai
systemctl stop juyou_ai
systemctl start juyou_ai
systemctl reload nginx
nginx -t

查看 API 日志:

journalctl -u juyou_ai -f
journalctl -u juyou_ai -n 200 --no-pager

修改域名或证书邮箱:

nano /opt/juyou_ai/deploy/.deploy.conf

也可以删除配置,让下次部署重新询问:

rm /opt/juyou_ai/deploy/.deploy.conf

更新 acme.sh

bash /opt/juyou_ai/deploy/update_acme.sh

7. 备份与故障排查

正式执行数据库迁移前应先备份数据库。以下示例中的数据库名必须替换为生产环境 DATABASE_NAME 的实际值:

mkdir -p /opt/juyou_ai/backups
sudo -u postgres pg_dump -Fc juchuang_factory | tee /opt/juyou_ai/backups/juchuang_factory.dump >/dev/null

PostgreSQL

systemctl status postgresql --no-pager
journalctl -u postgresql -n 200 --no-pager

Redis

systemctl status redis-server --no-pager
redis-cli ping

Nginx

nginx -t
journalctl -u nginx -n 200 --no-pager

API

systemctl status juyou_ai --no-pager
journalctl -u juyou_ai -n 200 --no-pager
ls -l /etc/juyou_ai/juyou_ai.env
ls -l /opt/juyou_ai/bin/jcf-api

如果部署提示环境字段缺失、格式错误或仍为示例值,修改本地 API/.env,重新执行 push.bat,然后再次在服务器运行部署脚本。

如果数据库迁移失败,应先核对数据库实际结构和 jcf_schema_migrations,不得通过手工插入迁移记录直接绕过错误。数据库迁移不会自动回滚。

8. 自动化部署流程说明

本节用于解释脚本内部做了什么。日常操作只需要按“首次部署”或“更新部署”章节执行命令。

8.1 push.bat 的本地流程

  1. 检查目标 SSH 地址;仅在使用 with-env 时检查本地 API/.env 是否存在。
  2. 通过 SSH 检查服务器是否已有完整的 Whisper small 模型。缺少时,本机运行 download_whisper_model.py 下载模型,并把 models/ 加入本次上传包。
  3. 执行 npm --prefix WEB run build,类型检查通过后将 WEB 输出到 API/static/web
  4. 执行 npm --prefix ADMIN run build,类型检查通过后将 ADMIN 输出到 API/static/admin
  5. 使用 GOOS=linuxGOARCH=amd64-trimpath 和裁剪调试信息的链接参数,编译 API/bin/jcf-api
  6. 创建本机临时压缩包,包含:
bin/
static/
deploy/
migrations/
acme/
workers/
models/       # 仅服务器缺少离线模型时包含
.env          # 仅使用 with-env 时包含
  1. 使用 SCP 将压缩包上传到 /tmp/juyou-deploy.tar.gz
  2. 使用 SSH 在服务器的 /tmp/juyou-deploy-work 临时目录解包。
  3. 默认删除可能残留的 /tmp/juyou_ai.env;使用 with-env 时才将 .env 安装为权限 600/tmp/juyou_ai.env,并从项目文件中删除 .env
  4. 服务器存在 rsync 时,以 --delete 将发布文件同步到 /opt/juyou_ai;不存在时使用 cp -a 覆盖复制。
  5. 删除服务器临时解包目录和压缩包。
  6. 删除本机临时压缩包。

同步时保留以下服务器内容:

/opt/juyou_ai/media/
/opt/juyou_ai/backups/
/opt/juyou_ai/models/

models/ 默认不会被 rsync --delete 清理;仅当服务器缺少完整模型且本次压缩包含有模型时,才会单独同步模型内容。

/opt/juyou_ai/deploy/.deploy.conf 仅在服务器首次运行部署脚本时生成;上传包会排除本地 .deploy.conf,后续部署不会覆盖服务器配置。

.go 源码、测试代码、cmdinternaltoolsmediabackups 不会进入上传包;运行时需要的 workers 会进入上传包。

8.2 one_click_deployment.sh 的服务器流程

  1. 首次运行时只从 JuYouAI 自己的 Nginx 配置恢复域名;没有该配置时询问域名。仅复用输入域名对应的证书和私钥,不扫描其他项目的证书,并保存 .deploy.conf
  2. 使用 with-env 时检测 /tmp/juyou_ai.env 并将其作为本次环境配置来源,否则继续使用服务器生产环境文件。
  3. 调用 deploy_with_ssl.sh 执行正式部署。

8.3 deploy_with_ssl.shprepare_server.sh 的服务器流程

  1. 本机执行 push.bat 时检查服务器是否已有 Whisper 模型;首次部署会在本机下载并上传到 /opt/juyou_ai/models/faster-whisper-small。服务器不访问 Hugging Face。
  2. 安装 sudo、Nginx、PostgreSQL、Redis、FFmpeg、curl、socat、ca-certificates、openssl、Python 3 和 pip;缺少时安装 faster-whisper 1.2.1
  3. 启用并启动 PostgreSQL、Redis 和 Nginx。
  4. 存在 /tmp/juyou_ai.env 时将其安装到 /etc/juyou_ai/juyou_ai.env;否则保留现有生产环境文件,权限保持 root:root600
  5. 将生产环境标准化为:
APP_ENV=production
DEBUG=false
SERVER_ADDRESS=127.0.0.1:8123
DATABASE_HOST=127.0.0.1
DATABASE_PORT=5432
DATABASE_URL=
REDIS_HOST=127.0.0.1
REDIS_PORT=6379
CORS_ORIGINS=根据部署域名生成
FFMPEG_PATH=ffmpeg
FFPROBE_PATH=ffprobe
PYTHON_PATH=python3
ASR_SCRIPT_PATH=/opt/juyou_ai/workers/transcribe.py
JCF_ASR_CACHE_DIR=/var/cache/juyou_ai
HF_HOME=/var/cache/juyou_ai/huggingface
FASTER_WHISPER_MODEL_PATH=/opt/juyou_ai/models/faster-whisper-small
  1. 校验离线 Whisper 模型、数据库、JWT、管理员、配置加密和 COS 等必填配置。
  2. 创建或更新 PostgreSQL 用户和数据库,配置本机认证。
  3. 按文件名顺序执行 /opt/juyou_ai/migrations/*.up.sql,并记录到 jcf_schema_migrations
  4. 创建或更新 /etc/systemd/system/juyou_ai.service
[Service]
User=www-data
Group=www-data
WorkingDirectory=/opt/juyou_ai
EnvironmentFile=/etc/juyou_ai/juyou_ai.env
CacheDirectory=juyou_ai
ExecStart=/opt/juyou_ai/bin/jcf-api
Restart=always
RestartSec=3
  1. 配置 Nginx/api/ 和健康检查路径代理到 127.0.0.1:8123/admin/ 提供 ADMIN 静态文件,其他路径提供 WEB 静态文件,上传体积上限为 2 GiB。
  2. 配置域名且已有该域名的证书时直接复用;没有证书但填写邮箱时,先创建 HTTP 验证站点,再使用 acme.sh 通过 HTTP-01 申请并安装 HTTPS 证书;域名填 _,或没有证书且未填写邮箱时使用 HTTP。
  3. 启用 HTTPS 时把 80 端口请求重定向到 HTTPS,并允许 TLS 1.2、TLS 1.3。
  4. 执行 nginx -t,配置检查成功后重载 Nginx。
  5. 重启 systemd 服务 juyou_ai
  6. 部署成功后删除 /tmp/juyou_ai.env

如果部署中途失败,临时环境文件可能保留,以便排查并重新执行部署;问题解决并部署成功后会自动清理。

8.4 重复执行与失败边界

  • 脚本使用 set -euo pipefail,关键命令失败时会立即退出。
  • 已有 PostgreSQL 用户会更新密码,已有数据库不会重复创建。
  • 已记录在 jcf_schema_migrations 的迁移会跳过,未记录迁移按文件名顺序执行。
  • systemd 和 Nginx 配置每次都会按当前发布内容重新生成。
  • 已保存的域名、证书邮箱和匹配域名的现有证书会复用。
  • 部署脚本不会自动恢复旧二进制,也不会自动回滚已经成功执行的数据库迁移。发布前必须自行完成数据库备份;需要应用级回滚时,应重新上传兼容当前数据库结构的旧版本并再次部署。