docs: update migration runbook to use gitea dump instead of pgloader
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -8,5 +8,8 @@ data/
|
|||||||
caddy_data/
|
caddy_data/
|
||||||
caddy_config/
|
caddy_config/
|
||||||
|
|
||||||
|
# 备份
|
||||||
|
backup/
|
||||||
|
|
||||||
# macOS
|
# macOS
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
|||||||
@@ -4,7 +4,9 @@
|
|||||||
|
|
||||||
迁移目标是把 `data/gitea/gitea.db` 中的业务数据导入到新的 PostgreSQL 数据库,同时继续复用现有的仓库、LFS、附件和配置目录。
|
迁移目标是把 `data/gitea/gitea.db` 中的业务数据导入到新的 PostgreSQL 数据库,同时继续复用现有的仓库、LFS、附件和配置目录。
|
||||||
|
|
||||||
> `gitea migrate` 不是 SQLite 到 PostgreSQL 的数据搬迁工具。它只会对当前 Gitea 配置指向的数据库执行 Gitea schema migration。数据库搬迁应使用 `pgloader` 完成。
|
> `gitea migrate` 不是 SQLite 到 PostgreSQL 的数据搬迁工具。它只会对当前 Gitea 配置指向的数据库执行 Gitea schema migration。
|
||||||
|
>
|
||||||
|
> Gitea 自带的跨数据库导出入口是 `gitea dump --database postgres`。Gitea 没有对应的自动 `gitea restore` 命令,恢复或导入 PostgreSQL 时需要手动解压 dump 包,并用 `psql` 导入其中的 `gitea-db.sql`。
|
||||||
|
|
||||||
## 迁移前准备
|
## 迁移前准备
|
||||||
|
|
||||||
@@ -19,12 +21,8 @@ POSTGRES_USER=gitea
|
|||||||
POSTGRES_PASSWORD=<强密码>
|
POSTGRES_PASSWORD=<强密码>
|
||||||
```
|
```
|
||||||
|
|
||||||
- 确认可以运行 `sqlite3`,并能拉取或运行 `dimitri/pgloader:latest` 镜像。
|
- 确认可以运行 `sqlite3`、`unzip`,并且 PostgreSQL 容器里可以运行 `psql`。
|
||||||
- 本文档默认 Docker Compose project 网络名为 `gitea_default`。如果实际名称不同,用下面命令查看后替换:
|
- 本文档假设 `docker-compose.yml` 把宿主机 `./data` 挂载到 Gitea 容器内的 `/data`。因此 dump 输出到容器内 `/data/gitea-dump-postgres.zip` 时,宿主机对应文件是 `data/gitea-dump-postgres.zip`。
|
||||||
|
|
||||||
```bash
|
|
||||||
docker network ls
|
|
||||||
```
|
|
||||||
|
|
||||||
## 1. 停止旧 Gitea
|
## 1. 停止旧 Gitea
|
||||||
|
|
||||||
@@ -56,7 +54,41 @@ tar -czf backups/$ts/gitea-data.tar.gz data/git data/gitea
|
|||||||
sqlite3 data/gitea/gitea.db "select 'user', count(*) from user union all select 'repository', count(*) from repository union all select 'lfs_meta_object', count(*) from lfs_meta_object union all select 'public_key', count(*) from public_key union all select 'issue', count(*) from issue union all select 'release', count(*) from release;"
|
sqlite3 data/gitea/gitea.db "select 'user', count(*) from user union all select 'repository', count(*) from repository union all select 'lfs_meta_object', count(*) from lfs_meta_object union all select 'public_key', count(*) from public_key union all select 'issue', count(*) from issue union all select 'release', count(*) from release;"
|
||||||
```
|
```
|
||||||
|
|
||||||
## 3. 更新代码并只启动 PostgreSQL
|
## 3. 使用 Gitea dump 导出 PostgreSQL SQL
|
||||||
|
|
||||||
|
在仍使用旧 SQLite 配置时运行 `gitea dump`。不要先把 Gitea 配置切到 PostgreSQL,否则 dump 会尝试读取新数据库。
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose run --rm --user git gitea \
|
||||||
|
gitea dump -c /data/gitea/conf/app.ini \
|
||||||
|
--database postgres \
|
||||||
|
--file /data/gitea-dump-postgres.zip
|
||||||
|
```
|
||||||
|
|
||||||
|
确认宿主机上已经生成 dump 包:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ls -lh data/gitea-dump-postgres.zip
|
||||||
|
```
|
||||||
|
|
||||||
|
如果当前镜像或环境不能识别 `git` 用户,可以改用官方镜像常见 UID/GID:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose run --rm --user 1000:1000 gitea \
|
||||||
|
gitea dump -c /data/gitea/conf/app.ini \
|
||||||
|
--database postgres \
|
||||||
|
--file /data/gitea-dump-postgres.zip
|
||||||
|
```
|
||||||
|
|
||||||
|
解压 dump 包,得到 `gitea-db.sql`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mkdir -p backups/gitea-dump-postgres
|
||||||
|
unzip -o data/gitea-dump-postgres.zip -d backups/gitea-dump-postgres
|
||||||
|
ls -lh backups/gitea-dump-postgres/gitea-db.sql
|
||||||
|
```
|
||||||
|
|
||||||
|
## 4. 更新代码并只启动 PostgreSQL
|
||||||
|
|
||||||
更新到包含 PostgreSQL 服务的最新 commit,并补齐 `.env` 中的 PostgreSQL 配置。
|
更新到包含 PostgreSQL 服务的最新 commit,并补齐 `.env` 中的 PostgreSQL 配置。
|
||||||
|
|
||||||
@@ -76,7 +108,7 @@ docker compose up -d postgres
|
|||||||
docker compose exec -T postgres psql -U gitea -d gitea -c "select version();"
|
docker compose exec -T postgres psql -U gitea -d gitea -c "select version();"
|
||||||
```
|
```
|
||||||
|
|
||||||
## 4. 确认 PostgreSQL 是空库
|
## 5. 确认 PostgreSQL 是空库
|
||||||
|
|
||||||
检查目标库是否已有表:
|
检查目标库是否已有表:
|
||||||
|
|
||||||
@@ -95,20 +127,14 @@ docker compose up -d postgres
|
|||||||
|
|
||||||
再次运行 `\dt`,确认目标库为空。
|
再次运行 `\dt`,确认目标库为空。
|
||||||
|
|
||||||
## 5. 使用 pgloader 导入 SQLite
|
## 6. 导入 dump SQL 到 PostgreSQL
|
||||||
|
|
||||||
把 `<POSTGRES_PASSWORD>` 替换为 `.env` 中的真实密码:
|
使用 `psql` 导入 `gitea-db.sql`:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker run --rm \
|
docker compose exec -T postgres psql -U gitea -d gitea < backups/gitea-dump-postgres/gitea-db.sql
|
||||||
--network gitea_default \
|
|
||||||
-v "$PWD/data/gitea:/data/gitea:ro" \
|
|
||||||
dimitri/pgloader:latest \
|
|
||||||
pgloader sqlite:///data/gitea/gitea.db postgresql://gitea:<POSTGRES_PASSWORD>@postgres:5432/gitea
|
|
||||||
```
|
```
|
||||||
|
|
||||||
如果 compose project 网络名不是 `gitea_default`,替换 `--network` 参数。
|
|
||||||
|
|
||||||
导入完成后,检查目标库关键表数量:
|
导入完成后,检查目标库关键表数量:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@@ -117,7 +143,7 @@ docker compose exec -T postgres psql -U gitea -d gitea -c "select 'user', count(
|
|||||||
|
|
||||||
这些数量应与第 2 步 SQLite 基线一致。
|
这些数量应与第 2 步 SQLite 基线一致。
|
||||||
|
|
||||||
## 6. 启动 Gitea
|
## 7. 启动 Gitea
|
||||||
|
|
||||||
确认 `docker-compose.yml` 已通过 `GITEA__database__*` 环境变量指向 PostgreSQL,然后启动 Gitea:
|
确认 `docker-compose.yml` 已通过 `GITEA__database__*` 环境变量指向 PostgreSQL,然后启动 Gitea:
|
||||||
|
|
||||||
@@ -134,7 +160,7 @@ Gitea 启动时会对 PostgreSQL 执行必要的 schema migration。日志中不
|
|||||||
docker compose up -d caddy
|
docker compose up -d caddy
|
||||||
```
|
```
|
||||||
|
|
||||||
## 7. 迁移后验证
|
## 8. 迁移后验证
|
||||||
|
|
||||||
- 使用原管理员账号登录 Web UI。
|
- 使用原管理员账号登录 Web UI。
|
||||||
- 确认用户、组织、仓库、Issue、Release、SSH Key 等数据存在。
|
- 确认用户、组织、仓库、Issue、Release、SSH Key 等数据存在。
|
||||||
@@ -148,6 +174,48 @@ docker compose up -d caddy
|
|||||||
docker compose logs gitea postgres
|
docker compose logs gitea postgres
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## 常见问题
|
||||||
|
|
||||||
|
### Gitea is not supposed to be run as root
|
||||||
|
|
||||||
|
`docker compose run` 默认可能以 root 用户启动一次性容器,但 Gitea 不允许以 root 运行。给 dump 命令加上 `--user git`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose run --rm --user git gitea \
|
||||||
|
gitea dump -c /data/gitea/conf/app.ini \
|
||||||
|
--database postgres \
|
||||||
|
--file /data/gitea-dump-postgres.zip
|
||||||
|
```
|
||||||
|
|
||||||
|
如果 `git` 用户不可用,改用:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose run --rm --user 1000:1000 gitea \
|
||||||
|
gitea dump -c /data/gitea/conf/app.ini \
|
||||||
|
--database postgres \
|
||||||
|
--file /data/gitea-dump-postgres.zip
|
||||||
|
```
|
||||||
|
|
||||||
|
### Unable to create dump file "/gitea-dump-*.zip": permission denied
|
||||||
|
|
||||||
|
`gitea dump` 默认会把文件写到容器当前目录。如果当前目录是 `/`,非 root 用户没有写权限。显式指定 `--file /data/gitea-dump-postgres.zip`,让 dump 写入已挂载且可持久化的 `/data` 目录。
|
||||||
|
|
||||||
|
### pgloader 备选方案
|
||||||
|
|
||||||
|
如果 `gitea dump --database postgres` 在当前版本或数据集上失败,可以把 `pgloader` 作为备选迁移工具。使用前仍然要停止 Gitea、完成冷备份,并确认 PostgreSQL 目标库为空。
|
||||||
|
|
||||||
|
把 `<POSTGRES_PASSWORD>` 替换为 `.env` 中的真实密码:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker run --rm \
|
||||||
|
--network gitea_default \
|
||||||
|
-v "$PWD/data/gitea:/data/gitea:ro" \
|
||||||
|
dimitri/pgloader:latest \
|
||||||
|
pgloader sqlite:///data/gitea/gitea.db postgresql://gitea:<POSTGRES_PASSWORD>@postgres:5432/gitea
|
||||||
|
```
|
||||||
|
|
||||||
|
如果 compose project 网络名不是 `gitea_default`,替换 `--network` 参数。
|
||||||
|
|
||||||
## 回滚
|
## 回滚
|
||||||
|
|
||||||
如果迁移后验证失败,先停止新 Gitea:
|
如果迁移后验证失败,先停止新 Gitea:
|
||||||
@@ -171,7 +239,7 @@ cp backups/<备份时间>/app.ini data/gitea/conf/app.ini
|
|||||||
docker compose up -d gitea
|
docker compose up -d gitea
|
||||||
```
|
```
|
||||||
|
|
||||||
在迁移完全确认前,不要删除 `data/gitea/gitea.db`、`backups/` 或迁移前的 `data/postgres.before-migration-*`。
|
在迁移完全确认前,不要删除 `data/gitea/gitea.db`、`backups/`、`data/gitea-dump-postgres.zip` 或迁移前的 `data/postgres.before-migration-*`。
|
||||||
|
|
||||||
## 演练建议
|
## 演练建议
|
||||||
|
|
||||||
@@ -182,4 +250,4 @@ cp -a gitea gitea-migration-dry-run
|
|||||||
cd gitea-migration-dry-run
|
cd gitea-migration-dry-run
|
||||||
```
|
```
|
||||||
|
|
||||||
演练中也要验证空库检查、pgloader 导入、表数量对比、Gitea 启动和 Web/Git 操作。演练通过后,再在正式目录执行维护窗口迁移。
|
演练中也要验证 dump 导出、SQL 解压、空库检查、`psql` 导入、表数量对比、Gitea 启动和 Web/Git 操作。演练通过后,再在正式目录执行维护窗口迁移。
|
||||||
|
|||||||
Reference in New Issue
Block a user