MAATRIX / Блог / Сколько RAM нужно для Forgejo

Сколько RAM нужно для Forgejo

MAATRIX

Официальной цифры «сколько RAM нужно Forgejo» в документации почти нет — проект вырос из Gitea в октябре 2022 года и унаследовал её экономность: сам сервис умещается в несколько сотен мегабайт. Падает такой сервер не от веб-интерфейса, а от git-подпроцессов на клонировании и от job в Forgejo Actions, которым на пике нужен гигабайт-другой. Разберём по частям: сервис, база, git и раннер — и дадим ориентиры для тарифов от 1 до 8 ГБ.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →

Короткий ответ: сколько RAM нужно для Forgejo

Цифры для сервера, где кроме Forgejo ничего не крутится.

RAMЧто реально помещаетсяКомментарий
1 ГБForgejo + SQLite, 1–3 человека, репозитории до 200 МБ, без ActionsВпритык, риск OOM на первом крупном клоне
2 ГБForgejo + PostgreSQL, 5–10 человек, зеркала, LFS, поиск по задачамРабочий минимум для небольшой команды
4 ГБТо же плюс forgejo-runner с одним job: сборка Go, Node, тестыВариант по умолчанию, если нужен CI
8 ГБ2–3 параллельных job, индексатор кода, реестр пакетов15–20+ разработчиков
16 ГБElasticsearch под поиск, монорепозиторий на десятки гигабайтНужно редко

Главное правило то же, что и для любого git-сервера на Go: требования — это не одна цифра, а две. Постоянное потребление (процесс, база, индексаторы) держится на сотнях мегабайт и растёт медленно. Пик — тяжёлый клон, ночная сборка pack-файлов, старт job в Actions — живёт минуты, но именно по нему считают тариф: сервер падает на пике, а не в покое. По CPU интерфейсу хватает одного ядра, но git pack-objects и job раннера процессорные, и на слабом vCPU отдача гигабайтного репозитория растянется на минуты.

Чем Forgejo отличается от Gitea по памяти

Кодовая база разошлась не сильно — Forgejo остаётся тем же Go-бинарником без PHP-воркеров и JVM, использует тот же конфиг app.ini и тот же git в подпроцессах. Поэтому почти все приёмы экономии памяти из мира Gitea переносятся один в один. Но три отличия на расход всё же влияют:

  • Имена другие. Юнит — forgejo.service, бинарник /usr/bin/forgejo, версия — forgejo --version. Конфиг в пакетной установке лежит в /etc/forgejo/app.ini, в Docker-образе codeberg.org/forgejo/forgejo — по историческому пути /data/gitea/conf/app.ini, хвост от форка.
  • Федерация (ActivityPub) — новая статья расхода, но по умолчанию выключена ([federation] ENABLED = false). Включаете обмен с другими Forgejo/Codeberg-инстансами — добавляется очередь исходящих запросов и кэш акторов, лишние десятки мегабайт.
  • Квоты хранилища — функции, которой у Gitea нет: лимиты на размер репозитория, LFS и артефактов. Память почти не ест, но полезна именно на тесном тарифе — защищает не от OOM, а от маленького диска (20–40 ГБ NVMe).

Раннер для Actions называется forgejo-runner, а не act_runner, хотя устроен по тому же принципу с общими корнями от проекта act. Конфиг и логика ниже идентичны тому, что описано для Gitea.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Куда уходит память в покое: сервис, база, индексаторы

Живой процесс Forgejo на небольшом инстансе (десятки репозиториев, PostgreSQL рядом, Actions выключены) обычно держит порядка 150–250 МБ resident-памяти, с пиками до 350–450 МБ на обновлении индекса задач или массовом веб-хуке. Это ориентир, не гарантия — сверяйте по своему systemctl status forgejo или cgroup, как описано ниже.

К этому добавляется база:

БазаRSS в покоеКогда брать
SQLiteотдельного процесса нетДо 10 человек, +20–60 МБ. При параллельных push возможна database is locked — лечится переходом на Postgres
PostgreSQL 17ориентировочно 130–220 МБСтандартный выбор: shared_buffers = 128MB плюс несколько бэкендов по 8–12 МБ
MySQL/MariaDBориентировочно 350–500 МБТолько если база уже есть в инфраструктуре — на 2 ГБ это заметная доля памяти впустую

Третья статья — индексаторы, секция [indexer]:

  • Поиск по задачам (ISSUE_INDEXER_TYPE) по умолчанию на bleve — плюс 40–120 МБ на нескольких тысячах задач. На тесной машине переключайте на db.
  • Поиск по коду (REPO_INDEXER_ENABLED) выключен не просто так: bleve-индекс занимает на диске столько же, сколько сам код, и добавляет 250–400 МБ RSS.
  • Elasticsearch как альтернативный REPO_INDEXER_TYPE снимает нагрузку с Forgejo, но JVM просит от 2 ГБ heap — это отдельная машина.

Плюс хост: systemd, sshd, агент мониторинга — обычно 150–250 МБ. «Пустая» инсталляция с PostgreSQL и без Actions укладывается примерно в 400–500 МБ, что и объясняет, почему 1 ГБ технически работает, но без запаса.

Git-подпроцессы: тот же корень, что и у Gitea

Сама Forgejo растёт медленно — растут её дети. На каждый клон, push, дифф и ночную проверку она запускает настоящий git, у которого по умолчанию нет лимитов памяти. Классическая картина на тесном сервере: разработчик клонирует репозиторий в несколько сотен мегабайт, получает fatal: early EOF на клиенте, а в dmesg на сервере — Out of memory: Killed process (git). Убивают не саму Forgejo, а git pack-objects: он собирает pack на лету, а pack.windowMemory по умолчанию не ограничен — берёт памяти столько, сколько попросит, отдельно на каждый поток, а потоков столько же, сколько ядер.

Нужные ключи Forgejo пишет в git-конфиг сама, секцией [git.config] в app.ini:

[git.config]
pack.windowMemory = 32m
pack.deltaCacheSize = 64m
pack.threads = 1
core.bigFileThreshold = 8m

pack.windowMemory ограничивает окно дельта-сжатия на поток, pack.threads = 1 убирает умножение расхода на число ядер, а core.bigFileThreshold (по умолчанию 512 МБ) велит не жать дельтами крупные файлы — именно на них уходит память в репозиториях с картинками и бинарями. Плата честная: отдача репозитория при одном потоке идёт заметно дольше, чем при полной параллельности.

Второй регулярный едок памяти — плановые задачи: health check по расписанию ([cron.repo_health_check]) обходит все репозитории и на крупных занимает заметно больше памяти, чем обычный запрос. Не запускайте вручную задачу вроде «Garbage collect all repositories» из панели администратора в рабочее время на тесном тарифе — она проходит git gc по всем репозиториям подряд, а аргументы в [git] GC_ARGS лучше держать без --aggressive при любой памяти.

Forgejo Actions и forgejo-runner: где кончаются гигабайты

Сама Forgejo задач не выполняет — их берёт forgejo-runner, лёгкий процесс, который на каждый job поднимает Docker-контейнер. Реальная память уходит именно туда. Порядок величин по типичным сценариям: сборка на Go — сотни мегабайт, npm ci && npm run build для Vite или Next — уже 1,5–2,5 ГБ на пике, docker build с buildkit — от 800 МБ до пары гигабайт плюс место на диске под слои. Это ориентиры: конкретный расход зависит от проекта, проверяйте по своему job.

Если сборка падает с ошибкой нехватки памяти внутри контейнера (например, JavaScript heap out of memory для Node) и job завершается кодом 137 — дело не в Forgejo и не в раннере: контейнеру не хватило лимита. Две настройки в config.yml раннера решают почти всё:

runner:
  capacity: 1
container:
  options: "--memory=2g --memory-swap=2g --cpus=2"

capacity — сколько job раннер берёт одновременно; по умолчанию 1, поднимать его на четырёхгигабайтной машине рискованно — две параллельные сборки Node легко дают совокупный пик за 4 ГБ. --memory=2g ограничивает контейнер жёстко: job умрёт сам, с кодом 137 в своём логе, а не утащит за собой Forgejo и базу.

Диск считайте отдельно от памяти: образы для раннера занимают от одного до нескольких гигабайт, а артефакты сборок хранятся не один день — проверьте [actions] ARTIFACT_RETENTION_DAYS, иначе диск на 20 ГБ забьётся раньше памяти.

Как ужать Forgejo до минимума и проверить свои цифры

Рабочая конфигурация для двух-трёх человек без CI, /etc/forgejo/app.ini:

[indexer]
ISSUE_INDEXER_TYPE = db
REPO_INDEXER_ENABLED = false

[database]
MAX_OPEN_CONNS = 10
MAX_IDLE_CONNS = 2

[git]
MAX_GIT_DIFF_LINES = 500
MAX_GIT_DIFF_FILES = 50

[federation]
ENABLED = false

MAX_GIT_DIFF_* — не про красоту интерфейса: открытый в браузере дифф на двадцать тысяч строк разворачивается в памяти целиком, а не потоково. Второй приём, о котором редко пишут, — GOMEMLIMIT, мягкий лимит для сборщика мусора Go: заставляет GC работать агрессивнее вместо того, чтобы дать процессу расти. Задаётся через sudo systemctl edit forgejo:

[Service]
Environment=GOMEMLIMIT=600MiB
Environment=GOGC=50

Честная оговорка: GOMEMLIMIT управляет только кучей самой Forgejo и не действует на git pack-objects — главный источник пиков. Плата за лимит — чуть выше загрузка CPU на сборку мусора.

Swap на 2 ГБ — не про постоянную нехватку, а про разовые пики: fallocate -l 2G /swapfile, chmod 600, mkswap, swapon, строка в /etc/fstab и vm.swappiness=10. Он даёт пережить ночной health check и одиночный тяжёлый клон, но не заменяет память по скорости — NVMe на порядки медленнее RAM. Как считать размер свопа под нагрузку — в отдельном разборе: правильный размер swap для VPS.

Проверять свои цифры, а не ориентиры из статьи, помогает cgroup:

cat /sys/fs/cgroup/system.slice/forgejo.service/memory.peak
grep -E '^(anon|file) ' /sys/fs/cgroup/system.slice/forgejo.service/memory.stat
journalctl -u forgejo --since "yesterday" | grep -iE "oom|signal|panic"
sudo dmesg -T | grep -iE "out of memory|oom-kill"

memory.peak — максимум за время жизни юнита, с ним и сравнивайте тариф. Если в dmesg убит процесс git, а не forgejo — виновата git-конфигурация, лечится секцией [git.config] выше, а не апгрейдом. Общая диагностика нехватки памяти на сервере — в статье что делать при нехватке RAM.

Какой сервер взять в MAATRIX под Forgejo

Честный минимум: 1 vCPU, 2 ГБ RAM, 30–40 ГБ NVMe. Не 1 ГБ — вы покупаете сервер целиком, а не изолированный процесс: сюда добавляются база, ОС и пик на клонировании. На 2 ГБ спокойно живёт команда из 5–10 человек с PostgreSQL, LFS и зеркалами. Actions на этом тарифе не запускайте.

Комфортный вариант: 2 vCPU, 4 ГБ RAM, 60–80 ГБ NVMe. Forgejo, PostgreSQL и forgejo-runner с capacity: 1 и лимитом --memory=2g на job. Помещается ежедневная сборка на Go или Node с запасом на ночные задачи — конфигурация по умолчанию, если CI нужен на той же машине.

Если сборок много: 4 vCPU, 8 ГБ RAM, 120–160 ГБ NVMe. Два-три параллельных job, поиск по коду, реестр пакетов. Часто дешевле держать саму Forgejo на небольшой машине, а раннер отдельно: он ходит к серверу по HTTPS через токен регистрации и физически рядом быть не обязан.

Ставится Forgejo вручную — готовым бинарником с systemd-юнитом или через Docker Compose с образом codeberg.org/forgejo/forgejo; автоустановки из каталога приложений для неё пока нет, в отличие от Gitea, у которой требования к памяти почти идентичны. Если выбираете между проектами — разница не в ресурсах, а в модели управления, и разбор Gitea против GitLab поможет с соседним вопросом.

Локацию выбирайте по тому, куда ходит CI. Если сборки тянут образы с Docker Hub и ghcr.io, пакеты npm и PyPI, модули через proxy.golang.org — берите площадку с прямым выходом за границу: лондонский датацентр снимает половину проблем с недоступностью реестров. Если вся команда в России и внешних зависимостей нет — держите сервер в РФ. Оплата в обоих случаях — картой российского банка, по СБП, криптовалютой или токеном MAAT, без иностранной карты.

Сомневаетесь между 2 и 4 ГБ — критерий тот же, что и для любого git-сервера: нужен ли CI на этой же машине. Нужен — берите четыре гигабайта сразу, доращивать тариф под уже работающий раннер менее удобно.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.

Частые вопросы

Forgejo и Gitea требуют разной памяти?

Нет, ядро почти идентично: оба на Go, с одним движком git в подпроцессах и одной моделью конфигурации. Разница на практике — в названиях сервиса и раннера, включённой, но по умолчанию выключенной федерации и в квотах хранилища, которых у Gitea нет.

Хватит ли 1 ГБ RAM для Forgejo?

Для двух-трёх человек и репозиториев до 200 МБ — да, если выключить индексаторы, добавить swap на 2 ГБ и ограничить pack.windowMemory в [git.config]. Первый же клон крупного репозитория или запуск Actions с высокой вероятностью закончится убитым процессом git в dmesg.

Почему память ест git, а не сам процесс Forgejo?

Forgejo делегирует работу с репозиториями бинарнику git и запускает его заново на каждый клон, push и дифф. У git pack-objects по умолчанию нет лимита памяти — его задаёте вы сами.

Нужно ли ставить forgejo-runner на тот же сервер, что и Forgejo?

Нет, и на тесном тарифе лучше не ставить. Раннер регистрируется по токену и общается с сервером по HTTPS, поэтому его можно вынести на отдельную машину — сборка, съевшая 2 ГБ на пике, не утащит за собой git-сервер и базу.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →