Мы уже научились использовать образы и модифицировать их под свои нужды. А как их хранить и передавать своим коллегам? Через Docker Registry. Сегодня мы разберемся, как развернуть локальный Docker реестр.
Он поможет вам хранить, управлять и распространять образы контейнеров внутри вашей команды без необходимости постоянного обращения к публичным реестрам.
- Шаг 1: Запуск Docker Registry в контейнере
- Шаг 2: Тегирование и отправка образов в Registry
- Шаг 3: Использование образов из локального Registry
- Шаг 4: Подключение к Docker Registry с другого хоста
- Шаг 5: Безопасноcть работы Registry
Пару слов об окружении:
В рамках данной статьи, Docker Registry будет запущен на хосте в локальной сети, без использования SSL сертификата и https. Чтобы Docker мог обращаться к такому реестру его надо внести в файл daemon.json (локация варьируется в зависимости от ОС).
В нашем случае файл /etc/docker/daemon.json имеет следующий вид (используйте IP вашего хоста):
{ "insecure-registries":["192.168.0.114:5000"] }
И перезапустить Docker:
[root@waky ~]# systemctl restart docker
[root@waky ~]#
Шаг 1: Запуск Docker Registry в контейнере
Самый простой способ — это использовать официальный образ Docker Registry. Выполните следующую команду для запуска Registry:
[root@waky ~]# docker run -d -p 5000:5000 --name local-registry registry:3
Unable to find image 'registry:3' locally
3: Pulling from library/registry
f637881d1138: Pull complete
ed8e0977a7e0: Pull complete
9fc4080776f9: Pull complete
1a51344b3dd0: Pull complete
658f32c91179: Pull complete
Digest: sha256:cd92709b4191c5779cd7215ccd695db6c54652e7a62843197e367427efb84d0e
Status: Downloaded newer image for registry:3
d2db9d1e681a1b5a34925106fa0bf768362e270f7812c821e3340771c6faabbf
[root@waky ~]#
Использованные параметры:
-d — запуск в фоновом режиме
-p 5000:5000 — проброс порта 5000, чтобы обращаться к Registry через IP-адрес или localhost
–name local-registry — имя контейнера для удобства
registry:3 — версия Docker Registry
После выполнения команды у вас будет запущен локальный Registry, доступный по адресу:
http://<ваш_IP>:5000
В моем случае это:
http:// 192.168.0.114:5000
Шаг 2: Тегирование и отправка образов в Registry
Если у вас уже есть кастомный образ, который вы хотите поместить в реестр, можете использовать его. Мы же создадим новый образ, с помощью простого Dockerfile следующего содержания:
FROM alpine:latest
RUN apk add wget
За основу мы берем образ alpine и устанавливаем утилиту wget, если вы не знакомы с использованием Dockerfile, вы найдете подробности в статье об образах.
Командой build мы собираем образ из Dockerfile находящегося в текущей (./) директории:
[root@waky my-app]# docker build -t my-app ./
[+] Building 6.1s (6/6) FINISHED
docker:default
=> [internal] load build definition from Dockerfile
0.1s
=> => transferring dockerfile: 133B
0.0s
=> [internal] load metadata for docker.io/library/alpine:latest
0.0s
=> [internal] load .dockerignore
0.0s
=> => transferring context: 2B
0.0s
=> CACHED [1/2] FROM docker.io/library/alpine:latest
0.0s
=> [2/2] RUN apk add wget
5.1s
=> exporting to image
0.4s
=> => exporting layers
0.3s
=> => writing image sha256:8e5ddd9894ab6f71a38606884f795af7d83ad5305626b4bd6a7e3a5f7179babc
0.0s
=> => naming to docker.io/library/my-app
0.0s
[root@waky my-app]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
my-app latest 8e5ddd9894ab 13 seconds ago 14.2MB
nginx latest d261fd19cb63 2 days ago 152MB
alpine latest 706db57fb206 4 weeks ago 8.32MB
registry 3 e4e570676819 7 months ago 57.7MB
[root@waky my-app]#
Наш новый образ my-app появился в списке.
Добавим этому образу новый тег (команда tag), не забудьте указать свой IP:
[root@waky my-app]# docker tag my-app 192.168.0.114:5000/my-app
[root@waky my-app]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
192.168.0.114:5000/my-app latest 8e5ddd9894ab 12 minutes ago 14.2MB
my-app latest 8e5ddd9894ab 12 minutes ago 14.2MB
nginx latest d261fd19cb63 2 days ago 152MB
alpine latest 706db57fb206 4 weeks ago 8.32MB
registry 3 e4e570676819 7 months ago 57.7MB
[root@waky my-app]#
Использованные параметры:
my-app – имя образа которому присваивается тег
192.168.0.114:5000/my-app – новый тег, по шаблону IP_хоста:порт/имя образа
В моем случае хост на котором я запустил локальный реестр имеет адрес 192.168.0.114, а порт при запуске контейнера с Docker Registry мы указали 5000.
Теперь отправим образ в локальный Docker Registry:
[root@waky my-app]# docker push 192.168.0.114:5000/my-app
Using default tag: latest
The push refers to repository [192.168.0.114:5000/my-app]
4bc8b0b331f1: Pushed
256f393e029f: Pushed
latest: digest: sha256:9e2e247248398e24153bd7fba9c5286a631963d9d7b6337f47f3d2ca4fc2d86d size: 738
[root@waky my-app]#
Образ успешно загрузился, и будет храниться у вас в локальном Registry.
Можем проверить образа в локальном реестре с помощью curl:
[root@waky my-app]# curl http://localhost:5000/v2/_catalog
{"repositories":["my-app"]}
[root@waky my-app]#
Если вы столкнулись с ошибкой вида:
http: server gave HTTP response to HTTPS client
перепроверьте, правильно ли вы добавили реестр в файл daemon.json
Шаг 3: Использование образов из локального Registry
Удалим образа из нашего локального Docker, чтобы убедиться что они будут подгружаться из Registry:
[root@waky my-app]# docker rmi my-app 192.168.0.114:5000/my-app
Untagged: my-app:latest
Untagged: 192.168.0.114:5000/my-app:latest
Untagged: 192.168.0.114:5000/my-app@sha256:9e2e247248398e24153bd7fba9c5286a631963d9d7b6337f47f3d2ca4fc2d86d
Deleted: sha256:8e5ddd9894ab6f71a38606884f795af7d83ad5305626b4bd6a7e3a5f7179babc
[root@waky my-app]#
Запустим контейнер из образа, который хранится в нашем Registry:
[root@waky my-app]# docker run -td --name my_container 192.168.0.114:5000/my-app /bin/sh
Unable to find image '192.168.0.114:5000/my-app:latest' locally
latest: Pulling from my-app
2d35ebdb57d9: Already exists
140a5e68c1f2: Already exists
Digest: sha256:9e2e247248398e24153bd7fba9c5286a631963d9d7b6337f47f3d2ca4fc2d86d
Status: Downloaded newer image for 192.168.0.114:5000/my-app:latest
a3c48eaf675fe9f59a64ddd701a0ad82590a840ee716678cdfbdabdd0406f874
[root@waky my-app]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
192.168.0.114:5000/my-app latest 8e5ddd9894ab About an hour ago 14.2MB
nginx latest d261fd19cb63 2 days ago 152MB
alpine latest 706db57fb206 4 weeks ago 8.32MB
registry 3 e4e570676819 7 months ago 57.7MB
[root@waky my-app]#
Docker не нашел запрашиваемый образ локально и выкачал его из нашего собственного хранилища.
Мы успешно настроили и проверили работу локального Docker Registry.
Шаг 4: Подключение к Docker Registry с другого хоста
На прошлых этапах все действия осуществлялись в рамках одного хоста, давайте попробуем подключиться к нашему Docker Registry, например, с нашего рабочего ПК.
Ранее на него мы установили Docker Desktop. Перед запуском Docker надо внести изменения в файл daemon.json
В моем случае это:
C:\Users\waky\.docker\daemon.json
где С – диск на котором установлена система, waky – имя пользователя
Соблюдая синтаксис json добавьте директиву “insecure-registries”, в моем случае содержимое файла выглядит так:
{
"builder": {
"gc": {
"defaultKeepStorage": "20GB",
"enabled": true
}
},
"experimental": false,
"insecure-registries": [
"192.168.0.114:5000"
]
}
192.168.0.114 – адрес хоста с реестром (замените на свой)
После сохраняем файл и запускаем/перезапускаем Docker Desktop.
Когда запустится Docker, открываем командную панель и выполняем ту же самую команду, что и на 3 шаге:
docker run -td --name my_container 192.168.0.114:5000/my-app /bin/sh
Программа обратиться к Docker Registry работающем на хосте с указанным IP, скачает образ и запустит контейнер из него.

Если на этапе подключения к реестру вы столкнулись с таймаутом, вероятнее всего вас блокирует файрвол. Убедитесь, что на принимающем хосте открыт доступ до порта 5000.
Шаг 5: Безопасность работы Registry
Мы рассмотрели упрощенный вариант использования Docker Registry. Его использование в таком виде возможно в локальных сетях без постороннего доступа.
В реальности же вы вряд ли захотите, чтобы ваш личный реестр образов был доступен без ограничений.
По умолчанию, Registry работает без защиты, работает по HTTP и не требует авторизации.
Для использования в закрытой сети это может быть приемлемо, но для производства рекомендуется настроить:
- TLS (SSL) — для шифрования трафика
- Аутентификацию — для ограничения доступа
- Файрвол – для ограничения трафика по IP
Эти настройки требуют генерации сертификатов и дополнительных конфигураций и заслуживают отдельной большой статьи.
Заключение
Теперь у вас есть полностью подготовленный и работающий локальный Docker Registry, который упростит вашу работу с образами и их передачу.
Это отличный шаг в развитии инфраструктуры контейнеризации в вашей среде.