Docker
使用 Docker / Docker Compose 部署 Kaiwu 服务器。
本文介绍如何使用 Docker 部署专属的 Kaiwu Server。内容仅涉及服务端本身。
请以 /apps/server/.env.example 作为基础环境变量模板,并在 Docker 或 Compose 中载入相同的配置值。
预构建镜像(推荐)
我们在 Docker Hub 上发布了预览版 Docker 镜像(推荐):
docker pull KAIWUdev/relay-server:preview此外,相同的镜像也会同步发布到 GitHub Container Registry (GHCR):
docker pull ghcr.io/KAIWU-dev/relay-server:preview已发布的镜像:
relay-server:Kaiwu Server + 内嵌 Web UI(本文主讲)dev-box:Docker 环境下的 Kaiwu CLI + 守护进程(参见:Dev box)
已发布的 relay-server 镜像基于签名认证的 server-runtime 和 UI-web 发布产物构建。该镜像以非 root 用户运行,在构建期便已内嵌 UI 静态资源包,既无需拉取源码,也不依赖 hstack。
预构建的 relay-server 镜像支持默认的 SQLite 配置,以及文档中说明的 Postgres 覆盖配置。出于体积考量,该镜像特意移除了生成的 MySQL Prisma 客户端。若要搭配 MySQL 运行 Kaiwu,请基于本仓库源码构建包含 MySQL 的 server 镜像。
标签:
:preview(动态预览标签):preview-⟦K21⟧(不可变预览构建标签):stable/:latest(稳定通道,启用后可用)
版本更新
Docker 镜像不会自动更新。升级时,只需拉取更新的标签版本,并重启或重新创建容器即可:
docker pull KAIWUdev/relay-server:preview
docker compose up -d --force-recreate如果需要严格控制版本,建议锁定到不可变标签(例如 :preview-⟦K22⟧)或镜像摘要。
完整版本矩阵(所有应用与资产):Updates。
relay-server 镜像默认采用 light(轻量)风格 + SQLite,所有数据均存放在 /data 下。请将其挂载为数据卷,以确保升级和重启时的数据安全。
docker run --rm -p 3005:3005 \
-v kaiwu-server-data:/data \
KAIWUdev/relay-server:preview配置文档:
- 服务端环境变量参考:Environment variables
- 服务端认证策略(GitHub/OIDC/匿名等):Server Auth
- 若你在无界面的无头设备上运行,且希望在没有浏览器的情况下完成配对或认证:Daemon auth (headless)
注意事项:
- 该 Docker 镜像直接运行 Kaiwu Server(针对自托管优化的默认配置)。
- 镜像内嵌了 Web UI 资源包,默认在
/提供服务。- 禁用 UI 服务:设置
KAIWU_SERVER_UI_DIR=(留空)。 - 在子路径
/ui下托管 UI:设置KAIWU_SERVER_UI_PREFIX=/ui。
- 禁用 UI 服务:设置
- 镜像内不会安装受管宿主服务。拉取新镜像标签并重启容器后,即完成升级。
预构建镜像:搭配 Postgres(full 风格)
relay-server 镜像源自相同的服务端代码,同样能够以 full 风格运行——只需覆盖默认配置即可。Postgres 是预构建镜像原生支持的外部数据库。容器启动时,会先执行内嵌的 Postgres 迁移,然后再启动服务端。对于由健康检查编排管理或多副本部署的场景,建议改用 Migrations 中介绍的独立迁移步骤。
docker-compose.yml 示例(Postgres + 本地文件后端):
services:
db:
image: postgres:17
environment:
POSTGRES_DB: kaiwu
POSTGRES_USER: kaiwu
POSTGRES_PASSWORD: change-me
volumes:
- pgdata:/var/lib/postgresql/data
relay:
image: KAIWUdev/relay-server:preview
ports:
- "3005:3005"
environment:
PORT: "3005"
KAIWU_SERVER_FLAVOR: full
KAIWU_DB_PROVIDER: postgres
DATABASE_URL: postgresql://kaiwu:change-me@db:5432/kaiwu
HANDY_MASTER_SECRET: change-me-to-a-long-random-string
KAIWU_FILES_BACKEND: local
KAIWU_SERVER_LIGHT_DATA_DIR: /data/kaiwu
volumes:
- kaiwu-relay-data:/data/kaiwu
depends_on:
- db
volumes:
pgdata:
kaiwu-relay-data:若要改用 S3/Minio 替代本地文件,请设置 KAIWU_FILES_BACKEND=s3 以及相关的 S3_* 环境变量(参见 Environment variables)。
可选:使用 Tailscale 安全暴露中继
如果你想在不开放入站端口的情况下,从手机或远程设备访问自托管中继,推荐使用 Tailscale 作为边车容器,并通过 Tailscale Serve 发布服务端。
该方案的优势:
- 无需公网入口与复杂的 TLS 配置
- 在你的 tailnet 内网中提供稳定的 HTTPS 访问地址
- Kaiwu 服务端镜像无需特权即可运行(Tailscale 在独立的容器中工作)
最小化 docker-compose.yml 示例(预览通道):
services:
relay:
image: KAIWUdev/relay-server:preview
environment:
PORT: "3005"
# Optional:
# Disable UI serving:
# KAIWU_SERVER_UI_DIR: ""
volumes:
- kaiwu-relay-data:/data
tailscale:
image: tailscale/tailscale:stable
network_mode: service:relay
cap_add:
- NET_ADMIN
- SYS_MODULE
devices:
- /dev/net/tun:/dev/net/tun
environment:
TS_AUTHKEY: ${TS_AUTHKEY}
TS_HOSTNAME: kaiwu-relay
TS_STATE_DIR: /var/lib/tailscale
volumes:
- tailscale-state:/var/lib/tailscale
command: >
sh -lc '
tailscaled --state=${TS_STATE_DIR}/tailscaled.state &
sleep 2
tailscale up --authkey="${TS_AUTHKEY}" --hostname="${TS_HOSTNAME}" --accept-dns=false
tailscale serve --bg --https=443 http://127.0.0.1:3005
tail -f /dev/null
'
volumes:
kaiwu-relay-data:
tailscale-state:注意事项:
TS_AUTHKEY请尽量使用临时、一次性的预授权密钥。tailscale serve会将 Kaiwu UI 与 API(包含 WebSocket)发布在 Tailscale HTTPS 端点后方。- 若宿主环境受限导致无法使用
/dev/net/tun,可退回采用传统的反向代理(Caddy/Traefik/nginx),或者在宿主机操作系统中运行 Tailscale 并代理至容器。- 请确保反向代理支持
/v1/updates路径上的 Socket.IO 实时通信 WebSocket upgrades 请求,否则设备可能会持续显示离线。 - 参见:Deployment → Environment variables → Networking / reverse proxy
- 请确保反向代理支持
构建镜像
本仓库顶层包含一个 Dockerfile,提供了多个构建目标。
# Server image (defaults to the full flavor; role defaults to "all" unless SERVER_ROLE is set at runtime)
docker build -t kaiwu-server --target server .
# Worker image (sets SERVER_ROLE=worker in the image)
docker build -t kaiwu-server-worker --target server-worker .server 与 server-worker 目标直接基于源码树构建。relay-server 目标则与公开发布的 Docker 镜像结构一致,基于产物构建,因此需要显式传入发布产物作为输入:
docker build -t kaiwu-relay-server --target relay-server \
--build-arg KAIWU_RELAY_SERVER_RELEASE_TAG=server-preview \
--build-arg KAIWU_RELAY_SERVER_VERSION=<server-runtime-version> \
--build-arg KAIWU_RELAY_UI_WEB_RELEASE_TAG=ui-web-preview \
--build-arg KAIWU_RELAY_UI_WEB_VERSION=<ui-web-version> \
.发布流水线会自动从 GitHub Releases 解析这些构建参数。本地源码迭代开发时,建议改用 server 目标进行构建。
可选:仅构建指定的数据库提供商
默认情况下,从源码构建的 server 与 server-worker 镜像会包含所有受支持数据库提供商的生成版 Prisma 客户端。预构建的 relay-server 镜像基于发布产物,并剔除了生成的 MySQL Prisma 客户端;若需要使用 MySQL,请使用下方介绍的 server 目标。
若希望精简镜像体积、针对特定提供商定制镜像,可在构建时限制生成的 Prisma 客户端:
# Build with only Postgres (includes pglite support since it uses the Postgres client)
docker build -t kaiwu-server --target server \
--build-arg KAIWU_BUILD_DB_PROVIDERS='postgres' \
.
# Build with Postgres + MySQL (no SQLite client)
docker build -t kaiwu-server --target server \
--build-arg KAIWU_BUILD_DB_PROVIDERS='postgres|mysql' \
.注意事项:
pglite使用的是 Postgres Prisma 客户端。若计划在 light 模式下使用 PGlite,请务必包含postgres。light 风格本身的默认设置为sqlite。- 若构建时未包含
mysql(或sqlite),而在运行时指定了KAIWU_DB_PROVIDER=mysql(或sqlite),服务端在启动时会报错退出,并明确提示重新构建以包含缺失的提供商。
Full 与 Light 预设对比
Kaiwu Server 提供两种预设,二者共用相同的 API 与运行时环境。预设决定了拓扑架构和后端默认值;无论采用哪种预设,均可通过 KAIWU_DB_PROVIDER 独立选择底层数据库。
Full 风格(生产环境推荐)
适用于生产环境部署:搭配外部数据库,并可选接入 Redis 以支持多副本 Socket.IO 实时通信。默认情况下,full 风格使用 S3/Minio 存储公共文件,但你也可以通过 KAIWU_FILES_BACKEND=local 选择本地磁盘存储。
所需资源:
- 一个数据库(
DATABASE_URL) - 公共文件后端(二选一):
- 兼容 S3/Minio 的对象存储(配合
S3_*环境变量),并配置KAIWU_FILES_BACKEND=s3(默认) - 本地磁盘存储,配置
KAIWU_FILES_BACKEND=local(文件存放在KAIWU_SERVER_LIGHT_DATA_DIR下)
- 兼容 S3/Minio 的对象存储(配合
- 一个固定的密钥(
HANDY_MASTER_SECRET) - 可选:Redis,用于在多个 API 副本间横向扩展实时连接(
REDIS_URL+KAIWU_SOCKET_ADAPTER=redis-streams)
Light 风格(单节点 / 测试)
适用于追求极简的自托管场景:数据库单节点落盘运行(默认为 SQLite,或通过 PGlite 嵌入 Postgres),公共文件保存在本地,由服务端直接在 GET /files/* 提供访问。
所需资源:
- 用于 light 数据目录的持久化磁盘(存放数据库、文件及持久化密钥)
- 可选配置
HANDY_MASTER_SECRET传入固定密钥(未配置时会自动生成并持久化存储)
数据库提供商
数据库提供商可通过以下方式配置:
KAIWU_DB_PROVIDER(推荐)或旧版KAIWU_DB_PROVIDER/HAPPY_DB_PROVIDER
两种预设下均支持以下取值:postgres、mysql(MySQL 8.0.16+)、sqlite 与 pglite。Full 预设默认采用 Postgres;Light 预设默认采用 SQLite。
镜像所支持的数据库取决于构建方式。预构建的 relay-server 镜像内置了 SQLite 与 Postgres 运行时支持;若需支持 MySQL,必须基于源码构建并包含 MySQL 的 server 镜像。
快速开始(单容器)
本节适用于快速验证与测试。在生产环境中,建议使用 Docker Compose(见下节),或配置容器重启策略并配合环境变量文件。
Full 风格(Postgres)
docker run --rm -p 3005:3005 \
-e PORT=3005 \
-e DATABASE_URL='postgresql://user:pass@db:5432/kaiwu?sslmode=require' \
-e HANDY_MASTER_SECRET='change-me-to-a-long-random-string' \
-e KAIWU_FILES_BACKEND=s3 \
-e S3_HOST='minio' \
-e S3_PORT='9000' \
-e S3_USE_SSL='false' \
-e S3_BUCKET='kaiwu-public' \
-e S3_PUBLIC_URL='https://files.example.com/kaiwu-public' \
-e S3_ACCESS_KEY='...' \
-e S3_SECRET_KEY='...' \
kaiwu-serverFull 风格(MySQL 8.0.16+)
docker run --rm -p 3005:3005 \
-e PORT=3005 \
-e KAIWU_DB_PROVIDER=mysql \
-e DATABASE_URL='mysql://user:pass@db:3306/kaiwu' \
-e HANDY_MASTER_SECRET='change-me-to-a-long-random-string' \
-e KAIWU_FILES_BACKEND=s3 \
-e S3_HOST='minio' \
-e S3_PORT='9000' \
-e S3_USE_SSL='false' \
-e S3_BUCKET='kaiwu-public' \
-e S3_PUBLIC_URL='https://files.example.com/kaiwu-public' \
-e S3_ACCESS_KEY='...' \
-e S3_SECRET_KEY='...' \
kaiwu-server生产环境注意:移除 --rm 并添加 --restart unless-stopped(或对应运行平台的等效参数);同时建议使用 --env-file,避免维护冗长繁杂的 -e ... 参数列表。
示例:
cp apps/server/.env.example .env
docker run --env-file .env -p 3005:3005 kaiwu-serverFull 风格(本地文件后端)
若无需 S3/Minio,可将公共文件持久化在本地磁盘:
docker run --rm -p 3005:3005 \
-e PORT=3005 \
-e DATABASE_URL='postgresql://user:pass@db:5432/kaiwu?sslmode=require' \
-e HANDY_MASTER_SECRET='change-me-to-a-long-random-string' \
-e KAIWU_FILES_BACKEND=local \
-e KAIWU_SERVER_LIGHT_DATA_DIR=/data/kaiwu \
-v kaiwu-server-data:/data/kaiwu \
kaiwu-serverLight 风格(PGlite)
默认的 server 镜像会启动 full 风格。若要在 Docker 中以 light 风格运行,可以通过以下两种方式之一:
- 使用
relay-server目标(自托管推荐方式),或 - 运行
server目标并传入KAIWU_SERVER_FLAVOR=light。
镜像入口点会在启动前执行内置的 PGlite 迁移主程序,其机制与外部 Postgres 一致。请务必持久化挂载本地数据目录。
docker run --rm -p 3005:3005 \
-e PORT=3005 \
-e KAIWU_SERVER_FLAVOR=light \
-e KAIWU_DB_PROVIDER=pglite \
-e KAIWU_SERVER_LIGHT_DATA_DIR=/data/server-light \
-v kaiwu-server-light:/data/server-light \
kaiwu-serverLight 风格(SQLite,默认)
SQLite 是 light 风格的默认数据库,也是 Docker 环境下 light 模式的推荐之选,其架构为单进程且易于备份。在 RUN_MIGRATIONS=1(默认配置)下,入口点会启用服务端既有的启动迁移链路;在正常启动流程中,迁移任务会在数据库客户端初始化前执行一次。
docker run --rm -p 3005:3005 \
-e PORT=3005 \
-e KAIWU_SERVER_FLAVOR=light \
-e KAIWU_DB_PROVIDER=sqlite \
-e KAIWU_SERVER_LIGHT_DATA_DIR=/data/server-light \
-v kaiwu-server-light:/data/server-light \
kaiwu-server推荐方式:Docker Compose
对于绝大多数自托管用户而言,Docker Compose 是最可靠、可复现度最高的服务端运行方案:环境变量和数据卷统一维护在一处,升级也更加便捷。
你可以选择以下任意一种方式:
- 将
/apps/server/.env.example中的配置复制到environment:,或 - 直接通过
env_file:指定你独立维护的配置文件副本。
Full 风格(单进程)
本示例采用 Postgres + Minio。Redis 为可选组件,仅在 API 部署为多副本时需要。
services:
db:
image: postgres:17
environment:
POSTGRES_DB: kaiwu
POSTGRES_USER: kaiwu
POSTGRES_PASSWORD: change-me
volumes:
- pgdata:/var/lib/postgresql/data
minio:
image: minio/minio
command: server /data --console-address :9001
environment:
MINIO_ROOT_USER: minioadmin
MINIO_ROOT_PASSWORD: minioadmin
volumes:
- minio:/data
ports:
- "9000:9000"
- "9001:9001"
server:
build:
context: .
target: server
ports:
- "3005:3005"
environment:
PORT: "3005"
DATABASE_URL: postgresql://kaiwu:change-me@db:5432/kaiwu
HANDY_MASTER_SECRET: change-me-to-a-long-random-string
KAIWU_FILES_BACKEND: s3
S3_HOST: minio
S3_PORT: "9000"
S3_USE_SSL: "false"
S3_BUCKET: kaiwu-public
# For Minio behind a reverse proxy, set this to your public files URL.
S3_PUBLIC_URL: https://files.example.com/kaiwu-public
S3_ACCESS_KEY: minioadmin
S3_SECRET_KEY: minioadmin
# Single-container mode: leave SERVER_ROLE unset (defaults to "all")
depends_on:
- db
- minio
volumes:
pgdata:
minio:Full 风格(单进程,MySQL 8.0.16+)
本示例采用 MySQL 8.0.16+ + Minio。
services:
db:
image: mysql:8.0
environment:
MYSQL_DATABASE: kaiwu
MYSQL_ROOT_PASSWORD: change-me
volumes:
- mysqldata:/var/lib/mysql
minio:
image: minio/minio
command: server /data --console-address :9001
environment:
MINIO_ROOT_USER: minioadmin
MINIO_ROOT_PASSWORD: minioadmin
volumes:
- minio:/data
ports:
- "9000:9000"
- "9001:9001"
server:
build:
context: .
target: server
ports:
- "3005:3005"
environment:
PORT: "3005"
KAIWU_DB_PROVIDER: mysql
DATABASE_URL: mysql://root:change-me@db:3306/kaiwu
HANDY_MASTER_SECRET: change-me-to-a-long-random-string
KAIWU_FILES_BACKEND: s3
S3_HOST: minio
S3_PORT: "9000"
S3_USE_SSL: "false"
S3_BUCKET: kaiwu-public
S3_PUBLIC_URL: https://files.example.com/kaiwu-public
S3_ACCESS_KEY: minioadmin
S3_SECRET_KEY: minioadmin
depends_on:
- db
- minio
volumes:
mysqldata:
minio:Light 风格(Compose,PGlite 或 SQLite)
Light 风格以单进程运行,所有数据均存储在本地磁盘。
services:
server:
build:
context: .
target: server
ports:
- "3005:3005"
environment:
PORT: "3005"
KAIWU_SERVER_LIGHT_DATA_DIR: /data/server-light
# default: SQLite
# KAIWU_DB_PROVIDER: sqlite
# alternative: embedded Postgres via PGlite
# KAIWU_DB_PROVIDER: pglite
volumes:
- kaiwu-server-light:/data/server-light
command: >
sh -lc '
if [ "${KAIWU_DB_PROVIDER:-sqlite}" = "pglite" ]; then
yarn --cwd apps/server migrate:light:deploy &&
KAIWU_DB_PROVIDER=pglite yarn --cwd apps/server start:light;
else
yarn --cwd apps/server migrate:sqlite:deploy &&
KAIWU_DB_PROVIDER=sqlite yarn --cwd apps/server start:light;
fi
'
volumes:
kaiwu-server-light:Full 风格(API + Worker)
若将角色拆分部署,配置规则如下:
- API 容器添加
SERVER_ROLE=api - Worker 容器添加
SERVER_ROLE=worker
当 API 副本数大于 1 时,需启用 Redis 广播分发机制(REDIS_URL + KAIWU_SOCKET_ADAPTER=redis-streams),并在负载均衡器处配置粘性会话。
最小化配置示例(叠加至上方 full 风格的 Compose 配置中):
services:
redis:
image: redis:7
api:
build:
context: .
target: server
environment:
SERVER_ROLE: api
REDIS_URL: redis://redis:6379
KAIWU_SOCKET_ADAPTER: redis-streams
depends_on:
- db
- minio
- redis
worker:
build:
context: .
target: server-worker
environment:
REDIS_URL: redis://redis:6379
KAIWU_SOCKET_ADAPTER: redis-streams
depends_on:
- db
- minio
- redis数据迁移
基于源码构建的 server 目标和预构建的 relay-server 镜像默认均会自动执行数据库迁移。具体选用哪种迁移机制由 KAIWU_DB_PROVIDER 决定,与预设无关:Postgres、MySQL 和 PGlite 会调用对应的内置/提供商迁移主程序;SQLite 则沿用服务端规范的进程内启动迁移路径。
默认机制非常适合单容器环境。对于由编排工具管理的 Postgres、MySQL 或 PGlite 部署,在替换应用容器前应单独执行一次迁移:
docker compose run --rm relay run-server --migrate-only
docker compose up -d --force-recreate relay请在长期运行的 API 和 Worker 服务中设置 RUN_MIGRATIONS=0。显式执行 --migrate-only 命令时,即使存在该环境变量也会照常运行迁移,并在迁移完成后立即退出,绝不启动服务端。你的部署系统必须将非零退出状态码视为部署失败,并保持现有的应用容器继续运行。
若你的部署平台无法运行并等待阻塞式预部署命令执行完毕(例如,由独立 Webhook 触发的多个 Dokploy 独立应用),可退而求其次,指定仅由某一个 API 服务作为迁移负责人:仅在这一处配置 RUN_MIGRATIONS=1,并在所有 Worker 和其他副本中配置 RUN_MIGRATIONS=0;同时采用“先启后停”滚动更新与自动回滚策略,并为负责迁移的容器预留足够的健康检查启动宽限时间,以应对最耗时的迁移任务。该兜底方案依赖向后兼容的数据库迁移,使得 API 负责人在升级模式期间,Worker 能够不受中断地持续对外服务。
注意事项:
- 可通过
RUN_MIGRATIONS=0禁用自动迁移。对于 SQLite,入口点会将该配置映射到服务端启动迁移设置中,不会拉起第二个迁移进程。 - SQLite 请保持常规的单进程启动流程;封装的 SQLite 运行时不支持
--migrate-only。 - PostgreSQL 的咨询锁可以串行化并发的迁移操作,但若编排器因启动健康检查超时而强制终止容器,咨询锁无法提供保护。如果迁移耗时可能超过平台的启动宽限期,请务必指定单独的专职迁移负责实例。
- 若迁移部署过程意外中断,在恢复前请务必核查数据库状态与迁移台账。绝不能仅为了让服务端启动,就盲目将状态未知的失败迁移强行标记为已应用。
反向代理检查清单
- 在反向代理处终止 TLS(推荐)。
- 转发 WebSocket upgrade 请求头。
- 为长连接适当增大超时时间。
- 密钥统一保存在部署平台的环境变量中,严禁提交至 Git 仓库。
开发说明(贡献者指南)
如果你是在参与 Kaiwu Server 本身的开发(而非仅仅部署运行),请留意以下要点:
- 存在两种运行时预设:full(
yarn --cwd apps/server start)与 light(yarn --cwd apps/server start:light)。 - 数据库提供商通过
KAIWU_DB_PROVIDER=postgres|mysql|sqlite|pglite独立指定;full 预设默认使用 Postgres,light 预设默认使用 SQLite。 - Prisma 模型的单一真实来源:
apps/server/prisma/schema.prisma。 - 各提供商的 schema 文件均由其生成:
yarn --cwd apps/server schema:sync(且测试会严格校验schema:sync:check)
- 迁移文件按提供商区分:
- Postgres/PGlite:
apps/server/prisma/migrations/* - SQLite:
apps/server/prisma/sqlite/migrations/* - MySQL:
apps/server/prisma/mysql/migrations/*
- Postgres/PGlite:
当你修改数据模型时,请务必执行以下步骤:
- 更新
apps/server/prisma/schema.prisma - 运行
yarn --cwd apps/server schema:sync
数据迁移
基于源码构建的 server 目标和预构建的 relay-server 镜像默认均会自动执行数据库迁移。具体选用哪种迁移机制由 KAIWU_DB_PROVIDER 决定,与预设无关:Postgres、MySQL 和 PGlite 会调用对应的内置/提供商迁移主程序;SQLite 则沿用服务端规范的进程内启动迁移路径。
默认机制非常适合单容器环境。对于由编排工具管理的 Postgres、MySQL 或 PGlite 部署,在替换应用容器前应单独执行一次迁移:
docker compose run --rm relay run-server --migrate-only
docker compose up -d --force-recreate relay请在长期运行的 API 和 Worker 服务中设置 RUN_MIGRATIONS=0。显式执行 --migrate-only 命令时,即使存在该环境变量也会照常运行迁移,并在迁移完成后立即退出,绝不启动服务端。你的部署系统必须将非零退出状态码视为部署失败,并保持现有的应用容器继续运行。
若你的部署平台无法运行并等待阻塞式预部署命令执行完毕(例如,由独立 Webhook 触发的多个 Dokploy 独立应用),可退而求其次,指定仅由某一个 API 服务作为迁移负责人:仅在这一处配置 RUN_MIGRATIONS=1,并在所有 Worker 和其他副本中配置 RUN_MIGRATIONS=0;同时采用“先启后停”滚动更新与自动回滚策略,并为负责迁移的容器预留足够的健康检查启动宽限时间,以应对最耗时的迁移任务。该兜底方案依赖向后兼容的数据库迁移,使得 API 负责人在升级模式期间,Worker 能够不受中断地持续对外服务。
注意事项:
- 可通过
RUN_MIGRATIONS=0禁用自动迁移。对于 SQLite,入口点会将该配置映射到服务端启动迁移设置中,不会拉起第二个迁移进程。 - SQLite 请保持常规的单进程启动流程;封装的 SQLite 运行时不支持
--migrate-only。 - PostgreSQL 的咨询锁可以串行化并发的迁移操作,但若编排器因启动健康检查超时而强制终止容器,咨询锁无法提供保护。如果迁移耗时可能超过平台的启动宽限期,请务必指定单独的专职迁移负责实例。
- 若迁移部署过程意外中断,在恢复前请务必核查数据库状态与迁移台账。绝不能仅为了让服务端启动,就盲目将状态未知的失败迁移强行标记为已应用。
反向代理检查清单
- 在反向代理处终止 TLS(推荐)。
- 转发 WebSocket upgrade 请求头。
- 为长连接适当增大超时时间。
- 密钥统一保存在部署平台的环境变量中,严禁提交至 Git 仓库。
开发说明(贡献者指南)
如果你是在参与 Kaiwu Server 本身的开发(而非仅仅部署运行),请留意以下要点:
- 存在两种运行时预设:full(
yarn --cwd apps/server start)与 light(yarn --cwd apps/server start:light)。 - 数据库提供商通过
KAIWU_DB_PROVIDER=postgres|mysql|sqlite|pglite独立指定;full 预设默认使用 Postgres,light 预设默认使用 SQLite。 - Prisma 模型的单一真实来源:
apps/server/prisma/schema.prisma。 - 各提供商的 schema 文件均由其生成:
yarn --cwd apps/server schema:sync(且测试会严格校验schema:sync:check)
- 迁移文件按提供商区分:
- Postgres/PGlite:
apps/server/prisma/migrations/* - SQLite:
apps/server/prisma/sqlite/migrations/* - MySQL:
apps/server/prisma/mysql/migrations/*
- Postgres/PGlite:
当你修改数据模型时,请务必执行以下步骤:
- 更新
apps/server/prisma/schema.prisma - 运行
yarn --cwd apps/server schema:sync - 为每个受支持的提供商创建迁移文件(至少包含 Postgres + MySQL;若本次修改需要支持 light/sqlite,还需包含 SQLite)