Gitea 在 docker 部署下的备份恢复

备份与恢复 | Gitea Documentation

Gitea Docker 环境

假设 gitea 是使用如下 compose.yaml 部署在 docker 容器中的(省略不重要信息):

volumes:
  gitea-data:
    driver: local
  gitea-config:
    driver: local
  postgres-data:
    driver: local
  redis-data:
    driver: local
 
services:
  gitea-server:
    image: gitea/gitea:1.23.3-rootless
    hostname: gitea
    environment:
      ...
    restart: unless-stopped
    volumes:
      - gitea-data:/var/lib/gitea
      - gitea-config:/etc/gitea
      - /etc/timezone:/etc/timezone:ro
      - /etc/localtime:/etc/localtime:ro
    depends_on:
      - pgsql-db
      - redis-db
 
  pgsql-db:
    image: postgres:16.3-alpine
    restart: unless-stopped
    environment:
      - POSTGRES_USER=gitea
      - POSTGRES_PASSWORD=xxx
      - POSTGRES_DB=gitea
    volumes:
      - postgres-data:/var/lib/postgresql/data
 
  redis-db:
    image: bitnami/redis:7.4
    restart: unless-stopped
    volumes:
      - redis-data:/bitnami/redis/data
    environment:
      - REDIS_PASSWORD=xxx

docker ps 显示如下:

CONTAINER ID   IMAGE                               COMMAND                  CREATED          STATUS          PORTS.                NAMES
8fd855839088   gitea/gitea:1.23.3-rootless         "/usr/bin/dumb-init …"   20 minutes ago   Up 20 minutes   2222/tcp, 3000/tcp    web-docker-gitea-server-1
28f6ef4fc8a5   postgres:16.3-alpine                "docker-entrypoint.s…"   20 minutes ago   Up 20 minutes   5432/tcp              web-docker-pgsql-db-1
c7ddf9b716c5   bitnami/redis:7.4                   "/opt/bitnami/script…"   20 minutes ago   Up 20 minutes   6379/tcp              web-docker-redis-db-1

按照官方备份恢复文档的说明,整体操作流程如下:

  1. 在 docker 容器里面执行 gitea dump 命令将所需的所有文件导出为 gitea-dump-xxx.zip的文件。
  2. 将数据库文件使用 dump 命令导出为 gitea-db.sql文件。
  3. gitea-db.sql文件拷贝到数据库容器,并恢复。
  4. gitea-dump-xxx.zip文件拷贝到 gitea 容器并恢复。

备份

备份 gitea

  1. 调用 gitea dump 命令备份 gitea 容器中的文件。
# 在宿主机中执行
docker exec -u git -it $(docker ps -qf 'name=^web-docker-gitea-server-1$') bash -c '/usr/local/bin/gitea dump -c /etc/gitea/app.ini'
  • 注意其中的 -u git :-u 参数指定在 docker 容器中执行 dump命令的用户,这个用户默认是 git ,如果不确定可以查看 gitea 容器中 /etc/gitea/app.ini 文件中 RUN_USER 的值:docker exec web-docker-gitea-server-1 cat /etc/gitea/app.ini | grep RUN_USER
  • 另一个是注意name=^web-docker-gitea-server-1$web-docker-gitea-server-1是我当前gitea服务的容器名,请按照自己容器名修改:docker ps

dump 完成后会输出如下信息:

2025/02/15 21:07:35 ...s/storage/storage.go:176:initAttachments() [I] Initialising Attachment storage with type: local
2025/02/15 21:07:35 ...les/storage/local.go:33:NewLocalStorage() [I] Creating new Local Storage at /var/lib/gitea/data/attachments
2025/02/15 21:07:35 ...s/storage/storage.go:166:initAvatars() [I] Initialising Avatar storage with type: local
2025/02/15 21:07:35 ...les/storage/local.go:33:NewLocalStorage() [I] Creating new Local Storage at /var/lib/gitea/data/avatars
2025/02/15 21:07:35 ...s/storage/storage.go:192:initRepoAvatars() [I] Initialising Repository Avatar storage with type: local
2025/02/15 21:07:35 ...les/storage/local.go:33:NewLocalStorage() [I] Creating new Local Storage at /var/lib/gitea/data/repo-avatars
2025/02/15 21:07:35 ...s/storage/storage.go:186:initLFS() [I] Initialising LFS storage with type: local
2025/02/15 21:07:35 ...les/storage/local.go:33:NewLocalStorage() [I] Creating new Local Storage at /var/lib/gitea/git/lfs
2025/02/15 21:07:35 ...s/storage/storage.go:198:initRepoArchives() [I] Initialising Repository Archive storage with type: local
2025/02/15 21:07:35 ...les/storage/local.go:33:NewLocalStorage() [I] Creating new Local Storage at /var/lib/gitea/repo-archive
2025/02/15 21:07:35 ...s/storage/storage.go:208:initPackages() [I] Initialising Packages storage with type: local
2025/02/15 21:07:35 ...les/storage/local.go:33:NewLocalStorage() [I] Creating new Local Storage at /var/lib/gitea/packages
2025/02/15 21:07:35 ...s/storage/storage.go:219:initActions() [I] Initialising Actions storage with type: local
2025/02/15 21:07:35 ...les/storage/local.go:33:NewLocalStorage() [I] Creating new Local Storage at /var/lib/gitea/actions_log
2025/02/15 21:07:35 ...s/storage/storage.go:223:initActions() [I] Initialising ActionsArtifacts storage with type: local
2025/02/15 21:07:35 ...les/storage/local.go:33:NewLocalStorage() [I] Creating new Local Storage at /var/lib/gitea/actions_artifacts
2025/02/15 21:07:35 cmd/dump.go:172:runDump() [I] Dumping local repositories... /var/lib/gitea/git/repositories
2025/02/15 21:07:35 cmd/dump.go:217:runDump() [I] Dumping database...
2025/02/15 21:07:36 cmd/dump.go:229:runDump() [I] Adding custom configuration file from /etc/gitea/app.ini
2025/02/15 21:07:36 cmd/dump.go:244:runDump() [I] Custom dir /var/lib/gitea/custom is inside data dir /var/lib/gitea, skipped
2025/02/15 21:07:36 cmd/dump.go:256:runDump() [I] Packing data directory.../var/lib/gitea
2025/02/15 21:07:36 cmd/dump.go:335:runDump() [I] Finish dumping in file /var/lib/gitea/gitea-dump-1739624855.zip

最后会输出 dump 的来的文件位置(容器中):/var/lib/gitea/gitea-dump-1739624855.zip

  1. 将 dump 出来的文件拷贝到宿主机中的当前位置
docker cp web-docker-gitea-server-1:/var/lib/gitea/gitea-dump-1739624855.zip .
docker exec web-docker-gitea-server-1 rm -rf /var/lib/gitea/gitea-dump-1739624855.zip

之后可以将这个文件发送到待恢复机器上。

备份 gitea 的数据库

其实在上一步的 gitea dump 出来的压缩包中已经包含了数据库文件 gitea-db.sql,但是根据 gitea 文件中说的: gitea dump 创建的 SQL 转储使用 XORM,Gitea 管理员可能更喜欢使用本地的 MySQL 和 PostgreSQL 转储工具。使用 XORM 转储数据库时仍然存在一些问题,可能会导致在尝试恢复时出现问题。 因此这里通过数据库的 dump 工具导出数据为数据库文件。

  1. 执行数据库的 dump 工具命令
# 在宿主机中执行,dump 出来的文件 gitea-db.sql 会保存在宿主机当前目录下
docker exec web-docker-pgsql-db-1 pg_dump -U gitea gitea > gitea-db.sql
  • 命令格式 pg_dump -U $user $database > $fileName

之后可以将这个文件发送到待恢复机器上。

恢复

  1. 根据同一份 docker compose.yaml 启动相关容器
  2. 恢复数据库
# 将 gitea-db.sql 拷贝到容器里面
docker cp gitea-db.sql web-docker-pgsql-db-1:/tmp/
# 进入容器
docker exec -it web-docker-pgsql-db-1 bash
# 恢复数据库
psql -U gitea -d gitea < /tmp/gitea-db.sql
rm -rf /tmp/gitea-db.sql
  1. 恢复gitea
# 将 gitea-dump-1739626068.zip gitea-dump-1739626068.zip
docker cp gitea-dump-1739626068.zip web-docker-gitea-server-1:/tmp/gitea/
 
# 进入容器并手动恢复文件
docker exec -it --user git web-docker-gitea-server-1 bash
 
# 注意我使用的是非根容器,不是非根容器位置会不一样,详情见官方文档
cd /tmp/gitea/
# 在容器内解压您的备份文件
unzip gitea-dump-1739626068.zip
# 恢复 app.ini
cp app.ini /etc/gitea/app.ini
# 恢复 Gitea 数据
rm -rf /var/lib/gitea/*
cp -r data/* /var/lib/gitea/
# 恢复仓库本身
mkdir /var/lib/gitea/git/repositories
cp repos/* /var/lib/gitea/git/repositories/
# 调整文件权限
chown -R git:git /etc/gitea/app.ini /var/lib/gitea
# 重新生成 Git 钩子
/usr/local/bin/gitea -c '/etc/gitea/app.ini' admin regenerate hooks