Разворачивал недавно self-hosted docker registry, потому что dockerhub сказали, что я плохой и запретили продлять подписку на моем шикарном аккаунте, где хранились все мои образы за последние много-много лет.
Изначально я хотел развернуть себе какой-нибудь стильный модный молодежный registry с красивым UI, графиками и админкой, но поизучав немного существующие решения, решил отказаться. Т.к. их рекомендуют поднимать не в докере, а прям на тачке. Я же не хотел устанавливать на домашний сервер никакие лишние штуки, потому что он у меня как большая помойка с кучей запущенных docker-контейнеров, но зато на хосте не установлены всякие nodejsы, фреймворки питонов и вот это вот все. Руками пихать все эти модные registry в докер тоже не хотелось, т.к. я ленивый.
В общем, решил я установить стандартный registry от docker + какой-то простенький UI, который умеет максимум Basic Authentication в браузере, да и бог с ним. Для того чтобы быстро развернуть и перестать мучиться, пойдет (там даже нельзя readonly пользователя сделать без костылей).
Взял я, значит, официальный образ registry, пихнул все это в docker-compose и понял, что если я сейчас в качестве volume подмонтирую туда просто папку, расположенную в raid массиве, то все это добро будет бесконтрольно расти и, рано или поздно, засрет все мои 23Тб. Поэтому я начал изучать вопрос, а как можно установить лимит на volume. Типа как когда создаешь виртуалку и указываешь размер диска для нее. Оказалось, что стандартными средствами сделать такой финт ушами нельзя. Эх, вот бы я изначально организовывал домашний сервер, как кучу виртуалок, можно было бы под registry выделить отдельный диск.
В какой-то момент я отчаялся, но вспомнил, что, вообще-то, на домашнем сервере установлен Debian, а значит, как самый настоящий красноглазик, я смогу что-то да наколдовать. Итак, как же сделать volume фиксированного размера в docker-compose (или просто для docker-контейнера).
1. Создаем в нужном месте файл необходимого размера, заполненный нулями (в моем случае примерно 40 гб)
dd if=/dev/zero of=/storage/docker/infra/hub/storage.ext3 bs=512 count=81920000
Как я получил 40 гб: 512 bytes * 81920000 = 41943040000 bytes ~ 40 Gb
В зависимости от размера и скорости вашего диска, это может занять некоторое время
2. Создаем в полученном файле ext3 файловую систему (приколдес, да?)
mkfs -t ext3 -q /storage/docker/infra/hub/storage.ext3 -F
3. Теперь создаем папку, в которую будем монтировать нашу новую файловую систему
mkdir -p /hub-storage
4. Осталось настроить автоматическое монтирование нашего нового диска в папку. Для этого открываем на редактирование /etc/fstab и дописываем туда такую строчку:
/storage/docker/infra/hub/storage.ext3 /hub-storage ext3 rw,loop,usrquota,grpquota 0 0
Закрываем, сохраняем, вы великолепны. Теперь диск будет автоматически монтироваться после перезагрузки. Но сейчас нам надо его смонтировать руками (потому что мы же не перезагружались), для этого выполняем команду
mount /hub-storage
5. Поздравляю, теперь у вас есть папка (диск вообще-то) /hub-storage, размер которой ограничен 40 гб и которую можно примонтировать в докер. Например так:
version: '3'
services:
registry:
container_name: docker_hub
image: registry:2
restart: unless-stopped
environment:
REGISTRY_HTTP_HEADERS_Access-Control-Allow-Origin: '[http://registry.example.com]'
REGISTRY_HTTP_HEADERS_Access-Control-Allow-Methods: '[HEAD,GET,OPTIONS,DELETE]'
REGISTRY_HTTP_HEADERS_Access-Control-Allow-Credentials: '[true]'
REGISTRY_HTTP_HEADERS_Access-Control-Allow-Headers: '[Authorization,Accept,Cache-Control]'
REGISTRY_HTTP_HEADERS_Access-Control-Expose-Headers: '[Docker-Content-Digest]'
REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY: /data
REGISTRY_STORAGE_DELETE_ENABLED: 'true'
REGISTRY_AUTH_HTPASSWD_PATH: /etc/docker/registry/htpasswd
REGISTRY_AUTH_HTPASSWD_REALM: "Registry Realm"
REGISTRY_AUTH: "htpasswd"
volumes:
- /hub-storage:/data