升级你的 OSS 版本
Logto 遵循 semver。你可以在 GitHub Releases 中找到每个版本及其变更。本指南解释了升级的工作原理、如何升级每种常见的部署方式,以及如何解决你可能遇到的问题。
升级的工作原理
一次升级包含两个部分:
- Logto 代码:你运行的 Docker 镜像或发布的 tarball。
- 数据库结构:不同版本之间的结构变更以数据库变更的形式发布,你需要使用 Logto CLI 部署这些变更。你的数据库会记录已经部署过哪些变更。
当 Logto 启动时,它会检查数据库。如果当前 Logto 版本中包含的某些变更还未被部署,Logto 会拒绝启动:
Found undeployed database alterations, you must deploy them first by npm run alteration deploy command.
...
Error: Undeployed database alterations found.
变更被设计为与上一版本的 Logto 兼容,因此仍在运行旧版本的实例在变更部署后可以继续工作。这样可以按照以下顺序操作,避免停机:
- 使用 新 版本的 Logto 部署变更。
- 用新版本替换正在运行的实例。
我们建议在开始前备份数据库。
始终使用你要升级到的版本自带的 CLI 部署变更,比如新的 Docker 镜像或新的发布 tarball。变更脚本与 CLI 一起打包,旧的 CLI 无法部署新版本 Logto 的变更。
你可以一次跨多个版本升级。部署目标版本的变更时,会按顺序部署所有中间版本的变更。
升级前的准备
- 阅读所有版本的发布说明,从你当前版本到目标版本之间的每个版本。
- 备份你的数据库(推荐),例如使用
pg_dump或数据库服务商的快照。变更可以回滚,但备份是最可靠的恢复方式。 - 锁定目标版本。 使用精确的版本号,如
ghcr.io/logto-io/logto:1.45.0,而不是latest。如果用latest,重启或拉取新镜像可能会在变更部署前升级 Logto,导致 Logto 无法启动。 - 检查 Node.js 要求,如果你直接用 Node.js 运行 Logto。每个发布版本在其
package.json的engines字段声明了要求。例如,Logto 1.45.0 需要 Node.js^22.14.0。 - 检查你的自定义连接器,如果有的话。参见 升级后自定义连接器被跳过。
- 先升级预发布环境,如果你有独立数据库的预发布环境。如果预发布环境与生产环境共用数据库,从预发布环境部署变更也会更改生产数据库。运行旧版本的生产实例仍可正常工作,因为变更与旧版本兼容。
升级步骤
以下示例中,1.45.0 是目标版本。请用你自己的版本号和数据库 URL 替换。
Docker
-
拉取新镜像:
docker pull ghcr.io/logto-io/logto:1.45.0 -
使用新镜像部署变更。在此步骤中,你当前的 Logto 容器会继续运行:
docker run --rm \-e DB_URL=postgres://username:password@your_postgres_url:port/db_name \ghcr.io/logto-io/logto:1.45.0 \alteration deploy 1.45.0你应该会看到类似如下的输出。变更的数量和名称取决于你跨越的版本:
info Deploy target 1.45.0info Found 1 alteration to deployinfo Run alteration 1.45.0-1791531333-add-tenant-viewer-role.js `up()` function succeeded备注:镜像的 entrypoint 是
npm run,所以镜像名后的参数会传递给npm run。请写alteration deploy 1.45.0,不要写npm run alteration deploy 1.45.0。 -
用新镜像替换正在运行的容器。保持端口、环境变量等参数不变:
docker stop logto && docker rm logtodocker run -d --name logto \-p 3001:3001 \-p 3002:3002 \-e DB_URL=postgres://username:password@your_postgres_url:port/db_name \ghcr.io/logto-io/logto:1.45.0
Docker Compose
-
在 Compose 文件中更新 Logto 服务的镜像标签,然后拉取:
services:logto:image: ghcr.io/logto-io/logto:1.45.0docker compose pull logto -
在新镜像的一次性容器中部署变更:
docker compose run --rm --entrypoint sh logto -c "npm run alteration deploy 1.45.0"将
logto替换为你 Compose 文件中 Logto 服务的名称(示例docker-compose.yml中命名为app)。覆盖 entrypoint 可以让命令在服务自定义了entrypoint时也能正常运行,如示例文件所示。 -
用新镜像重新创建 Logto 容器:
docker compose up -d logto
如果你只运行单个 Logto 实例,可以让容器在每次启动时自动初始化新数据库并部署变更:
services:
logto:
image: ghcr.io/logto-io/logto:1.45.0
entrypoint:
['sh', '-c', 'npm run cli db seed -- --swe && npm run alteration deploy latest && npm start']
这里的 latest 指镜像中包含的最新版本,因此变更总是与运行的镜像匹配。不要在多实例场景下使用此方法。原因见 Kubernetes。
如果你的配置基于示例 docker-compose.yml,其中的 Postgres 容器数据存储在匿名卷中。匿名卷在 docker compose down 后不会再次挂载,因此下次 docker compose up 会以空数据库启动。在运行 docker compose down 前,请将数据迁移到命名卷或外部数据库。
Kubernetes
用 Job 部署一次变更,然后发布新镜像。
-
创建一个 Job,使用新镜像运行变更:
apiVersion: batch/v1kind: Jobmetadata:name: logto-alteration-1-45-0spec:backoffLimit: 0template:spec:restartPolicy: Nevercontainers:- name: alterationimage: ghcr.io/logto-io/logto:1.45.0command: ['/bin/sh', '-c', 'npm run alteration deploy 1.45.0']env:- name: DB_URLvalueFrom:secretKeyRef:name: logtokey: db-url应用并等待完成:
kubectl apply -f logto-alteration-job.yamlkubectl wait --for=condition=complete job/logto-alteration-1-45-0 --timeout=10mkubectl logs job/logto-alteration-1-45-0 -
更新 Logto Deployment 的镜像并等待发布。如果你的 Deployment 有使用 Logto 镜像的 init 容器(如 共享连接器文件夹 示例),也要一并更新:
kubectl set image deployment/logto logto=ghcr.io/logto-io/logto:1.45.0kubectl rollout status deployment/logto
如果你用 Helm 或 GitOps 工具部署,请在 Deployment 更新前运行 Job,例如作为 Helm 的 pre-upgrade hook 或 Argo CD 的 PreSync hook。
只从一个地方部署变更。CLI 在部署变更时不会锁定数据库,所以不要在每个副本的启动命令中都部署变更。
Node.js
如果你用 npm init @logto 或发布 tarball 安装了 Logto,请在当前版本旁边安装新版本。在升级完成前保留当前目录,以便快速切换回去。
-
确保你的 Node.js 版本满足新版本的要求。
-
下载并解压新版本:
curl -fL -o logto-1.45.0.tar.gz https://github.com/logto-io/logto/releases/download/v1.45.0/logto.tar.gzmkdir logto-1.45.0tar -xzf logto-1.45.0.tar.gz -C logto-1.45.0 --strip-components=1要获取最新版本,也可以运行
npm init @logto@latest -- --path ./logto-new --skip-seed。--skip-seed参数是必须的,因为你的数据库已经存在。 -
从当前安装目录(默认
~/logto)复制配置文件:cp ~/logto/.env logto-1.45.0/.env -
官方连接器已包含在发布包中。如果你添加了其他连接器,请再次添加到新目录,例如:
cd logto-1.45.0npm run cli connector add <connector-package-name> -
从新目录部署变更。CLI 会从
.env文件读取DB_URL:npm run alteration deploy 1.45.0 -
停止当前 Logto 进程,并从新目录启动新版本:
npm start如果你使用 systemd 或 pm2 等进程管理器,请将其工作目录更新为新目录。
托管服务商
如果你通过托管服务商的一键模板部署了 Logto,请将 Logto 镜像标签改为目标版本。在新版本启动前,使用服务商的一次性命令或 shell 功能,用新镜像运行 npm run alteration deploy 1.45.0 部署变更。对于单实例,也可以使用 Docker Compose 提示 中的启动命令。模板由服务商维护,具体细节请查阅其文档。
回滚
如果新版本未按预期工作:
-
切换回旧版本。 由于变更与旧版本 Logto 兼容,通常可以直接运行旧版本,无需更改数据库。此方法仅适用于目标版本的前一个版本。如果你跨多个版本升级,还需回滚变更。
-
回滚变更。 用 新 版本运行回滚,因为旧版本不包含新变更脚本。然后再启动旧版本。例如,使用 Docker:
docker run --rm \-e DB_URL=postgres://username:password@your_postgres_url:port/db_name \ghcr.io/logto-io/logto:1.45.0 \alteration rollback 1.44.0回滚后,未重新部署变更前新版本将无法启动。详情见 回滚变更。
-
恢复备份,如果你做了备份。这是最可靠的方式,但备份后写入的数据会丢失。
故障排查
升级后 Logto 无法启动
如果日志显示 Undeployed database alterations found,请按 升级步骤 部署变更。
如果你已经部署了变更但仍看到此错误,很可能是用旧版 CLI 部署的,比如全局安装的 logto 命令或 npx @logto/cli 解析到旧版本。这种情况下,CLI 会提示 Found 0 alteration to deploy,因为它不知道有新变更。请用新版本的 CLI 重新部署变更:新 Docker 镜像、新发布目录,或 npx @logto/cli@1.45.0 db alteration deploy 1.45.0。
重启后 Logto 启动失败
如果你使用 latest 标签,重启或拉取新镜像可能在未部署变更的情况下升级了 Logto。请用当前运行的镜像部署变更,然后锁定精确版本以避免意外升级。
Error: Missing target version
没有交互式终端时,CLI 无法询问要部署哪个版本。请显式传递目标版本,如 alteration deploy 1.45.0,或用 alteration deploy latest 部署到 CLI 包含的最新版本。
npm error Missing script: "npm"
你在 docker run 的镜像名后写了 npm run alteration ...。镜像的 entrypoint 已经是 npm run,所以只需传递 alteration deploy 1.45.0。
变更失败
每个变更都在事务中运行,因此失败不会留下部分更改。修复原因后再次运行相同命令。已部署的变更会被跳过。常见原因:
- 语句超时。 对大型表的变更可能超过默认 60 秒的语句超时。为变更命令设置
DATABASE_STATEMENT_TIMEOUT(单位毫秒),或设置为DISABLE_TIMEOUT。 - 数据库权限。 用与你初始化数据库时相同权限的数据库用户运行变更。
少数变更包含在事务外运行的步骤。如果错误信息提示非事务步骤可能已被应用,请在再次运行命令前检查数据库状态。
升级后自定义连接器被跳过
Logto 会检查每个连接器是否支持 Logto 捆绑的 @logto/connector-kit 版本。如果不支持,Logto 会跳过并记录日志:
[load-connector] skip <connector-name> due to error: Connector requires @logto/connector-kit to be <range>, but the version here is <version>.
请更新连接器以支持新的 @logto/connector-kit 版本。设置 IGNORE_CONNECTOR_VERSION_CHECK=1 可以跳过检查,但强烈不建议在生产环境使用。
这也可能发生在 共享连接器文件夹 中的官方连接器:npm run cli connector add -- --official 会从 npm 下载最新版连接器,可能需要更高版本的 Logto。此时请升级 Logto,或直接使用 Docker 镜像自带的官方连接器而不是共享文件夹。
npm init @logto 删除了新目录
如果你在已有数据库上运行 npm init @logto 且未加 --skip-seed,因为数据库已存在,初始化失败,CLI 会删除刚创建的目录。你的数据库不会被更改。请加上 --skip-seed 重新运行命令。