Реестр контейнеров GitLab во FreeBSD
FreeBSD Caddy GitLab Podman реестр контейнеров прокси зависимостей
Ранее я установил GitLab на виртуальную машину FreeBSD, однако то был лишь базовый набор. Хотелось продолжить эксперимент и посмотреть, что еще можно выжать из столь нетривиального сочетания. В частности, получится ли развернуть Container Registry, и да - получилось. Каким образом? Об этом и пойдет речь в сегодняшней статье.
Для контекста: устанавливается пакет gitlab-ce и отдельно PostgreSQL, а потом идет довольно длительный этап настройки. Для сборки ресурсов требуется не менее 8 гигабайт оперативной памяти. В качестве веб-сервера я использую Caddy. Пёсель меж тем обновился с версии 18.2 до 18.3, так что я на себе проверил инструкцию по обновлению и даже обнаружил ошибку (пропущенный шаг). Статью, разумеется, подправил.
Компиляция
Почему-то оный реестр не входит ни в пакет gitlab-ce как таковой, ни в какой-либо отдельный. К счастью, он написан на go, а следовательно его нетрудно собрать из исходников. Версия на момент написания – v4.27.0-gitlab. Пожалуй единственный нюанс в том, что для этого потребуется много дискового пространства (почти 2 гигабайта для кэша модулей и где-то гигабайт для кэша сборки). Небольшой скрипт (как обычно, под root, если не указано иное):
cd /usr/src
pkg install lang/go
go telemetry off
fetch -o registry.tar.gz https://gitlab.com/gitlab-org/container-registry/-/archive/v4.27.0-gitlab/container-registry-v4.27.0-gitlab.tar.gz
tar xzf registry.tar.gz
cd container-registry-v4.27.0-gitlab
go mod download
CGO_ENABLED=0 gmake PREFIX=/go binaries
file ./bin/registry | grep "statically linked"
Вместо make (как в Dockerfile) – gmake; clean не нужен, так как директория не является git-репозиторием (впрочем все равно ругается, возможно и впрямь было бы лучше склонировать репозиторий вместо скачивания архива). Последняя команда – дымовой тест, как ни странно команда file есть во FreeBSD. Почему-то пишет for FreeBSD 12.3, а у нас уже 14.3, но надеюсь ничего страшного.
По желанию можно потом очистить кэши: go clean -cache -modcache
Настройка
Копируем или переносим получившийся файл bin/registry в /usr/local/bin, а заготовку конфигурации – как /usr/local/etc/registry/config.yml для определенности. В зависимости от того, задействовать ли базу метаданных или нет, этой заготовкой будет config/database-filesystem.yml или config/filesystem.yml. Давайте пойдем по более сложному пути и все-таки сделаем БД:
# This config file is a basic configuration using database metadata and
# filesystem blob storage.
version: 0.1
log:
accesslog:
disabled: false
formatter: text
level: info
formatter: text
fields:
service: registry
storage:
delete:
enabled: true
filesystem:
rootdirectory: "/usr/local/www/gitlab/shared/registry"
database:
enabled: true
host: 127.0.0.1
port: 5432
user: "git"
dbname: "registry"
sslmode: "disable"
http:
# Registry API will be accessible at localhost:5000
addr: localhost:5000
secret: "BzVHJpRm..."
# debug:
# addr: :5001
# # Metrics will be accessible at localhost:5001/metrics/
# prometheus:
# enabled: true
# path: /metrics
# # Profiling information will be accessible at localhost:5001/debug/pprof/
# pprof:
# enabled: true
auth:
token:
realm: "http://192.168.56.143/jwt/auth"
service: container_registry
issuer: gitlab-issuer
rootcertbundle: /usr/local/www/gitlab/config/registry.crt
Раздел log я решил оставить как есть. Поменял адрес на localhost:5000 (значение по умолчанию «торчит» наружу), сгенерировал http/secret, закомментировал подраздел debug, прописал storage/filesystem/rootdirectory и параметры доступа к БД (напомню, что у меня бессовестным образом разрешены локальные подключения без пароля), а также добавил раздел аутентификации, иначе реестром смогли бы пользоваться все подряд.
Создал БД и применил миграции, за них оказывается отвечает сам реестр:
su -l postgres -c "createdb --owner=git registry"
su -l git -c "registry database migrate up /usr/local/etc/registry/config.yml"
Включил реестр в gitlab.yml:
registry:
enabled: true
host: "registry.local"
http_secret: "BzVHJpRm..."
api_url: http://localhost:5000/ # internal address to the registry, will be used by GitLab to directly communicate with API
key: /usr/local/www/gitlab/config/registry.key
path: /usr/local/www/gitlab/shared/registry
issuer: gitlab-issuer
Пришлось прописывать «симметричные» параметры, иначе возникала ошибка 500 при попытке открыть настройки репозиториев. Уж не знаю, является ли галлюцинацией ИИ указание http_secret здесь, но пусть живет. «На проде» в Docker такого нет, а сам этот ключ хранится в gitlab-secrets.json, которого в свою очередь нет во FreeBSD. Пути на всякий пожарный прописал абсолютные. Сгенерировал сертификат для реестра:
cd /usr/local/www/gitlab/config
openssl genrsa -out registry.key 3072
openssl req -new -key registry.key -out registry.csr
openssl x509 -req -days 365 -in registry.csr -signkey registry.key -out registry.crt
Вторая команда задает различные вопросы, я конечно же ответил на них весьма номинально:
Country Name (2 letter code) [AU]:RU
State or Province Name (full name) [Some-State]:
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:registry.local
Email Address []:
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
Что касается срока сертификата, то я для примера поставил год, но вот как лучше поступить в реальности, вопрос неоднозначный. То ли сделать срок поменьше и генерировать новый при каждом обновлении реестра, то ли поставить лет на 10 и забыть. Кстати в Docker сертификат как раз десятилетний.
Перезапустил GitLab:
service gitlab restart
Реестр пока запустил врукопашную в отдельном сеансе:
su -l git -c "registry serve /usr/local/etc/registry/config.yml"
Проверка и завершение настройки
Создал частный (private) репозиторий root/container-registry и включил в нем реестр контейнеров. Прописал registry.local в /etc/hosts. С помощью установленного ранее Podman попробовал было «запушить» образ freebsd-static:14.3, его идентификатор 749192a8d953. Оказалось, что все должно работать по https. К счастью, у нас есть не только Caddy, но и сертификат, который можно переиспользовать. Автоматический https у меня полностью отключен, так что придется еще и явно прописать редирект. Добавляем настройки в Caddyfile:
http://registry.local {
redir https://registry.local{uri}
}
registry.local {
tls /usr/local/www/gitlab/config/registry.crt /usr/local/www/gitlab/config/registry.key
reverse_proxy localhost:5000
}
Ранее я настраивал portacl только для http (да еще безапелляционно заявил, что https на виртуалке ни к чему, а вот поди ж ты), пришлось вернуть стандартную настройку. Перезапустил сервисы portacl и caddy. Авторизовал Podman в registry.local и повторно отправил образ:
podman login registry.local --tls-verify=false
podman push 749192a8d953 registry.local/root/container-registry:freebsd-14.3-static --tls-verify=false
--tls-verify=false нужно для обхода самоподписанного сертификата. Работает?!
Чтобы каждый раз не отключать проверку TLS через аргумент командной строки, добавим такой фрагмент в файл /usr/local/etc/containers/registries.conf:
[[registry]]
location = "registry.local"
insecure = true
Если работает podman_service, то целесообразно его перезапустить для применения изменений в нем.
Примечание от 18.09.2025. Фактически благодаря такой записи реестр может работать и по http, так что можно убрать редирект и сертификат из Caddyfile.
Сделаем репозиторий публичным и намутим мутку:
podman logout registry.local
podman image rm 749192a8d953
podman pull registry.local/root/container-registry:freebsd-14.3-static
Trying to pull registry.local/root/container-registry:freebsd-14.3-static...
Getting image source signatures
Copying blob bf0d0a3c3204 done |
Copying config 749192a8d9 done |
Writing manifest to image destination
749192a8d9532583948dae8a82a5aad80d4b08eb4b523890505f6d22552eebb0
Таки загружает!
Сервис rc.d
Остается открытым вопрос с автоматическим запуском реестра. Теоретически можно было бы смухлевать и добавить команду в crontab, но лучше написать сервис, хоть и весьма упрощенный.
Файл /usr/local/etc/rc.d/registry (права 755):
#!/bin/sh
# PROVIDE: registry
# REQUIRE: DAEMON NETWORKING
# BEFORE: gitlab
# KEYWORD: shutdown
#
# Add the following line to /etc/rc.conf to enable registry:
#
# registry_enable (bool): Set to "NO" by default.
# Set it to "YES" to enable registry
# registry_config (str): Set to "/usr/local/etc/registry/config.yml" by default.
# Set it to configuration file to run registry with
# registry_user (str): Set to "git" by default.
# Set it to user to run registry under
# registry_group (str): Set to "git" by default.
# Set it to group to run registry under
# registry_logfile (str): Set to "/var/log/registry.log" by default.
# Set it to file to send registry logs to
#
. /etc/rc.subr
name="registry"
rcvar="registry_enable"
load_rc_config $name
: ${registry_enable:="NO"}
: ${registry_config:="/usr/local/etc/registry/config.yml"}
: ${registry_user:="git"}
: ${registry_group:="git"}
: ${registry_logfile:="/var/log/registry.log"}
: ${registry_args:="serve $registry_config"}
: ${registry_svcj_options:="net_basic"}
pidfile="/var/run/${name}.pid"
procname=/usr/local/bin/${name}
start_precmd="registry_startprecmd"
start_cmd="registry_startcmd"
registry_startprecmd()
{
if [ ! -e "${pidfile}" ]; then
install -g ${registry_group} -o ${registry_user} -- /dev/null "${pidfile}";
fi
}
registry_startcmd()
{
daemon -u ${registry_user} -p ${pidfile} ${procname} ${registry_args} run < /dev/null >> ${registry_logfile} 2>> ${registry_logfile}
}
run_rc_command $1
Фактически я переделал сервис gitlab_pages. Помимо прочего, добавил указание запуска до GitLab. Вообще, раз теперь лог пишется в файл, возможно стоило бы повысить его уровень до warn или даже error.
Если вдруг реестр еще запущен, то выходим по Ctrl+\. Включаем и запускаем сервис:
service registry enable
service registry start
Вот теперь все практически как в лучших домах.
Прокси зависимостей
Оно включено по умолчанию и, как ни странно, тоже работает. Добавляем «реестр» 192.168.56.143 как небезопасный (GitLab как таковой у меня работает «по IP» без https):
[[registry]]
location = "192.168.56.143"
insecure = true
Авторизуем Podman непосредственно в GitLab (несмотря на публичность группы, без входа возвращается статус 403 Forbidden) и скачаем для примера все тот же образ freebsd-static:
podman login 192.168.56.143
podman pull 192.168.56.143/containers/dependency_proxy/containers/freebsd/freebsd-static:14.3
Первая containers – это идентификатор (пространство имени) группы.
В настройках группы (Settings – Package and registers, разделе Dependency proxy) можно задать настройки аутентификации в Docker Hub, по идее станет чуть свободнее в плане ограничений на загрузку образов.
Резервное копирование и обновление
Напомню основную команду бэкапа для варианта компиляции из исходников, к которой относится установка GitLab во FreeBSD:
su -l git -c "cd /usr/local/www/gitlab && rake gitlab:backup:create RAILS_ENV=production"
Файловое хранилище реестра контейнеров, благодаря выполненным настройкам, в данный архив попадает. Базу метаданных же придется сохранять отдельно:
pg_dump -U git registry | gzip -9 > registry.sql.gz
А также созданные нами файлы настроек и определения сервиса.
Обновление сводится к компиляции новой версии реестра, остановке сервиса, замене исполняемого файла, применения миграций к базе метаданных при наличии таковой и запуске сервиса обратно. Если вдруг закончился срок действия сертификата для аутентификации, то потребуется сделать его заново наряду с перезапуском GitLab и веб-сервера (если он вдруг задействован и там).
Вместо заключения
Я не очень понял, почему нет пакета для реестра контейнеров, в то время как в стандартную поставку входят Pages (с которыми-то, забегая вперед, все как раз очень сложно). К счастью, программу реестра оказалось относительно просто скомпилировать и настроить вручную.
Я подумывал о том, чтобы сделать контейнер Podman, но тогда не совсем понятно, как быть с PostgreSQL в частности и IP адресами в целом, ведь все это должно друг с другом и самим GitLab интенсивно взаимодействовать. А еще меня немного смущает Apache License 2.0, ну и актуальность сего действа (в смысле создание образа) тоже далеко не очевидна.
Категория: Программирование, веб | Опубликовано 12.09.2025 | Редакция от 18.09.2025
Похожие материалы
Переезд реестра контейнеров GitLab в S3
Ранее я писал о MinIO в качестве хранилища реестра контейнеров, но в случае VDS/VPS такой вариант экономически не выгоден: чуть ли не на порядок дешевле воспользоваться услугой аренды S3 у какого-нибудь облачного провайдера. Что я и решил сделать, ведь место на сервере стало очень быстро заканчиваться. Заодно мигрируем прокси зависимостей, LFS и всякое такое.






