跳到主要内容

升级你的 OSS 版本

Logto 遵循 semver。你可以在 GitHub Releases 中找到每个版本及其变更。本指南解释了升级的工作原理、如何升级每种常见的部署方式,以及如何解决你可能遇到的问题。

升级的工作原理​

一次升级包含两个部分:

  1. Logto 代码:你运行的 Docker 镜像或发布的 tarball。
  2. 数据库结构:不同版本之间的结构变更以数据库变更的形式发布,你需要使用 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 兼容,因此仍在运行旧版本的实例在变更部署后可以继续工作。这样可以按照以下顺序操作,避免停机:

  1. 使用 新 版本的 Logto 部署变更。
  2. 用新版本替换正在运行的实例。

我们建议在开始前备份数据库。

信息:

始终使用你要升级到的版本自带的 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​

  1. 拉取新镜像:

    docker pull ghcr.io/logto-io/logto:1.45.0
  2. 使用新镜像部署变更。在此步骤中,你当前的 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.0
    info Found 1 alteration to deploy
    info 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。

  3. 用新镜像替换正在运行的容器。保持端口、环境变量等参数不变:

    docker stop logto && docker rm logto
    docker 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​

  1. 在 Compose 文件中更新 Logto 服务的镜像标签,然后拉取:

    services:
    logto:
    image: ghcr.io/logto-io/logto:1.45.0
    docker compose pull logto
  2. 在新镜像的一次性容器中部署变更:

    docker compose run --rm --entrypoint sh logto -c "npm run alteration deploy 1.45.0"

    将 logto 替换为你 Compose 文件中 Logto 服务的名称(示例 docker-compose.yml 中命名为 app)。覆盖 entrypoint 可以让命令在服务自定义了 entrypoint 时也能正常运行,如示例文件所示。

  3. 用新镜像重新创建 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 部署一次变更,然后发布新镜像。

  1. 创建一个 Job,使用新镜像运行变更:

    apiVersion: batch/v1
    kind: Job
    metadata:
    name: logto-alteration-1-45-0
    spec:
    backoffLimit: 0
    template:
    spec:
    restartPolicy: Never
    containers:
    - name: alteration
    image: ghcr.io/logto-io/logto:1.45.0
    command: ['/bin/sh', '-c', 'npm run alteration deploy 1.45.0']
    env:
    - name: DB_URL
    valueFrom:
    secretKeyRef:
    name: logto
    key: db-url

    应用并等待完成:

    kubectl apply -f logto-alteration-job.yaml
    kubectl wait --for=condition=complete job/logto-alteration-1-45-0 --timeout=10m
    kubectl logs job/logto-alteration-1-45-0
  2. 更新 Logto Deployment 的镜像并等待发布。如果你的 Deployment 有使用 Logto 镜像的 init 容器(如 共享连接器文件夹 示例),也要一并更新:

    kubectl set image deployment/logto logto=ghcr.io/logto-io/logto:1.45.0
    kubectl rollout status deployment/logto

如果你用 Helm 或 GitOps 工具部署,请在 Deployment 更新前运行 Job,例如作为 Helm 的 pre-upgrade hook 或 Argo CD 的 PreSync hook。

注意:

只从一个地方部署变更。CLI 在部署变更时不会锁定数据库,所以不要在每个副本的启动命令中都部署变更。

Node.js​

如果你用 npm init @logto 或发布 tarball 安装了 Logto,请在当前版本旁边安装新版本。在升级完成前保留当前目录,以便快速切换回去。

  1. 确保你的 Node.js 版本满足新版本的要求。

  2. 下载并解压新版本:

    curl -fL -o logto-1.45.0.tar.gz https://github.com/logto-io/logto/releases/download/v1.45.0/logto.tar.gz
    mkdir logto-1.45.0
    tar -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 参数是必须的,因为你的数据库已经存在。

  3. 从当前安装目录(默认 ~/logto)复制配置文件:

    cp ~/logto/.env logto-1.45.0/.env
  4. 官方连接器已包含在发布包中。如果你添加了其他连接器,请再次添加到新目录,例如:

    cd logto-1.45.0
    npm run cli connector add <connector-package-name>
  5. 从新目录部署变更。CLI 会从 .env 文件读取 DB_URL:

    npm run alteration deploy 1.45.0
  6. 停止当前 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/[email protected] 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 重新运行命令。