OpenProject Docker 数据库迁移指南:将 all-in-one 容器从 MySQL 平滑迁移到 PostgreSQL
【免费下载链接】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 官方 all-in-one Docker 镜像部署、当前以 MySQL 为底层数据库的安装实例,详细讲解如何借助镜像内置的 pgloader 迁移脚本,将全部数据平滑迁移到 PostgreSQL,并在迁移后恢复正常容器启动流程。读完本文,你将掌握从备份、搭建目标 PostgreSQL、配置MYSQL_DATABASE_URL与DATABASE_URL环境变量、执行迁移到迁移后清理的完整操作链路,并理解迁移脚本在镜像中的底层实现原理。
迁移方案概述与原理
OpenProject 官方 Docker 镜像(all-in-one 容器)内置了一套基于 pgloader 的 MySQL → PostgreSQL 迁移方案。其核心思路是:
- 容器内同时预置 MySQL 与 PostgreSQL 客户端;
- 通过两个环境变量分别指定「迁移源」(MySQL)与「迁移目标」(PostgreSQL)的连接信息;
- 启动容器时由迁移入口脚本自动执行数据搬运,并将过程反馈给你。
从仓库的镜像构建配置可以印证这一设计。在 docker/prod/mysql-to-postgres/Dockerfile 中可以看到:
- 镜像安装
mysql-client与postgresql-client,保证迁移期间两种数据库客户端均可用; - 通过
COPY docker/mysql-to-postgres/bin/build /tmp/build-pgloader在镜像构建阶段编译 pgloader(bin/build脚本位于 docker/prod/mysql-to-postgres/bin/build); - 通过
COPY docker/mysql-to-postgres/bin/migrate-mysql-to-postgres /usr/local/bin/将迁移脚本安装为可执行命令; - 该层镜像的默认入口(
CMD ["migrate-mysql-to-postgres"])就是迁移脚本本身。
因此,当你带着迁移环境变量启动官方镜像时,容器会自动执行内置的migrate-mysql-to-postgres脚本,全程无需手工安装 pgloader。OpenProject 还提供了一套自定义构建的 pgloader(pgloader-ccl),其中嵌入了针对大型 MySQL 数据库迁移的内存优化,可参考同仓库的打包版迁移指南 docs/installation-and-operations/misc/packaged-postgresql-migration/README.md 了解其背景。
第一步:迁移前备份当前安装
任何数据库迁移都存在风险,开始前请务必为现有安装创建一份完整备份。针对 Docker 部署,备份要点如下(详细步骤见 docs/installation-and-operations/operation/backing-up/README.md):
- 使用 docker-compose 的场景:数据卷由 Docker 管理,需按 Docker 卷备份的常规方式处理,例如从数据库容器导出逻辑备份:
docker exec -it db_1 pg_dump -U postgres -d openproject -x -O > openproject.sql以上命令假设数据库容器名为
db_1;实际名称可通过docker ps | grep postgres确认。
- 使用 all-in-one 容器的场景:备份你在启动容器时通过
-v绑定的本地数据卷(如pgdata、assets目录),并可将数据库单独导出为逻辑备份:
docker exec -it $OP_CONTAINER_NAME su - postgres -c 'pg_dump -d openproject -x -O' > openproject.sql其中$OP_CONTAINER_NAME为你的 OpenProject 容器名,可用docker ps | grep openproject查找。备份完成后,建议将归档文件复制到安全的异地位置(如对象存储或备份服务器),以防迁移中途出现不稳定状态时能够回滚。
第二步:准备目标 PostgreSQL 数据库
迁移的目标是一个 PostgreSQL 数据库。根据你的使用场景有两种选择:
- 使用容器内置 PostgreSQL 实例:all-in-one 镜像内部自带配置好的 PostgreSQL,可直接使用连接串
postgres://openproject:openproject@127.0.0.1/openproject,无需任何额外搭建; - 使用外部 PostgreSQL 数据库:在容器之外搭建独立 PostgreSQL,并像当初提供 MySQL 连接信息一样,把连接信息交给容器。
如果选择在宿主机(容器外)搭建 PostgreSQL,以下是通用的基于 apt 的安装步骤,请按你的发行版适当调整:
1. 安装 PostgreSQL(OpenProject 要求至少 PostgreSQL 9.5)
[root@host] apt-get install postgresql postgresql-contrib libpq-dev如果发行版自带包过旧,需要从上游获取更新版本的安装包。
2. 切换到 PostgreSQL 系统用户
[root@host] su - postgres3. 以 PostgreSQL 用户创建 OpenProject 的系统用户
[postgres@host] createuser -W openproject命令会提示你设置密码。下文示例统一假设密码为openproject,实际使用请务必选择强密码,并将指南中的占位值全部替换为你的真实密码。
4. 创建由该用户拥有的数据库
[postgres@host] createdb -O openproject openproject5. 退出 PostgreSQL 系统用户
[postgres@host] exit # 你现在又回到 root 了。第三步:配置迁移所需的环境变量
运行镜像内置迁移部分时,需要为容器提供两个环境文件/变量,分别指向迁移源与迁移目标。
3.1 迁移源:MYSQL_DATABASE_URL
记下(或复制)当前 MySQL 的DATABASE_URL,形如:
# 大致如下 # mysql2://user:password@localhost:3306/dbname # 传入容器时,将 mysql2 替换为 mysql! MYSQL_DATABASE_URL="mysql://user:password@localhost:3306/dbname"重要提醒:该 URL 必须以
mysql://开头,而不是mysql2://!这是因为迁移脚本(pgloader)需要的是标准的 MySQL 协议连接串,而mysql2://是 Ruby 生态中 mysql2 适配器的专有前缀,二者不可混用。
3.2 迁移目标:DATABASE_URL
传入指向新 PostgreSQL 数据库的DATABASE_URL。它可以是容器内置库的默认值postgres://openproject:openproject@127.0.0.1/openproject,也可以是你按上文搭建的外部 PostgreSQL 的连接信息:
POSTGRES_DATABASE_URL="postgresql://<USER>:<PASSWORD>@<HOST>/<Database name>"如果密码中包含特殊字符,需要注意在数据库 URL 中进行百分号编码(percent-encoding)。例如打包版指南中提供了一行 Ruby 命令用于转义密码:
openproject run ruby -r cgi -e "puts CGI.escape('your-password-here');"Docker 场景下可借助任意支持 URL 编码的方式先处理密码,再拼接进DATABASE_URL。
3.3 适配主机名:localhost与host.docker.internal
注意:取决于你的 Docker 安装方式与网络配置,数据库 URL 中的主机名localhost可能需要替换为host.docker.internal才能访问 Docker 宿主机。例如在 macOS 上,localhost指向的是 Docker 客户端(即容器自身)而非宿主机。请根据你的 Docker 网络环境选择正确的地址。
第四步:运行迁移
准备好上述两个环境变量后,直接运行以下命令(将环境变量内容替换为你的实际值):
docker run -it \ -e MYSQL_DATABASE_URL="mysql://user:password@localhost:3306/dbname" \ -e DATABASE_URL="postgresql://openproject:<PASSWORD>@localhost:5432/openproject" \ openproject/openproject:latest镜像启动后会自动完成迁移所需的全部步骤,包括:
- 检测到
MYSQL_DATABASE_URL的存在,触发内置的migrate-mysql-to-postgres迁移入口(即 docker/prod/mysql-to-postgres/Dockerfile 中CMD指定的脚本); - 使用 pgloader 将 MySQL 中的数据、表结构与索引搬运至目标 PostgreSQL;
- 在交互终端中向你输出迁移进度与后续操作提示。
迁移耗时取决于当前安装的数据量,大型数据库可能花费较长时间,请耐心等待其完成。迁移脚本会通过容器日志明确告知你迁移状态与下一步应执行的操作。
第五步:迁移后的收尾工作
迁移成功完成后,需要移除迁移专用的MYSQL_DATABASE_URL环境变量,并按正常方式启动容器:
docker run -d -p 8080:80 --name openproject \ -e SECRET_KEY_BASE=<your-secret-key-base> \ -e DATABASE_URL="postgresql://openproject:<PASSWORD>@localhost:5432/openproject" \ -v /var/lib/openproject/pgdata:/var/openproject/pgdata \ -v /var/lib/openproject/assets:/var/openproject/assets \ openproject/openproject:latest要点:
- 启动时不再传入
MYSQL_DATABASE_URL,否则容器会再次进入迁移流程; - 保留指向 PostgreSQL 的
DATABASE_URL(若使用内置库则保留默认值即可); - 若此前使用了绑定数据卷,务必保持原有
-v参数不变,确保附件等文件数据不丢失。
自此,你的 OpenProject 容器便运行在 PostgreSQL 之上。若将来需要再次迁移或回滚,请先恢复第一步中的备份归档,再重复上述流程。
常见问题与注意事项汇总
| 问题/场景 | 处理方式 |
|---|---|
MYSQL_DATABASE_URL必须以什么协议前缀开头? | 必须以mysql://开头,不能是mysql2:// |
| 数据库 URL 中密码含特殊字符 | 先对密码做百分号编码,再拼入 URL |
| 容器访问宿主机数据库失败 | 将 URL 中localhost替换为host.docker.internal(如 macOS 环境) |
| 迁移后容器又执行迁移 | 检查是否仍残留MYSQL_DATABASE_URL环境变量,务必移除 |
| 迁移耗时长 | 属正常现象,OpenProject 对 pgloader 做了内存优化(pgloader-ccl),请耐心等待完成 |
| PostgreSQL 版本要求 | OpenProject 要求至少 PostgreSQL 9.5 |
此外,若你使用的是 DEB/RPM 打包安装(而非 Docker)的 OpenProject,可参考同仓库的 docs/installation-and-operations/misc/packaged-postgresql-migration/README.md,其中覆盖了openproject config:set MYSQL_DATABASE_URL、sudo openproject run ./docker/mysql-to-postgres/bin/migrate-mysql-to-postgres、openproject reconfigure及可选卸载 MySQL 等打包版专属步骤;其备份归档说明(数据库 dump、附件、配置文件、仓库的打包)对理解迁移前应保留哪些数据也很有参考价值。
小结
本指南完整覆盖了 Docker all-in-one OpenProject 从 MySQL 迁移到 PostgreSQL 的五个核心环节:备份、搭建目标库、配置双环境变量、执行迁移与迁移后收尾。整个过程由镜像内置的 pgloader 迁移脚本自动驱动(见 docker/prod/mysql-to-postgres/Dockerfile 及 docker/prod/mysql-to-postgres/bin/build),你只需正确提供MYSQL_DATABASE_URL与DATABASE_URL两个连接串,即可在最小人工干预下完成数据库底座的切换。
【免费下载链接】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),仅供参考