Docker Registry у homelab – це приватний реєстр контейнерних образів для локальної інфраструктури. Такий вузол закриває просту задачу: зберігати власні образи, віддавати їх по HTTPS і не світити їх назовні. Нижче – робоча схема з TLS, базовою авторизацією, постійним сховищем і перевіркою клієнта.
Підхід підходить для кількох серверів, CI-джоб і домашнього Kubernetes або Docker Swarm. Для одного хоста можна жити й без окремого реєстру, але після появи другого вузла, тестового пайплайна або власних збірок тягати образи вручну вже незручно.
Нормальна межа такого розгортання – невеликий homelab, де важливі контроль доступу і прогнозована поведінка. Якщо потрібні web UI, реплікація, сканування вразливостей і керування проектами, голого Registry швидко стане мало – там уже логічніше дивитися в бік Harbor.
Що вийде в результаті
Фінальна схема проста: контейнер Docker Distribution слухає HTTPS, використовує сертифікат для вашого hostname, перевіряє логін і пароль через htpasswd та пише образи у змонтований каталог. Клієнти Docker працюють з ним як зі звичайним приватним endpoint.
Для прикладу нижче використано домен registry.example.lan. Його потрібно замінити на свій FQDN, який резолвиться всередині мережі.
Що підготувати до запуску
Потрібен Linux-хост з Docker і Docker Compose plugin, окремий DNS-ім’я для реєстру та сертифікат, якому довіряють клієнти. Найчастіше в homelab це або внутрішній CA, або сертифікат від reverse proxy, який уже обслуговує локальні сервіси.
Registry боляче реагує не на складність, а на дрібні перекоси. Ім’я в сертифікаті не збігається з hostname – отримаєте помилку TLS. Сертифікат довірений браузеру, але не Docker daemon – push теж впаде. Саме тут часто витрачається більше часу, ніж на запуск контейнера.
Структура каталогів може бути такою:
sudo mkdir -p /opt/registry/{data,auth,certs}
Створення користувача для базової авторизації
Docker Registry підтримує кілька механізмів доступу, але для homelab базова авторизація через htpasswd закриває більшість задач. Вона проста, прозора і не тягне за собою окремий identity stack.
Файл паролів зручно згенерувати контейнером httpd:
docker run --rm --entrypoint htpasswd httpd:2 -Bbn homelab StrongPassword > /opt/registry/auth/htpasswd
Користувача можна назвати як завгодно. Пароль краще не зберігати в shell history. Для цього варто або очистити історію після команди, або згенерувати файл іншим способом.
Як підключити TLS без insecure registry
Self-hosted Docker Registry варто піднімати відразу по TLS. Режим insecure registry працює для швидкого тесту, але в реальній мережі тягне за собою зайві винятки на всіх клієнтах і розмиває контроль над довірою до endpoint.
У каталог /opt/registry/certs потрібні два файли: сертифікат і приватний ключ. Назви довільні, але в compose-файлі вони мають збігатися. Якщо сертифікат випущений внутрішнім CA, кореневий сертифікат треба встановити на кожен Docker-клієнт.
Для локального PKI це зазвичай виглядає так:
/opt/registry/certs/registry.crt /opt/registry/certs/registry.key
На клієнті Docker довірений сертифікат для registry hostname часто кладуть у каталог:
/etc/docker/certs.d/registry.example.lan/ca.crt
Якщо endpoint працює не на стандартному 443 порту, каталог має включати порт, наприклад registry.example.lan:5000.
Docker Registry з TLS та авторизацією – compose-файл
Нижче мінімальна конфігурація, якої вистачає для приватного реєстру образів. Вона вмикає файлове сховище, htpasswd auth і HTTPS прямо в контейнері. Для homelab це нормальний базовий варіант без зайвих шарів.
services:
registry:
image: registry:2
container_name: registry
restart: unless-stopped
ports:
- "443:5000"
environment:
REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY: /var/lib/registry
REGISTRY_AUTH: htpasswd
REGISTRY_AUTH_HTPASSWD_REALM: Registry Realm
REGISTRY_AUTH_HTPASSWD_PATH: /auth/htpasswd
REGISTRY_HTTP_ADDR: 0.0.0.0:5000
REGISTRY_HTTP_TLS_CERTIFICATE: /certs/registry.crt
REGISTRY_HTTP_TLS_KEY: /certs/registry.key
volumes:
- /opt/registry/data:/var/lib/registry
- /opt/registry/auth:/auth:ro
- /opt/registry/certs:/certs:ro
Зберегти це можна як /opt/registry/docker-compose.yml, після чого запустити:
cd /opt/registry docker compose up -d
Порт 443 назовні зручний тим, що клієнту не треба вказувати нестандартний endpoint. Якщо на хості вже стоїть reverse proxy, краще не публікувати порт напряму, а передати трафік через проксі з TLS termination або TCP passthrough – залежно від вашої схеми.
Коли краще поставити reverse proxy попереду
Якщо в homelab уже працює Traefik, Nginx Proxy Manager або Caddy, Docker Registry можна сховати за проксі. Це спрощує випуск сертифікатів і прибирає дублювання TLS-налаштувань на кожному сервісі.
Є нюанс. Для великих push-операцій проксі повинен коректно працювати з довгими HTTP-сесіями, заголовками авторизації та розміром body. Саме на цьому місці часто з’являються обриви завантаження, 413, 502 або зависання на фінальному шарі. Якщо реєстр стоїть окремо й немає потреби в єдиній точці входу, прямий TLS у контейнері зазвичай спокійніший.
Перевірка логіна, push і pull
Після запуску варто пройти повний цикл: login, push, pull. Якщо всі три операції відпрацювали, Docker Registry з TLS та авторизацією готовий до роботи. Сам факт, що контейнер у статусі Up, ще нічого не доводить.
- Увійти в реєстр:
docker login registry.example.lan
- Позначити локальний образ новим тегом:
docker tag nginx:latest registry.example.lan/nginx:latest
- Відправити образ у реєстр:
docker push registry.example.lan/nginx:latest
- Видалити локальний тег і витягнути образ назад:
docker image rm registry.example.lan/nginx:latest docker pull registry.example.lan/nginx:latest
Додаткова перевірка – подивитися, чи з’явилися дані в каталозі /opt/registry/data, і чи немає помилок у логах контейнера:
docker logs registry --tail 100
Де Docker Registry ламається найчастіше
Проблем у такій схемі небагато, але вони повторюються. Більшість з них не в самому Registry, а в стику між Docker daemon, TLS і мережею.
Сертифікат приймає curl, але Docker не довіряє
Docker використовує власну модель довіри до registry endpoint. Системний CA store і поведінка curl тут не завжди збігаються. Якщо login падає з x509 error, перевіряти треба каталог /etc/docker/certs.d/… і точний hostname.
Push обривається на великих шарах
Таке часто трапляється за reverse proxy або на нестабільному NAS-сховищі. Сам Registry поводиться спокійно, а от проксі може впиратися в timeout або ліміт розміру запиту. Для домашнього реєстру локальний SSD помітно надійніший за мережеву шару, навіть якщо вона швидка на папері.
Після зміни сертифіката клієнти все одно не входять
У Docker daemon буває впертий кеш стану з’єднань. Після оновлення CA або hostname інколи доводиться перезапустити Docker service на клієнті, інакше старий ланцюжок довіри висить довше, ніж хотілося б.
Видалення образів не звільняє місце
У Registry очищення сховища не зводиться до простого delete тега. Без прибирання невикористаних blob каталог росте далі. Для маленького homelab це помітно не одразу, а через кілька циклів CI місце зникає дуже швидко.
Що вибрати для сховища образів
Для self-hosted Docker Registry в homelab найпростіше і найстабільніше працює локальне файлове сховище. Воно добре переносить рестарти, не додає мережевого шару і спрощує бекап. Знімок каталогу часто достатній.
Мережеві файлові системи теж трапляються, але там більше шансів впіймати дивні затримки або проблеми з блокуванням. Для невеликої інфраструктури краще тримати metadata і blobs локально, а резервні копії вже вивозити на NAS або object storage.
Ще один практичний момент: registry з CI-пайплайнами активно пише дрібні файли. На повільному диску це відчувається сильніше, ніж при звичайному pull. Якщо образи штовхаються часто, диск стає важливішим за CPU.
Коли цього рішення вже мало
Чистий Docker Registry добре закриває задачу приватного реєстру образів. Але він лишається саме бекендом для зберігання. Без UI, ролей рівня проектів, політик реплікації та нормального lifecycle management межа настає швидко.
Для 2-3 вузлів, ручного push і кількох власних сервісів цього вистачає з запасом. Коли з’являються кілька команд, окремі namespace, залежність від CI і потреба бачити, хто що залив, варто мігрувати на більш важку платформу. На практиці тут часто обирають Harbor.
Якщо ж потрібен просто приватний endpoint без зайвої надбудови, self-hosted Docker Registry з TLS та авторизацією лишається тверезим і робочим варіантом.