前情提要:
请在任何操作前备份数据
开端
将 Forgejo 迁移到 PostgreSQL 的最简单方法似乎是使用 forgejo dump 命令导出数据库。但是这样做导出的数据在导入 PostgreSQL 数据库会失败,我们需要一个翻译器解决这种问题。
看其他文章推荐使用 pgloader 将数据和结构导入到空的 PostgreSQL 数据库中。不过由于错误的数据库结构,Forgejo 在导入后拒绝启动,表现为不断尝试删除无法删除的索引。
解决
这时候我们可以用一个空的 PostgreSQL 数据库启动 Forgejo,等到所有表都设置完毕,然后停止 Forgejo 进程。这时候程序在一种没有实际生产数据的状态,可以当新的实例正常使用。
然后将 pgloader 配置为仅导入数据,这样可以在不弄乱数据库结构的情况下导入生产数据:
# pgloader.load
LOAD DATABASE
FROM sqlite:///git/data/gitea/gitea.db
INTO pgsql://forgejo:forgejo@127.0.0.1/forgejo
WITH data only, reset sequences, prefetch rows = 10000
SET work_mem TO '16MB', maintenance_work_mem TO '512MB';
注意修改 sqlite:// 和 pgsql://,前者是绝对路径,后者是连接字符串。
随后使用 pgloader 加载我们的脚本:
pgloader pgloader.load
如果不出意外,在十秒内迁移将会完成。不过程序会有四个报错,均为重复键错误(duplicate key value)。在我的测试中,这四个错误可以忽略,无需人工干预:
2025-10-19T15:35:50.860000Z ERROR Database error 23505: duplicate key value violates unique constraint "version_pkey"
DETAIL: Key (id)=(1) already exists.
CONTEXT: COPY version, line 1
2025-10-19T15:35:50.876000Z ERROR Database error 23505: duplicate key value violates unique constraint "forgejo_version_pkey"
DETAIL: Key (id)=(1) already exists.
CONTEXT: COPY forgejo_version, line 1
2025-10-19T15:35:51.324000Z ERROR Database error 23505: duplicate key value violates unique constraint "oauth2_application_pkey"
DETAIL: Key (id)=(1) already exists.
CONTEXT: COPY oauth2_application, line 1
2025-10-19T15:35:52.172000Z ERROR Database error 23505: duplicate key value violates unique constraint "app_state_pkey"
DETAIL: Key (id)=(runtime-state) already exists.
CONTEXT: COPY app_state, line
启动 Forgejo 容器,这时候可以注意到成功启动,没有任何问题。至此迁移完成,如有任何问题请留言,操作前务必备份所有数据。
参考
我使用的 compose.yml(已简化),仅供参考:
services:
git:
image: codeberg.org/forgejo/forgejo:13
container_name: forgejo
environment:
- USER_UID=1000
- USER_GID=1000
restart: unless-stopped
depends_on:
- db
db:
image: postgres:14-alpine
restart: unless-stopped
environment:
- POSTGRES_USER=forgejo
- POSTGRES_PASSWORD=forgejo
- POSTGRES_DB=forgejo
ports:
- "127.0.0.1:5432:5432"