Docker и Docker Compose — професионално ръководство

Част 9: Docker Registry — съхранение и управление на Images

След като вече мога да създавам собствени Docker Images, идва естественият въпрос: къде ги съхранявам и как ги прехвърлям надеждно между различни машини? Тук идва Docker Registry — мястото, от което Images се публикуват, изтеглят и управляват.

Docker Registry е хранилище за Docker Images. Docker Engine може да изтегля Images от Registry с 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.

Dockerfile

source

docker build

Image

Registry

storage

docker pull

deployment

4. Tag — версията на Image-а

Tag-ът позволява да различавам различни версии на един Image.

Tag-ване
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, мога да го публикувам.

Push
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 със:

Pull
docker login registry.example.com
docker pull registry.example.com/myapp:1.0

След това Image-ът може да бъде използван нормално:

Run
docker run -d --name myapp registry.example.com/myapp:1.0

7. Private Registry с Docker Registry

За малка собствена инфраструктура мога да стартирам стандартния Registry като container. Това е удобен начин да имам собствено Image хранилище без сложна външна платформа.

Стартиране на Registry
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-а към него:

Local Registry
docker tag myapp:1.0 localhost:5000/myapp:1.0

docker push localhost:5000/myapp:1.0

Проверявам наличните repositories:

Registry API
curl http://localhost:5000/v2/_catalog
Важно: примерът с HTTP е подходящ само за лабораторна или изолирана среда. За Registry, достъпен през мрежата, използвам TLS и authentication.

9. HTTPS и сигурност

Registry, който се използва между различни hosts, не трябва да бъде оставян незащитен. Най-малкото трябва да имам TLS, а при private Registry и контрол на достъпа.

  • HTTPS/TLS за комуникацията;
  • authentication за потребителите;
  • ограничен достъп до Registry;
  • backup на storage-а;
  • контрол върху това кой може да push и pull.

10. Authentication

При private Registry не искам всеки, който има мрежов достъп, да може да публикува Images. Docker поддържа стандартния login workflow:

Login
docker login registry.example.com

След успешен login Docker съхранява credentials според конфигурацията на клиента. На production host трябва внимателно да се управлява кой има достъп до тези credentials.

11. Registry и Docker Compose

Именно тук Registry започва да става особено полезен. Compose може да използва Image, който не се build-ва локално, а се изтегля от Registry.

compose.yaml
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. Например:

Примерни tags
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 система

Това е важно разграничение. Registry съхранява Images, но сам по себе си не е пълна backup стратегия за инфраструктурата. Не трябва да приемам, че наличието на Image в Registry означава, че имам backup на application data, volumes, databases и configuration.

Ако container използва persistent data, тази информация трябва да бъде защитена отделно. Registry пази Image-а, а не данните, които приложението е натрупало по време на работа.

15. Retention и почистване

С времето Registry може да се напълни с десетки или стотици стари Images и layers. Затова трябва да имам политика кои версии се пазят и кои могат да бъдат премахнати.

  • пазя production версиите;
  • пазя необходимите rollback версии;
  • премахвам временните build tags;
  • следя свободното място;
  • правя backup преди рискови операции.

16. Практически workflow

За собствените ми проекти workflow-ът може да изглежда така:

1. Source code

Dockerfile + application

2. docker build

създавам Image

3. docker push

публикувам версията

4. docker pull

production host получава Image-а

5. Docker Compose

стартира 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-а и старите версии.
Моят принцип: Registry не трябва да бъде просто „склад за Images“. Той е част от deployment процеса. Когато versioning-ът, достъпът, backup-ът и lifecycle-ът са под контрол, преместването на приложение между Docker hosts става значително по-просто и предвидимо.

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 риск.