OpenProject 打包安装(DEB/RPM)迁移至 Docker Compose 完整指南:备份、SECRET_KEY_BASE 复用与数据库版本迁移实战
2026/9/14 21:42:21 网站建设 项目流程

OpenProject 打包安装(DEB/RPM)迁移至 Docker Compose 完整指南:备份、SECRET_KEY_BASE 复用与数据库版本迁移实战

【免费下载链接】openprojectOpenProject is the leading open source project management software for product, project and portfolio management. A powerful Jira alternative with agile planning, issue tracking, roadmaps, Gantt charts, time tracking, collaboration features, and more. Available on premises or in the cloud. ⭐ Star us on GitHub项目地址: https://gitcode.com/GitHub_Trending/op/openproject

本指南基于 OpenProject 官方文档 packaged-docker-migration,系统讲解如何将基于 DEB/RPM 包的 OpenProject 实例平滑迁移到 Docker Compose 部署。你将掌握完整 7 步迁移流程:打包备份、SECRET_KEY_BASE复用、Compose 栈搭建、跨大版本数据库转储迁移(bin/migrate)、数据库与附件恢复,以及迁移后的启动验证与故障排查,最终在不停摆业务、不丢失会话的前提下完成部署形态切换。

背景:为什么官方推荐从打包安装迁移到 Docker Compose

OpenProject 的打包安装(DEB/RPM)长期是自托管的主流方式,但官方已在多个层面明确其维护边界:

  • 在 打包安装文档 中明确声明:不再为新的 Linux 发行版构建软件包(例如 Ubuntu 24.04),仅对已支持发行版持续发布至其 EOL(生命周期结束)。
  • 当发行版到达 EOL 后,软件包源将不再更新,打包安装的 OpenProject 将无法获得新版本的安全修复与功能升级。
  • 因此官方推荐将存量打包实例迁移到Docker Compose(或 Kubernetes),这是后续获得持续更新的可行路径。

值得注意的是,较旧的 OpenProject 版本依然可以迁移——你不需要被困在旧打包版本上。迁移到 Docker Compose 后,你的实例将直接进入当前维护版本,并可通过docker compose pull && docker compose up -d这类方式持续升级(参见 升级文档 的 Compose 升级小节)。

整个迁移过程分为 7 个阶段:

  1. 备份打包安装
  2. 检索并复用SECRET_KEY_BASE
  3. 用 Docker Compose 安装 OpenProject
  4. 为目标版本准备数据库转储(跨大版本迁移)
  5. 将数据库恢复进 Docker Compose
  6. 恢复附件
  7. 启动 OpenProject 并验证

下文逐一展开。

Step 1:备份打包安装

迁移的第一步是创建当前打包实例的完整备份,并存放于安全位置(如独立的备份服务器或对象存储)。打包安装自带备份工具,官方备份流程详见 package-based backup guide。

核心命令:

sudo openproject run backup

备份文件默认生成在/var/db/openproject/backup目录下,典型产物如下(时间戳因备份时刻而异):

postgresql-dump-<timestamp>.pgdump # 数据库备份(PostgreSQL 二进制/自定义格式) attachments-<timestamp>.tar.gz # 附件 / 上传文件 conf-<timestamp>.tar.gz # 打包安装配置(含密钥) git-repositories-<timestamp>.tar.gz # Git 仓库数据(如使用) svn-repositories-<timestamp>.tar.gz # SVN 仓库数据(如使用)

关键:额外生成一份纯文本 SQL 备份

打包备份中的postgresql-dump-<timestamp>.pgdump使用 PostgreSQL 的binary/custom 备份模式。这种格式在打包环境与 Docker Compose 环境的 PostgreSQL 大版本不一致时,恢复可能失败。因此官方要求额外用pg_dump导出一份纯文本 SQL 备份:

pg_dump $(sudo openproject config:get DATABASE_URL) -x -O > openproject.sql

参数说明:

  • $(sudo openproject config:get DATABASE_URL):动态读取打包实例的数据库连接串(形如postgres://user:pass@host:port/dbname);
  • -x:不导出权限/授权(grants),避免跨环境权限差异报错;
  • -O:不设置对象所有者(no-owner),避免目标库角色不一致;
  • 输出重定向为纯文本openproject.sql,该文件可直接被psql导入。

后续步骤你需要使用这份纯文本 SQL dump以及打包备份中的attachments-<timestamp>.tar.gz归档。其余产物(conf-*、仓库归档)在 Docker Compose 迁移中不直接使用,但应妥善留存以防需要回退。

Step 2:检索并复用SECRET_KEY_BASE

SECRET_KEY_BASE是 Rails 密钥派生输入,用于生成会话 Cookie、提醒与邀请令牌以及其他签名值。如果迁移后改变了该值,所有用户会话将失效,部分令牌(邀请、提醒等)需要重新签发。因此复用原值可让现有用户无感切换。

在打包安装上检索现有值:

sudo openproject config:get SECRET_KEY_BASE

若返回为空,尝试旧式变量名(旧版打包安装中两者通常设为相同值):

sudo openproject config:get SECRET_TOKEN

打包安装历史上同时暴露SECRET_KEY_BASESECRET_TOKEN两个变量;而 Docker Compose 部署只使用SECRET_KEY_BASE。建议沿用原值,以保证已有会话和令牌持续有效。若强制生成新值,所有用户会话将被注销,部分令牌(如邀请、提醒令牌)在重新签发前失效。

获取到的值将在下一步写入 Docker Compose 的.env文件中。

Step 3:用 Docker Compose 安装 OpenProject

在目标主机上部署一套全新的 Docker Compose 栈。生产环境的 Compose 配置由官方openproject-docker-compose仓库单独维护(本仓库根目录的 docker-compose.yml 为开发环境版本,其中通过LOCAL_DEV_CHECK环境变量注释明确指出了这一仓库拆分)。请按其说明克隆仓库并创建你的.env文件。

在首次启动前,.env中至少要设置两项:

SECRET_KEY_BASE=<value from step 2> OPENPROJECT_HOST__NAME=<your public hostname>
  • SECRET_KEY_BASE:填入第 2 步从打包实例取回的原值;
  • OPENPROJECT_HOST__NAME:实例的对外公开主机名(注意 OpenProject 环境变量中__双下划线代表配置层级分隔,此处即host_name配置项)。

然后启动栈一次,让数据卷和数据库容器先创建出来:

docker compose up -d

启动后确认前端服务正常起来——此刻应出现一个全新的空实例(首启会自动执行数据库初始化和 seed,见下文seeder说明)。这是预期状态,后续步骤会用打包实例的数据库和附件替换掉这份空数据。

关于 Compose 栈的服务构成,可参考仓库根 docker-compose.yml(开发版)与 docker/prod 目录下的生产入口脚本:栈包含db(PostgreSQL 17,卷pgdata)、webworkercronseeder等服务;附件存放在opdata卷中并挂载到容器内/var/openproject/assets。其中 seeder 入口脚本 的逻辑清晰印证了首启行为:数据库无表时执行rake db:structure:load初始化,非空时执行rake db:migrate,随后执行rake db:seed

本指南聚焦 Docker Compose 安装方式,因为官方推荐将其用于生产迁移场景。all-in-one 单容器镜像的恢复路径在 Backup Restoring Guide 中单独说明。

Step 4:为目标版本准备数据库转储(跨大版本迁移)

为什么需要这一步

Docker Compose 栈安装的是当前 OpenProject 大版本。而 OpenProject无法总是将数据库转储跨多个大版本一步迁移到位——官方支持从一个主版本迁移到下一个主版本,跳级迁移不被支持(详见 升级文档 的说明)。

如果你把较旧打包版本(例如 13.x)的转储直接导入当前 Compose 栈,seeder服务可能崩溃并反复重启(crash-loop),且不给出清晰错误,排查成本很高。

使用bin/migrate脚本

对于OpenProject 10.x 及以上的转储,仓库提供了 bin/migrate 脚本。它会启动临时 Docker 容器,按大版本逐级应用迁移,直到转储与当前版本匹配。

下载并执行(或直接克隆 OpenProject 仓库使用bin/migrate):

# 下载脚本(或克隆 OpenProject 仓库) curl -fsSL -o migrate https://raw.githubusercontent.com/opf/openproject/dev/bin/migrate chmod +x migrate # 迁移你的 SQL 转储 ./migrate /path/to/openproject.sql

执行完毕后会生成形如openproject-migrated.sql.gz的迁移后转储,供下一步导入使用。

从源码看bin/migrate的实现原理

阅读 bin/migrate 源码,其工作流程清晰可见:

  1. 启动临时 PostgreSQL 17 容器(容器名op-migrate-pg17),等待数据库就绪;

  2. 创建目标数据库并预装 OpenProject 依赖的扩展:

    CREATE EXTENSION IF NOT EXISTS btree_gist WITH SCHEMA pg_catalog; CREATE EXTENSION IF NOT EXISTS pg_trgm WITH SCHEMA pg_catalog; CREATE EXTENSION IF NOT EXISTS unaccent WITH SCHEMA pg_catalog;

    脚本注释说明:虽然理论上迁移本身会处理扩展,但实践中即使对 v16 级别的转储,缺少这些扩展也会导致迁移失败;

  3. 导入转储,并在导入管道中执行sed 's/OWNER TO openproject/OWNER TO postgres/g',把打包环境常见的OWNER TO openproject所有权语句改写为postgres,规避目标库角色缺失问题;

  4. 版本校验:查询schema_migrations表中2020%前缀的最大版本号,若为空则报错“版本早于 10”,并提示改用script/migrate/migrate-from-pre-8.sh

  5. 逐版本迁移循环:从脚本内定义的起始大版本(当前为OP_VERSION=15)开始,依次docker pull openproject/openproject:<N>并用该镜像执行bundle exec rake db:migrate;若报PG::DuplicateTable ... "work_packages" already exists,说明转储已超过该版本,继续尝试下一版本;否则迁移成功;

  6. 处理迁移入队的后台任务:通过rails runner执行 GoodJob 队列中迁移期间新产生的后台任务,确保数据一致性;

  7. 输出迁移结果:默认输出 gzip 压缩的 SQL({输入}-migrated.sql.gz),指定-f pgdump时输出自定义格式({输入}-migrated.pgdump);支持-n/--change-schema-name在导出前重命名 schema。

完整参数说明

脚本用法(详见 Step-wise database migration script):

./bin/migrate [OPTIONS] <dump-file>
选项说明
-n, --change-schema-name NAME导出前将 PostgreSQL schema 重命名为NAME(默认public
-f, --format FORMAT输出格式:sql(默认,gzip 压缩)或pgdump(自定义/二进制格式)

示例:

# 迁移到最新版本(默认 SQL gzip 输出) ./bin/migrate openproject-10.5.sql # 输出 PostgreSQL 自定义格式 ./bin/migrate -f pgdump openproject-10.5.sql # 迁移并重命名 schema ./bin/migrate -n custom_schema openproject-10.5.sql # 组合使用 ./bin/migrate -f pgdump -n custom_schema openproject-10.5.sql

输出文件名规则:SQL 格式为{输入}-migrated.sql.gz;pgdump 格式为{输入}-migrated.pgdump

脚本使用注意事项:

  • 需要本机已安装并运行 Docker,且能访问 Docker Hub(按需拉取各版本镜像);
  • 只接受 OpenProject10.x 及以后的纯文本 SQL 转储;更早版本需先使用script/migrate/migrate-from-pre-8.sh
  • 迁移耗时与数据库体积、跨越版本数量正相关;
  • 脚本在退出时(含出错)会自动清理临时容器与临时文件;
  • 若打包实例与 Compose 目标已是同一大版本(或仅落后一个大版本),可跳过本步骤直接导入openproject.sql;不确定时优先运行bin/migrate,这是旧打包版本更稳妥的路径。

Step 5:将数据库恢复进 Docker Compose

在 Compose 栈至少启动过一次之后(此时db容器与pgdata卷已存在),即可将(迁移后的)SQL 转储导入db容器。以下步骤与 Using Docker Compose 的恢复指南一致。

在包含docker-compose.yml的目录下执行:

# 1. 停止应用进程,避免导入期间数据库被写入: docker compose stop web worker cron seeder # 2. 删除并重建数据库(Compose 默认以 postgres 超级用户连接) # 使用 FORCE 标志确保即使仍有进程连接也能断开后删除 docker compose exec -T db psql -U postgres -c 'DROP DATABASE IF EXISTS openproject WITH (FORCE);' docker compose exec -T db psql -U postgres -c 'CREATE DATABASE openproject OWNER postgres;' # 3. 导入转储(适用时使用第 4 步的迁移后转储) # 纯文本 .sql 文件: docker compose exec -T db psql -U postgres -d openproject < openproject-migrated.sql # bin/migrate 产生的 gzip 转储: gunzip -c openproject-migrated.sql.gz | docker compose exec -T db psql -U postgres -d openproject

关于所有权报错:使用pg_dump -x -O导出的转储(或bin/migrate产物)在导入时出现的、指向打包环境openproject角色的所有权提示通常可以忽略。如果你的转储确实依赖该角色,先创建它再导入:

docker compose exec -T db psql -U postgres -c "DO \$\$ BEGIN CREATE ROLE openproject LOGIN; EXCEPTION WHEN duplicate_object THEN NULL; END \$\$;"

Step 6:恢复附件

打包备份将附件存放在attachments-<timestamp>.tar.gz中。在 Docker Compose 部署里,附件位于opdata卷,挂载进应用容器后对应/var/openproject/assets。需要将归档解压到该卷的files子目录下。

场景 A:使用绑定挂载的资产目录

Compose 的.env.example常将OPDATA设置为/var/openproject/assets。此时:

sudo mkdir -p /var/openproject/assets/files sudo tar -xzf attachments-<timestamp>.tar.gz -C /var/openproject/assets/files sudo chown -R 1000:1000 /var/openproject/assets

场景 B:使用默认的命名 Docker 卷

先找到卷名(通常以 Compose 项目目录名作为前缀):

docker volume ls | grep opdata # 例如:openproject_opdata

再将归档解压进该卷:

docker run --rm \ -v openproject_opdata:/var/openproject/assets \ -v /path/to/backup:/backup:ro \ alpine sh -c " mkdir -p /var/openproject/assets/files && tar -xzf /backup/attachments-<timestamp>.tar.gz -C /var/openproject/assets/files && chown -R 1000:1000 /var/openproject/assets "

openproject_opdata/path/to/backup替换为你的实际卷名与备份目录。chown -R 1000:1000是让容器内以 UID/GID 1000 运行的应用用户可读写附件(恢复指南 restoring 中同样采用该权限设定)。

Docker 部署不支持 OpenProject 内建托管的 Subversion/Git 仓库。如果打包实例使用了该功能,迁移后需要将项目指向外部仓库。详见 Docker limitations。

Step 7:启动 OpenProject 并验证

对恢复后的数据运行数据库迁移/seed,然后重新拉起整个栈:

docker compose run --rm seeder docker compose up -d docker compose logs -f web worker seeder

docker compose run --rm seeder的作用可对照 seeder 入口脚本:它会对恢复进来的数据执行rake db:migrate(数据库非空分支)与rake db:seed,把数据库补齐到当前版本应有的结构与种子数据。

随后逐项确认迁移结果:

  • 可以用已有用户登录系统(尤其是复用了SECRET_KEY_BASE的场景,旧会话应保持有效);
  • 项目与工作包(work package)显示正常;
  • 附件可以正常打开与下载;
  • 后台任务正常处理,没有反复出现的 seeder 崩溃循环

如果直接导入后 seeder 仍然 crash-loop,请回到 Step 4,先用bin/migrate迁移转储,再重新导入。

常见问题与注意事项

迁移后所有用户被登出?大概率是SECRET_KEY_BASE未复用。检查.env中该值是否与打包实例一致(第 2 步取回的值)。若确实需要更换密钥,用户会重新登录,部分令牌需重新签发,属预期行为。

seeder 反复崩溃但无清晰报错?几乎可以断定是转储版本与目标大版本差距过大。回到第 4 步用bin/migrate逐版本迁移后重新导入,这是旧打包版本的标准解法。

数据库导入时出现openproject角色相关错误?第 5 步中创建该角色的命令可解决问题;-x -O转储与bin/migrate产物通常已规避此问题。

备份来自 OpenProject 云(Enterprise Cloud)?云备份的数据库 schema 为长随机名(非public),恢复前需在数据库内执行DROP SCHEMA public CASCADE; ALTER SCHEMA "<长随机名>" RENAME TO public;,详见恢复指南中的 Changing the database schema from cloud to on-premises。

想迁移到另一台打包环境而不是 Docker?参考 Migrating a packaged installation to another packaged environment 指南,其备份产物与本文第 1 步相同,但恢复方式不同(涉及/etc/openproject配置迁移与pg_restore)。

相关文档

  • Backing up —— 打包与 Docker 环境的备份方法
  • Restoring —— 含 Using Docker Compose 恢复小节
  • Upgrading —— 含 Step-wise database migration script 的bin/migrate完整参数说明
  • Install OpenProject with DEB/RPM packages —— 打包安装现状与发行版支持边界
  • OpenProject on Docker —— 含 Docker 部署的限制说明
  • bin/migrate —— 仓库内数据库分步迁移脚本源码
  • seeder —— 生产容器数据库初始化/迁移/seed 入口脚本

【免费下载链接】openprojectOpenProject is the leading open source project management software for product, project and portfolio management. A powerful Jira alternative with agile planning, issue tracking, roadmaps, Gantt charts, time tracking, collaboration features, and more. Available on premises or in the cloud. ⭐ Star us on GitHub项目地址: https://gitcode.com/GitHub_Trending/op/openproject

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询