docker pull
и да публикува Images с docker push. Registry може да бъде публичен
като Docker Hub или частен, управляван от самия мен.
1. Защо ми е необходим Registry?
В началото мога да създам Image директно на server-а и веднага да стартирам container. Това работи, но много бързо се появява проблем: ако имам втори server, staging среда, backup машина или CI/CD pipeline, трябва да прехвърля Image-а.
Registry решава точно този проблем. Вместо да копирам ръчно tar архиви между машините, публикувам Image-а в Registry и всяка машина го получава по стандартния Docker механизъм.
- build-вам Image веднъж;
- публикувам го в Registry;
- другите Docker hosts го изтеглят;
- Compose може да използва конкретна версия;
- deployment-ът става възпроизводим.
2. Docker Hub и private Registry
Docker Hub е най-познатият публичен Registry. Той е удобен за публични Images и за много стандартни workflow-и.
При собствена инфраструктура обаче често предпочитам private Registry. Тогава Images остават в моята инфраструктура и мога да контролирам достъпа, storage-а и lifecycle-а им.
| Вариант | Подходящ за |
|---|---|
| Docker Hub | Публични Images, малки проекти и бърз старт. |
| Private Registry | Вътрешни приложения и собствена инфраструктура. |
| Cloud Registry | CI/CD и инфраструктура в cloud среда. |
3. Как изглежда един Image адрес?
Registry адресът е част от името на Image-а. Например:
registry.example.com/myapp:1.0
Тук registry.example.com е Registry, myapp е repository,
а 1.0 е tag.
source
Image
storage
deployment
4. Tag — версията на Image-а
Tag-ът позволява да различавам различни версии на един Image.
docker tag myapp:latest registry.example.com/myapp:1.0
docker tag myapp:latest registry.example.com/myapp:1.1
В production не разчитам сляпо на latest. Предпочитам ясни версии,
за да знам точно кой Image е deployment-нат.
latest не е версия.
Той е tag. Ако съдържанието зад този tag се промени, следващият
docker pull може да получи различен Image.
5. Push — публикуване на Image
След като Image-ът има име, сочещо към Registry, мога да го публикувам.
docker login registry.example.com
docker push registry.example.com/myapp:1.0
Docker разделя Image-а на layers и качва необходимите layers към Registry. Ако даден layer вече съществува, той не се качва повторно.
6. Pull — изтегляне на Image
На друг Docker host мога да получа същия Image със:
docker login registry.example.com
docker pull registry.example.com/myapp:1.0
След това Image-ът може да бъде използван нормално:
docker run -d --name myapp registry.example.com/myapp:1.0
7. Private Registry с Docker Registry
За малка собствена инфраструктура мога да стартирам стандартния Registry като container. Това е удобен начин да имам собствено Image хранилище без сложна външна платформа.
docker run -d \
--name registry \
--restart unless-stopped \
-p 5000:5000 \
-v registry-data:/var/lib/registry \
registry:3
Данните се записват в Docker volume registry-data.
В реална инфраструктура бих обърнал специално внимание на backup-а на това хранилище.
8. Използване на локалния Registry
След като Registry работи локално на същия host, мога да tag-на Image-а към него:
docker tag myapp:1.0 localhost:5000/myapp:1.0
docker push localhost:5000/myapp:1.0
Проверявам наличните repositories:
curl http://localhost:5000/v2/_catalog
9. HTTPS и сигурност
Registry, който се използва между различни hosts, не трябва да бъде оставян незащитен. Най-малкото трябва да имам TLS, а при private Registry и контрол на достъпа.
- HTTPS/TLS за комуникацията;
- authentication за потребителите;
- ограничен достъп до Registry;
- backup на storage-а;
- контрол върху това кой може да push и pull.
10. Authentication
При private Registry не искам всеки, който има мрежов достъп, да може да публикува Images. Docker поддържа стандартния login workflow:
docker login registry.example.com
След успешен login Docker съхранява credentials според конфигурацията на клиента. На production host трябва внимателно да се управлява кой има достъп до тези credentials.
11. Registry и Docker Compose
Именно тук Registry започва да става особено полезен. Compose може да използва Image, който не се build-ва локално, а се изтегля от Registry.
services:
web:
image: registry.example.com/myapp:1.0
restart: unless-stopped
ports:
- "8080:8080"
db:
image: mariadb:11
restart: unless-stopped
environment:
MARIADB_DATABASE: app
MARIADB_USER: app
MARIADB_PASSWORD: change-me
MARIADB_ROOT_PASSWORD: change-me-too
Така build процесът може да се случва на отделна машина или CI/CD runner, а production host-ът просто получава готовия Image.
12. Versioning на Images
Добрата практика е да използвам ясна схема за versioning. Например:
myapp:1.0.0
myapp:1.1.0
myapp:1.1.1
При нужда мога да използвам и допълнителни tags като stable или testing,
но production deployment-ите е по-добре да сочат към конкретна версия.
13. Image digest — още по-точно идентифициране
Tag-ът е подвижен. Digest-ът идентифицира конкретно съдържание на Image.
docker image inspect registry.example.com/myapp:1.0
В среди, където е критично deployment-ът да бъде напълно възпроизводим, pin-ването към digest може да даде по-сигурна гаранция, че се използва точно определен Image.
14. Registry не е backup система
Ако container използва persistent data, тази информация трябва да бъде защитена отделно. Registry пази Image-а, а не данните, които приложението е натрупало по време на работа.
15. Retention и почистване
С времето Registry може да се напълни с десетки или стотици стари Images и layers. Затова трябва да имам политика кои версии се пазят и кои могат да бъдат премахнати.
- пазя production версиите;
- пазя необходимите rollback версии;
- премахвам временните build tags;
- следя свободното място;
- правя backup преди рискови операции.
16. Практически workflow
За собствените ми проекти workflow-ът може да изглежда така:
Dockerfile + application
създавам Image
публикувам версията
production host получава Image-а
стартира stack-а
17. Най-честите грешки
- използване на
latestкато единствена версия; - private Registry без HTTPS;
- Registry без authentication, когато е достъпен извън локалната среда;
- липса на backup на Registry storage-а;
- смесване на Image backup с backup на application data;
- натрупване на огромен брой стари Images без retention политика;
- изтриване на Image-и без да е проверено кои deployment-и ги използват.
18. Моите практически правила
| Правило | Причина |
|---|---|
| Всеки production Image има ясна версия | Знам какво точно е deployment-нато. |
| Private Registry използва TLS | Credentials и Images не се предават незащитено. |
| Registry storage-ът има backup | Registry също е инфраструктура. |
| Application data се backup-ва отделно | Image-ът не съдържа runtime data. |
| Използвам retention политика | Контролирам storage-а и старите версии. |
19. Заключение
С Dockerfile вече мога да създавам собствен Image. С Registry правя следващата крачка: отделям build процеса от машината, на която ще работи приложението.
Това е особено важно при повече от един Docker host, при staging/production среда и при CI/CD. Build-вам веднъж, публикувам конкретна версия и deployment-ът получава същия Image.
В следващата част ще премина към Docker Security — users, capabilities, secrets, image scanning, rootless containers и практиките, които използвам, за да не превръщам container-а в излишен security риск.