Бэкап и восстановление Forgejo
Forgejo — форк Gitea, появившийся после смены управления проектом в 2022 году: часть команды не согласилась с планами вынести Gitea в закрытую коммерческую структуру и увела код в собственный форк под крылом некоммерческого Codeberg e.V. Кода это почти не задело — движок, база данных, формат репозиториев и CLI-команды первое время совпадали с Gitea почти дословно, различия сегодня в основном в мелочах интерфейса и политике релизов. А вот гайды по бэкапам в сети — с разночтениями: часть работает для Forgejo один в один, часть уже разошлась в деталях вроде имени бинарника и пути к конфигу. Разберём, что копировать в Forgejo, как это делать штатной командой forgejo dump и что проверить перед восстановлением, чтобы не потерять историю коммитов и Actions-раннеры в придачу.
Содержание
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Что хранит Forgejo и что должно попасть в бэкап
Легковесность Forgejo — один Go-бинарник без внешних зависимостей вроде Redis или Sidekiq — оборачивается тем, что состояние сервиса разбросано по нескольким местам, и потеря любого бьёт по-разному:
- Git-репозитории — сами объекты
.git, лежат вrepos/внутриdata-каталога (в Docker-образе это/data/git/repositories). Это самое ценное: без базы данных Forgejo можно поднять заново и привязать репозитории вручную, а без самих репозиториев — нет. - База данных — пользователи, issues, pull request'ы, комментарии, права доступа, вебхуки, настройки организаций, токены Actions-раннеров. SQLite хранится файлом рядом с данными, PostgreSQL/MySQL — отдельным сервисом.
- LFS-объекты — если включён Git LFS, крупные бинарные файлы (архивы, датасеты, сборки) лежат отдельно от Git-объектов, в
data/lfs. - Аватары, вложения, миниатюры —
data/avatars,data/attachments,data/repo-avatars. - Конфиг
app.ini— секретный ключSECRET_KEY,INTERNAL_TOKEN, настройки почты и OAuth. ПотеряSECRET_KEYозначает, что сохранённые пароли и токены в базе станут нечитаемыми даже при восстановлении самой базы. - SSH-ключи хоста (при встроенном SSH-сервере, а не системном
sshd) — без них у клонов по SSH после восстановления сменится fingerprint. - Custom-шаблоны и хуки — каталог
custom/, если вы там что-то правили.
Проверить, что реально лежит на диске, можно так:
du -sh /var/lib/forgejo/data/* 2>/dev/null || du -sh /data/*
Для Docker-инсталляции обычно есть один именованный volume, смонтированный в /data, — весь список выше находится внутри него.
Быстрый бэкап штатной командой forgejo dump
У Forgejo, как и у Gitea, есть встроенная команда дампа, которая собирает почти всё перечисленное выше в один архив, не трогая при этом файлы, которые Forgejo меняет на лету (сессии, временные файлы, кеш индексации).
Для установки из бинарника (systemd-сервис, пользователь git):
sudo -u git forgejo dump -c /etc/forgejo/app.ini \
--file /home/git/forgejo-dump-$(date +%F).zip \
--tempdir /home/git/tmp
Команда создаёт zip-архив, внутри которого:
app.iniиз указанного конфига;data/(репозитории, LFS, аватары, вложения) — кроме сессий и кэшей;custom/— ваши шаблоны и правки;log/— журналы (можно исключить флагом--skip-log, если бэкап и так большой);- дамп базы данных в формате SQL, если она не SQLite (SQLite попадает в архив как есть, файлом).
Полезные флаги:
forgejo dump --skip-repository # без Git-объектов — только метаданные, для быстрой проверки конфига
forgejo dump --skip-log # без логов, экономит место
forgejo dump --database # явно указать движок БД, если автоопределение путается
Важный нюанс: во время дампа Forgejo ставит блокировку и приостанавливает часть операций записи — на больших инсталляциях (десятки гигабайт репозиториев) дамп может идти минутами, и в этот момент пользователи получат медленные ответы, а не ошибки. Планируйте forgejo dump на тихие часы, как и в любой self-hosted Git-системе — принципы те же, что для бэкапа Gitea.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверБэкап Forgejo в Docker Compose
Если Forgejo развёрнута через docker-compose.yml (самый частый вариант на VPS), команду нужно выполнять внутри контейнера, а сам архив — сразу выгружать наружу:
docker exec -u git -it forgejo forgejo dump \
-c /data/gitea/conf/app.ini \
--file /tmp/forgejo-dump.zip \
--tempdir /tmp
docker cp forgejo:/tmp/forgejo-dump.zip \
/opt/backups/forgejo-dump-$(date +%F).zip
docker exec forgejo rm /tmp/forgejo-dump.zip
Обратите внимание: конфиг внутри официального образа лежит по пути /data/gitea/conf/app.ini — унаследованное от Gitea расположение, его не переименовали, чтобы не ломать миграции с Gitea. Проверить точный путь на своём сервере:
docker exec forgejo find /data -maxdepth 3 -iname "app.ini"
Если под Forgejo используется отдельный контейнер с PostgreSQL (типичная схема — два сервиса в одном docker-compose.yml), надёжнее бэкапить базу отдельной командой рядом, не полагаясь на встроенный дамп базы внутри forgejo dump:
docker exec -t forgejo-db pg_dump -U forgejo -d forgejo \
| gzip > /opt/backups/forgejo-db-$(date +%F).sql.gz
и держать оба архива — дамп данных и дамп базы — как одну пару с одинаковой временной меткой, чтобы при восстановлении не свести случайно несовместимые версии.
Отдельный бэкап базы данных: SQLite, PostgreSQL, MySQL
| Движок БД | Как бэкапить отдельно | Особенность |
|---|---|---|
| SQLite3 | sqlite3 /data/gitea/gitea.db ".backup /tmp/gitea.db.bak" | Обычный cp во время записи может дать повреждённый файл — используйте встроенный .backup, он безопасен при одновременной записи |
| PostgreSQL | pg_dump -U forgejo -Fc forgejo > forgejo.dump | Формат -Fc (custom) сжимается сам и восстанавливается через pg_restore, удобнее для больших баз |
| MySQL/MariaDB | mysqldump --single-transaction -u forgejo -p forgejo > forgejo.sql | Обязательно --single-transaction, иначе дамп на живой базе может словить блокировки таблиц issues/comments |
Для команд, которые уже используют PostgreSQL под другие сервисы на том же VPS, есть смысл посмотреть на общую схему регулярной архивации базы — подход из статьи настройка PostgreSQL на VPS применим и здесь, только источник данных — база Forgejo.
Восстановление Forgejo из бэкапа
Порядок действий одинаковый что при переезде на новый сервер, что при восстановлении после сбоя:
- Поднимите чистую Forgejo той же версии, что была на момент дампа — номер смотрите в имени пакета/образа, который использовали для бэкапа (в
app.iniего нет). Расхождение на один минорный релиз обычно переживается автоматическими миграциями при старте, но лучше держать версии одинаковыми. - Остановите сервис, чтобы избежать записи поверх восстанавливаемых данных:
docker compose stop forgejo forgejo-db
- Восстановите базу данных первой:
gunzip -c forgejo-db-2026-08-20.sql.gz | \
docker exec -i forgejo-db psql -U forgejo -d forgejo
Для PostgreSQL из -Fc дампа — pg_restore -U forgejo -d forgejo --clean forgejo.dump.
- Распакуйте архив данных в volume, который смонтирован в
/data:
docker cp forgejo-dump-2026-08-20.zip forgejo:/tmp/
docker exec forgejo unzip -o /tmp/forgejo-dump-2026-08-20.zip -d /data
Содержимое архива должно принадлежать пользователю, от имени которого работает Forgejo внутри контейнера (обычно git, UID 1000) — проверьте docker exec forgejo ls -la /data/git/repositories и при необходимости поправьте владельца через chown -R git:git.
- Верните
app.iniиз архива на прежнее место, если разворачивали конфиг заново — особенно важно перенестиSECRET_KEYиINTERNAL_TOKEN, без них старые сессии и OAuth-интеграции не заработают. - Запустите сервис и проверьте целостность репозиториев:
docker compose up -d
docker exec -u git forgejo forgejo doctor check --all
Команда doctor check находит битые ссылки на несуществующие Git-объекты, рассинхрон между базой и файловой системой и другие несостыковки — полезно прогонять её сразу после любого восстановления, а не только когда что-то уже сломалось.
- Проверьте Actions-раннеры отдельно. Если использовались Forgejo Actions с self-hosted раннерами, токены регистрации раннеров хранятся в базе, но сами раннеры при смене сервера нужно перерегистрировать заново через
forgejo actions generate-runner-token— старые токены с прежнего IP не переедут автоматически.
Автоматизация и хранение бэкапов вне сервера
Бэкап на том же диске, что и сам сервис, — копия для очистки совести, а не защита: при отказе диска или компрометации сервера пропадёт всё разом. Рабочая схема — cron-задача плюс выгрузка на другой сервер или в объектное хранилище.
Простой скрипт-обвязка (/opt/scripts/backup-forgejo.sh):
#!/usr/bin/env bash
set -euo pipefail
DATE=$(date +%F)
BACKUP_DIR=/opt/backups/forgejo
mkdir -p "$BACKUP_DIR"
docker exec -u git forgejo forgejo dump \
-c /data/gitea/conf/app.ini \
--file "/tmp/forgejo-$DATE.zip" \
--tempdir /tmp
docker cp "forgejo:/tmp/forgejo-$DATE.zip" "$BACKUP_DIR/"
docker exec forgejo rm "/tmp/forgejo-$DATE.zip"
# хранить только последние 7 локальных копий
find "$BACKUP_DIR" -name "forgejo-*.zip" -mtime +7 -delete
Добавьте в crontab:
0 3 * * * /opt/scripts/backup-forgejo.sh >> /var/log/forgejo-backup.log 2>&1
Дальше архив стоит выгрузить за пределы сервера — через rclone в S3-совместимое хранилище или на отдельный сервер под бэкапы:
rclone copy /opt/backups/forgejo/forgejo-$(date +%F).zip remote:forgejo-backups/
Подробно о настройке rclone под такую задачу — в статье бэкап и восстановление rclone. Если репозитории растут быстро и важна дедупликация между ежедневными архивами, смотрите на restic вместо копирования zip-файлов — см. установка и настройка restic на VPS; сам архив Forgejo в этом случае становится источником для restic backup.
Держите копию в другой локации, чем основной сервер: если недоступен весь дата-центр, копия на соседней стойке того же провайдера не спасёт.
Проверка бэкапов и типичные ошибки
Бэкап, который никогда не восстанавливали, с равной вероятностью может как сработать, так и не сработать в реальной аварии. Минимальная проверка — раз в месяц-два развернуть архив на тестовом VPS и убедиться, что forgejo doctor check --all не находит проблем, а хотя бы один репозиторий клонируется по HTTPS.
Частые причины, по которым восстановление проходит не с первого раза:
- Забыли
SECRET_KEY. Без переноса ключа из старогоapp.iniсохранённые в базе OAuth-токены перестают расшифровываться, пользователи оказываются разлогинены, а webhook-интеграции молча перестают работать. - Версия сервера не совпадает с версией на момент дампа. Схема базы меняется через миграции, которые применяются автоматически, но только вперёд — откатить базу на более старую версию штатно нельзя, только руками через SQL.
- Права на файлы после распаковки. Архив распаковали от
root, а сервис работает отgit— сервис стартует, но не может писать вdata/, в логахpermission deniedнаgit push. - LFS-объекты не попали в архив. Если LFS вынесен на отдельный volume или в S3-совместимое хранилище,
forgejo dumpзаберёт только метаданные — сами объекты бэкапьте отдельно тем жеrclone. - Дамп базы и дамп данных из разного времени. Разные расписания дают рассинхрон — например, issue ссылается на ещё не существовавший на момент архива комментарий. Снимайте оба дампа одним скриптом.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверНужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.
Частые вопросы
Чем бэкап Forgejo отличается от бэкапа Gitea?
Практически ничем на уровне механики — forgejo dump устроена как gitea dump, потому что Forgejo начинался прямым форком кодовой базы. Различия в деталях: путь к бинарнику (forgejo вместо gitea), название образа в registry — формат архива дампа остаётся совместимым.
Можно ли восстановить Forgejo из бэкапа Gitea и наоборот?
Технически да, пока версии не разошлись слишком далеко в миграциях базы. Так делают при миграции с Gitea на Forgejo: разворачивают Forgejo, скармливают ей дамп Gitea, проверяют doctor check.
Нужно ли останавливать Forgejo перед снятием дампа?
Необязательно — forgejo dump работает на живом сервисе. Но на время дампа он заметно замедляется для пользователей, поэтому крупные инсталляции лучше бэкапить в тихие часы.
Как часто нужно бэкапить Forgejo?
Ориентируйтесь на то, сколько работы готовы потерять. Для активной команды — раз в сутки минимум, а перед рискованной операцией (крупный релиз, миграция) снимайте внеплановый дамп вручную.
Диск с /data отказал, а последний бэкап устарел на неделю — что делать?
Восстановить из доступного архива, а недостающие коммиты и ветки частично вернуть git push --mirror из актуальных локальных клонов у разработчиков. Issues, pull request'ы и комментарии так не восстановить — только из бэкапа базы.
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →