При всех своих достоинствах, GitLab - система, крайне требовательная к ресурсам сервера. Одной только оперативной памяти ей фактически нужно 4 гигабайта, и то не без ухищрений. А в контексте FreeBSD это еще и старое недоброе красноглазие при настройке. Определенно нужна альтернатива, и она есть. Встречайте Gitea, работающую даже на Raspberry Pi 3 (по заверениям разработчиков).
Установка
FreeBSD
По аналогии с установкой GitLab на FreeBSD, я создал новую виртуальную машину VirtualBox 7.2 с несколько избыточной формулой 2/2/20 – можно было смело ставить 1 гиг оперативки. Версия FreeBSD 14.3, диск разметил автоматически в GPT/UFS.
Сразу после установки ОС прокачиваем ее:
freebsd-update fetch
freebsd-update install
reboot
Я страдаю сильной зависимостью от Midnight Commander , а это в свою очередь тянет за собой bash, в которой он не засоряет историю команд:
pkg install bash mc
chsh -s /usr/local/bin/bash
exit
При работе с двумя сетевыми адаптерами (NAT и виртуальной сети хоста) необходимо убедиться, что оба получают настройки от DHCP (файл /etc/rc.conf):
ifconfig_em0="DHCP"
ifconfig_em1="DHCP"
В файле /etc/ssh/sshd_config разрешаем вход по SSH root’у:
PermitRootLogin yes
Перезапускаем сервис sshd или всю машину для пущей важности. Получаем IP-адрес второго (первого) адаптера с помощью ifconfig (в моем случае это 192.168.56.102), благодаря чему можем работать удаленно.
Gitea
Установим ее с помощью менеджера, хотя она там немного отстает (1.24.2 при актуальной 1.24.6):
pkg install gitea
Пакет тянет за собой очень небольшое число зависимостей, в основном git как таковой. В результате для установки понадобится всего лишь около 220 мегабайт дискового пространства.
Включаем и запускаем сервис:
service gitea enable
service gitea start
Что дальше? На самом деле ничего не происходит: /var/log/messages сообщают, что gitea не может получить доступ на запись к своему же конфигурационному файлу, чтобы записать секретный ключ:
Sep 20 22:49:08 gitea[71649]: 2025/09/20 22:49:08 modules/setting/oauth2.go:152:loadOAuth2From() [F] save oauth2.JWT_SECRET failed: failed to save "/usr/local/etc/gitea/conf/app.ini": open /usr/local/etc/gitea/conf/app.ini: permission denied
Проанализировав /usr/local/etc/rc.d/gitea, можно сделать вывод, что она должна запускаться под пользователем git, в то время как /usr/local/etc/gitea/conf/app.ini имеет стандартные права 644, root:wheel. Давайте поставим 666 , что ли…
chmod 666 /usr/local/etc/gitea/conf/app.ini
Снова запускаем сервис, в логах видим пожелание установить права 600:
Sep 20 22:56:04 gitea[76162]: 2025/09/20 22:56:04 .../setting/config_provider.go:280:(*iniConfigProvider).Save() [W] Failed changing conf file permissions to -rw-------. Consider changing them manually.
Этого мы наверное не будем делать, но в целом что-то куда-то запускается – curl http://localhost:3000/
отвечает. Извне доступа нет, давайте организуем прокси.
Caddy
Как обычно, устанавливаем ее из пакетов и настраиваем на запуск под пользователем www. Надеюсь, HTTPS не понадобится:
pkg install caddy security/portacl-rc
sysrc portacl_users+=www
sysrc portacl_user_www_tcp="http"
service portacl enable
service portacl start
sysrc caddy_user=www caddy_group=www
service caddy enable
/usr/local/etc/caddy/Caddyfile предлагаю сократить до:
{
auto_https off
}
http://gitea.local {
reverse_proxy localhost:3000
}
В /usr/local/etc/gitea/conf/app.ini прописываем ROOT_URL
сервера:
[server]
ROOT_URL = http://gitea.local/
Gitea перезапускаем, а Caddy запускаем:
service gitea restart
service caddy start
Как обычно в таких случаях, сопоставляем хост gitea.local с IP виртуальной машины. Например в Windows 10 это файл C:\Windows\System32\drivers\etc\hosts (редактировать с правами администратора):
192.168.56.102 gitea.local
И заходим на http://gitea.local/
Даже в немалой степени русифицировано.
Справедливости ради, Gitea сама может работать по https, а сертификат получить через Let’s Encrypt. На мой взгляд, это лишняя функция (да ее и не рекомендуют применять), но теоретически есть возможность выставить чашку с чаем наружу и без дополнительного ПО.
Лирическое отступление. Первоначально по названию я себе придумал древнегреческую богиню Гитею, покровительницу системы управления версиями исходного кода. Но потом осознал, что на логотипе изображена чашка с пакетиком чая, а название состоит из слов git и tea. Увы, реальность оказалось куда менее поэтичной…
PostgreSQL
От лирики, что называется, к физике. По умолчанию Gitea использует БД SQLite. В принципе ее для личных нужд было бы достаточно, но в рамках обзора хочу продемонстрировать настройку «слона». Устанавливаем его и включаем:
pkg install postgresql17-server
service postgresql enable
Как мы с вами помним, стандартная инициализация через service postgresql initdb
приводит к доверенным локальным подключениям. В инструкции же предлагается настроить доступ по паролю и чуть ли не через сокет. Хорошо, усложним себе жизнь и инициализируемся с флагом --auth
:
su -l postgres -c "initdb --encoding=utf-8 --lc-collate=C --auth=scram-sha-256 --pwprompt /var/db
/postgres/data17"
Где --encoding=utf-8 --lc-collate=C
взято из инициализации через сервис, так же как и директория для данных. Пароль суперпользователя будет запрошен (--pwprompt
).
Стартуем и входим в оболочку:
service postgresql start
su -l postgres -c psql
Создаем пользователя gitea
с ультразащищенным паролем (вместо gitea в примере) и БД giteadb
:
CREATE ROLE gitea WITH LOGIN PASSWORD 'gitea';
CREATE DATABASE giteadb WITH OWNER gitea TEMPLATE template0 ENCODING UTF8 LC_COLLATE 'en_US.UTF-8' LC_CTYPE 'en_US.UTF-8';
Выходим (exit
или \q
).
Предложено проверить подключение:
su -l git -c "psql -U gitea giteadb"
Если все в порядке, перенастраиваем /usr/local/etc/gitea/conf/app.ini:
[database]
DB_TYPE = postgres
HOST = 127.0.0.1:5432
NAME = giteadb
PASSWD = gitea
SSL_MODE = disable
USER = gitea
Я решил подключаться по TCP, а не к сокету. Кстати во FreeBSD это /tmp/.s.PGSQL.5432, ну такое. Прежде чем (пере)запускать Gitea, предлагаю довести до ума конфигурацию.
Настройка
Токен и ключи
При «наивном» запуске сервиса формируется только один JWT_SECRET
, а их там вообще говоря еще несколько. Давайте сделаем:
gitea generate secret INTERNAL_TOKEN
gitea generate secret SECRET_KEY
Результаты выполнения команд (ключи) по-видимому нужно вручную внести в app.ini, по крайней мере у меня этот файл не менялся.
Администратор
Создадим его через командную строку:
su -l git -c "gitea admin user create --admin --username gitea --email gitea@example.com --random-password --must-change-password=false"
Не забудьте записать выданный пароль. Похоже что интерактивный ввод пароля не предусмотрен, т.е. либо рандом, либо явное указание через параметр.
Отправка почты
Для виртуальной машины «на попробовать» это наверное не очень актуально, но в принципе система умеет отправлять почту через sendmail или непосредственно по SMTP. Я предпочитаю второй способ, поэтому настройка могла быть примерно такой:
[mailer]
ENABLED = true
FROM = noreply@example.com
SMTP_ADDR = smtp.mail.ru
SMTP_PORT = 465
USER = noreply@example.com
PASSWD = `password`
ENABLE_HELO = false
Я пользуюсь сервисом от мэйла, поэтому указал его SMTP_ADDR
, а также отключил HELO – то ли эта штука в принципе не поддерживается, то ли пароля внешнего приложения с доступом только по SMTP недостаточно.
Git LFS
В поставляемом app.ini про это ничего не сказано, следовательно функция по умолчанию отключена. Чтобы ее включить, сначала сгенерируем LFS_JWT_SECRET
:
gitea generate secret LFS_JWT_SECRET
И добавим настройки в соответствующие секции app.ini:
[server]
LFS_START_SERVER = true
LFS_JWT_SECRET = CHANGE_ME
[lfs]
PATH = /var/db/gitea/data/lfs
Отключение лишнего
На скриншоте выше вы можете заметить счетчик времени формирования страницы. Мне кажется, эта информация явно ни к чему, отключим:
[other]
SHOW_FOOTER_TEMPLATE_LOAD_TIME = false
Аналогично можно отключить ссылку «Работает на Gitea» (SHOW_FOOTER_POWERED_BY
) и вывод версии (SHOW_FOOTER_VERSION
).
Предлагаю заодно убрать самостоятельную регистрацию:
[service]
DISABLE_REGISTRATION = true
И клонирование по SSH:
[server]
DISABLE_SSH = true
После внесения всех настроек давайте восстановим права доступа и перезапустим сервис:
chmod 644 /usr/local/etc/gitea/conf/app.ini
service gitea restart
Откровенно говоря, по сравнению с GitLab особо и нечего настраивать, что в app.ini (хотя…), что в панели управления веб-интерфейса.
Импорт репозитория
Источники
Есть возможность импортировать проекты из нескольких источников, среди которых есть GitHub и GitLab. Последнее, теоретически, предоставляет возможность переезда, если у вас нет сильной привязки к каким-то специфическим функциям. Подозреваю, основная проблема будет в CI/CD.
Миграция из GitLab
Давайте попробуем что-нибудь перенести. Для примера я взял репозиторий, в котором начал делать различные образы PHP. На данный момент это PHP-FPM и FrankenPHP, оба для FreeBSD и Podman (по ссылкам вы можете прочитать статьи об их создании). Для импорта чего-то помимо git-репозитория как такового нужен токен доступа с правом read_api
(прав read_repository
не хватило).
Интерфейс, по крайней мере тема по умолчанию, очень похож на GitHub. С одной стороны, не оригинально, а с другой – зачем что-то выдумывать, если есть индустриальный стандарт.
По умолчанию включены все функции репозитория. Я отключил ненужные в рамках данного вики, проекты, релизы, действия и запросы на слияние.
Реестр контейнеров
Образы для Podman во FreeBSD я делаю в отдельной виртуальной машине. Соответственно прописал gitea.local в /etc/hosts и как «небезопасный» реестр в /usr/local/etc/containers/registries.conf:
[[registry]]
location = "gitea.local"
insecure = true
Авторизовал Podman:
podman login gitea.local
Прежде чем отправлять образы в реестр, стоит упомянуть, что Gitea умеет работать с хранилищем S3, так что при желании можно было бы интегрироваться с MinIO подобно GitLab или арендовать оное у какого-нибудь хостера.
Итак, схема именования стандартная – {registry}/{owner}/{image}:{tag}
, в соответствии с которой отправил образы (позволю себе не перечислять весь набор меток для FrankenPHP):
podman push dc17e55cea50 gitea.local/gitea/php:8.4-fpm-freebsd14.3-pkg
podman push f9c097da3da8 gitea.local/gitea/php:frankenphp-1.9.0-builder-php8.4.11-freebsd14.3
podman push d2f3fc56c8d2 gitea.local/gitea/php:frankenphp-1.9.0-php8.4.11-freebsd14.3
На всякий случай напомню, что синтаксис Докера немного отличается, надо было бы сначала присвоить новый тег образу и потом пушить:
docker tag dc17e55cea50 gitea.local/gitea/php:8.4-fpm-freebsd14.3-pkg
docker push gitea.local/gitea/php:8.4-fpm-freebsd14.3-pkg
Подобно GitHub, потребовалось вручную сопоставить пакет с репозиторием, поэтому сначала образы нужно искать у себя в профиле:
Что интересно, из меток подтянулось описание и ссылка на репозиторий в GitHub (я решил указать его в org.opencontainers.image.source
). Еще понравилось, что выводится история образа (слои) – этого не делает ни GitHub, ни GitLab.
Так вот, по малозаметной ссылке «Настройки» сбоку можно сопоставить пакет с репозиторием:
Что не понравилось, так это то, что система открывает последний тег, а остальные как бы являются версиями пакета. Если бы я попивал чаёк на постоянной основе, то возможно пришлось бы пересматривать подход к именованию образов и явно определять метку latest
.
Аналога гитлабовской функции Dependency proxy похоже нет, а жаль. Что есть, так это поддержка большого количества форматов этих самых пакетов, их сильно больше, чем у пёсика. Например, у меня есть кое-какие мысли по поводу composer, а статус в Лабе – бета.
Резервное копирование и восстановление
https://docs.gitea.com/administration/backup-and-restore
Для создания архива служит команда gitea dump
. Предварительно по понятным причинам рекомендуется остановить сервис:
service gitea stop
Под root команда дампа не запускается в принципе (стоит проверка), поэтому выполняем ее от имени git:
su -l git -c "gitea dump --skip-log"
На мой взгляд, логи не особо нужны, поэтому добавил соответствующий параметр. По умолчанию архив сохранится в домашнем каталоге пользователя, т.е. /usr/local/git.
Присутствует мелочь, которая не лезет ни в какие ворота. База данных выгружается каким-то XORM, поэтому в случае MySQL или PostgreSQL сами разработчики рекомендуют резервировать БД отдельно специализированными средствами. В нашем случае это pg_dump, например:
pg_dump -U gitea giteadb | gzip -9 > gitea-db.sql.gz
Поскольку ранее настроили аутентификацию, будет запрошен пароль.
Восстановление же предлагается выполнять вручную, хотя в общем это и понятно – дамп по большому счету представляет собой архив директории данных. Если база данных сохранена отдельно, то и восстанавливать ее надо отдельно, например:
zcat gitea-db.sql.gz | psql -U gitea giteadb
Кстати штатный SQLite надо было бы восстанавливать из дампа XORM примерно так:
sqlite3 /var/db/gitea/gitea.db < gitea-db.sql
Слегка адаптированный «скрипт» восстановления файлов из инструкции (под пользователем git):
unzip -d dump gitea-dump-1758540802.zip
cd dump
mv app.ini /usr/local/etc/gitea/conf/app.ini
mv data/* /var/db/gitea/data/
mv repos/* /var/db/gitea/gitea-repositories/
mv log/* /var/log/gitea/
Во FreeBSD чуть иначе работает unzip – нужно явно указать директорию для извлечения, чтобы не распаковать архив прямо в текущую, а также отличается расположение каталогов.
Запускаем сервис (обратно под root):
service gitea start
Есть важный нюанс: если вдруг изменилась директория данных или способ установки, то нужно заново сформировать хуки (написано, при запущенной gitea):
su -l git -c "gitea admin regenerate hooks"
После восстановления (и вообще) не повредит воспользоваться услугами очередного доктора Кто:
su -l git -c "gitea doctor check --all"
Какие-то «болезни» он может даже вылечить самостоятельно (--fix
).
Заключение
Да уж, что-то я даже немного пожалел, что изначально связался с GitLab. Оказывается, можно делать почти то же самое и не жрать при этом оперативку и процессор как не в себя. В этом «почти», наверное, и заключается суть – лаборатория продукт явно более мощный. Вопрос в том, нужны ли эти 80% процентов возможностей, которыми пользуется 20% пользователей, мне или вам.
Одной из таких функций GitLab являются Pages. Я тут недавно сокрушался, что их не получилось полноценно завести во FreeBSD. На самом же деле в реальности я не нашел им применение. Поэтому факт, что аналогичного сервиса в Gitea нет, меня не особо расстраивает. Да, есть какие-то очень странные проекты – Codeberg и caddy-gitea, но с ними честно говоря совершенно не хочется связываться.
Говоря о CI/CD в целом, буря в стакане действия в чашке, за некоторыми исключениями, совместимы с Хабом. Пока что я ничем таким не пользуюсь, возможно в будущем сравню обе системы (в смысле рыжую с зеленой).
Из более актуальных для меня вещей – недавно в GitLab у меня появилась вложенная группа. Здесь же иерархия организаций (аналог групп) не поддерживается. Или вот упомянутая ранее прокси зависимостей. Интерфейс собачки мне пожалуй тоже ближе, хотя возможно что это уже дело привычки. Все-таки уже больше года плотно с ним взаимодействую.
Подводя итоги, Gitea стоит предпочесть, если:
- у вас FreeBSD
;
- ограниченные ресурсы;
- нужна русификация;
- вы хотите просто хостить проекты.
Да, по сравнению с GitLab мне показалось, что театрал «просто работает». Конечно не как iPhone против Android, но что-то в этом есть. Соответственно выбор пёсика более вероятен:
- в организациях;
- когда нет проблем с ресурсами сервера;
- у вас Linux;
- и, очевидно, нужны его конкретные функции.
Конечно, я уже не побегу все переносить из GitLab в Gitea, но подумать есть о чем. Для старта может быть и впрямь лучше начинать с напитка, особенно если вы переезжаете с GitHub. А в случае чего, теоретически в Лабе есть импорт «зеленых» репозиториев.
Категория: Программирование, веб | Опубликовано 23.09.2025
Похожие материалы
Перенос GitLab на другой сервер в Docker
Примерно год я мучался с GitLab на сервере с двумя гигабайтами оперативки. Когда оплаченный период закончился, решил взять более мощный VDS по формуле 4/4/30. До этого сам GitLab был установлен непосредственно из репозитория, но для экспериментов с Pages и т.д. нужен Docker. А раз он и так есть, почему бы не завернуть GitLab в контейнер? Заодно на сервер можно будет установить что-нибудь еще.