Skip to Content
开发部署部署与开发

部署与开发

数据库自动升级

生产容器的 releasestart 都会先执行 npm run database:init。该命令只执行当前 Prisma migrations,然后用当前 Prisma schema 补齐尚未进入迁移目录的非破坏性结构变更。同步不使用 --accept-data-loss,遇到需要丢弃数据的变更会停止发布。已上线的早期资产目录基线迁移和无限画布分集数据回填不再随初始化执行,仓库也不再提供对应的一键迁移命令;初始化末尾只运行只读分集完整性检查,不修改业务数据。若检查报告 CANVAS_EPISODE_BACKFILL_INCOMPLETE,说明数据库存在未绑定分集的异常旧数据,需要根据报告逐项核对实际归属并定向修复后再发布,不能把多集数据统一猜测为第 1 集。

本地开发

VVICAT 要求 Node.js 22 和 npm 9 以上版本。本地运行需要 PostgreSQL、Redis 和对象存储;npm run dev 会同时启动 Next.js、Worker、Watchdog 和 Bull Board,并先初始化存储。

npm install cp .env.example .env npm run project:init npm run dev

.env.example 配置数据库、Redis、Supabase 和存储。不要提交 .env。Web 默认使用 3000 端口,Bull Board 默认使用 3010 端口;长任务必须由 Worker 消费,不能只启动 Web 后判断生成功能不可用。

修改文档后运行:

npm run check:docs-sync npx vitest run tests/unit/docs npm run typecheck npm run build

npm run build 成功后会自动把 Next 生成的文档 HTML 整理到 .next/pagefind-site,再生成 public/_pagefind 索引。生产镜像和部署产物必须保留该目录,否则文档搜索会无法加载索引。本地开发需要先完成一次构建,再重启开发服务测试搜索。索引是构建产物,不提交到 Git。

Turbopack 会静态解析本地价格 adapter 对仓库根目录 prisma/model-prices.json 的依赖;移动 src/lib/pricing/adapters/local-seed.ts 时必须同步校正相对路径,否则构建会报告模块不存在。

Docker 单容器部署

运行期配置统一来自 .env.example 的副本,并只读挂载到 /app/.env。不要把真实 .env 或 npm token 提交到仓库。

需要的服务

服务用途与要求
Docker 镜像仓库存放研发构建的固定版本镜像,不使用 latest
Supabase使用 Supabase Auth 登录;Supabase PostgreSQL 可直接作为业务数据库,也可改用独立 PostgreSQL 16
阿里云 Redis提供完整 REDIS_URL,例如 redis://:密码@主机:6379/库编号
阿里云 OSS使用私有 Bucket;AccessKey 只授予该 Bucket 必要的读、写、删除权限;CORS 允许正式站点来源执行 GET,并暴露 Content-LengthContent-Type 响应头,供浏览器使用短期签名地址直接下载
域名反向代理指向容器 3000 端口,Supabase 同步配置正式站点和登录回调地址

部署步骤

  1. 研发构建并推送固定版本镜像。构建时注入正式 Supabase 和站点配置:
docker build \ --build-arg NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co \ --build-arg NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY=<Publishable Key> \ --build-arg NEXT_PUBLIC_SITE_URL=https://app.example.com \ -t registry.example.com/vvicat:<version> . docker push registry.example.com/vvicat:<version>

镜像依赖使用仓库提交的 package-lock.json 执行确定性安装。.env*、本地 worktree 和 AI 工具目录不会进入构建上下文;构建期公开配置必须通过 --build-arg 注入,运行期配置通过只读文件挂载注入。

Supabase 登录、注册和邮件确认通过代码中的 redirectTo 参数显式传入回调地址,统一使用 NEXT_PUBLIC_SITE_URL 拼接 /{locale}/auth/callback,不会改用浏览器当前 origin。该值必须填写当前部署域名,并在 Supabase Redirect URLs 中允许对应路径。

镜像提供 releaseserveall 三种启动模式,默认使用 all:每次容器启动时先幂等同步数据库结构、管理员和初始化数据,再启动常驻服务。普通应用部署应保持 NPM_PUBLISH_ENABLED=false,避免容器重启触发 CLI 发布。多副本或自动扩缩环境应把 release 作为单独的发布任务,并把应用启动命令覆盖为 sh scripts/docker-start.sh serve

  1. 复制并填写运行配置:
cp .env.example .env

至少填写数据库、Redis、Supabase、管理员 UUID 和对象存储配置。VVICAT_ADMIN_USER_ID 来自 Supabase Authentication → Users;密码始终由 Supabase 管理。

  1. 启动容器并只读挂载配置;默认 all 会先执行发布初始化,再启动常驻服务:
docker run -d --name vvicat \ --restart unless-stopped \ -p 3000:3000 -p 3010:3010 \ --mount type=bind,src="$(pwd)/.env",dst=/app/.env,readonly \ registry.example.com/vvicat:<version>

release 会从 /app/.env 依次执行数据库迁移与 schema 同步、对象存储 Bucket 初始化、首个管理员设置、初始化快照同步、积分套餐 seed、模型价格 seed 和画布提示词发布。初始化同步只通过幂等 upsert 新增或更新全局数据,不删除用户业务数据;已有积分套餐会保留后台修改值,模型价格无变化时不会创建新修订,有变化时发布新的不可变修订。模型价格 seed 优先使用命令行明确指定的管理员;否则尝试 VVICAT_ADMIN_USER_ID,未配置或对应账号失效时自动选择最早创建的管理员。它不会读取或覆盖供应商密钥、连接地址、启停状态及支付渠道配置。任一步失败都会终止发布,不会继续启动应用。默认 all 会在容器重启时重复这些幂等步骤;多副本环境应改用独立 release 任务和 serve 启动命令。

自动发布 CLI 到 npm

默认不发布。需要让本次 releaseall 自动推送 CLI 时,先更新 CLI 版本,再在只读挂载的 .env 中设置:

NPM_PUBLISH_ENABLED=true NPM_PUBLISH_PACKAGE_NAME=@aswless_854771076/ai_short_studio_cli VVICAT_CLI_PACKAGE_NAME=@aswless_854771076/ai_short_studio_cli VVICAT_CLI_LATEST_VERSION=0.1.15 NPM_PUBLISH_TAG=latest NODE_AUTH_TOKEN=<npm Granular Access Token>

NPM_PUBLISH_PACKAGE_NAME 控制发布目标;VVICAT_CLI_PACKAGE_NAME 指定 npm 包,VVICAT_CLI_LATEST_VERSION 是 npm registry 暂时不可用时的稳定版本降级值,成功发布后必须同步更新。正常情况下 /api/v1/bootstrap 以该包的 npm latest 为准。Token 必须具有目标包发布权限并允许 bypass 2FA。发布会构建 npm 包并从 registry 安装精确版本完成验证;失败会中止发布流程。普通应用部署保持 NPM_PUBLISH_ENABLED=false

CLI 发布位于画布提示词发布之后。部署前运行 npm run check:prompt-ab-regression,确保提示词 catalog 声明的变量与中英文模板一致;如果容器日志出现 CANVAS_PROMPT_VARIABLE_MISMATCH,本次 release 会在访问 npm 之前终止,因此远端版本不会变化。修正变量合同并重新部署,不要先排查 npm Token 或手工补发版本。

latest 是 npm 的默认 dist-tag,每次用该标签发布新版本都会移动到新版本,但已经全局安装的 CLI 不会自动升级。手动更新命令为:

npm install --global @aswless_854771076/ai_short_studio_cli@latest
  1. 将反向代理指向 3000 端口,确认 HTTPS、Supabase 登录、图片上传、Redis 队列和 OSS 读取正常。

发布后检查

  • Web、Worker、Watchdog 和 Bull Board 进程都已启动。
  • 登录回调、项目创建、媒体上传与读取、Redis 队列和后台任务正常。
  • VVICAT_ADMIN_USER_ID 对应正确的 Supabase 用户,Bull Board 受账号密码保护。
  • 日志保持结构化并启用敏感字段脱敏;LOG_ASYNC_TASK_PAYLOAD_ENABLED 默认关闭。
  • 配置变更后重新创建容器,不使用 latest,不手工修改容器内文件。

相关文档

Last updated on