Skip to main content

Архивация образов и Хранилище образов (hub)

Терминология

реестр (registry или hub) – сервис, отвечающий за хранение и распространение образов.
репозиторий (repository) – набор взаимосвязанных образов, обычно различные версии приложения
тег (tag) – алфавитно-цифровой идентификатор, присваиваемый образам внутри репозитория (например, 14.04 или stable). Тегов может быть много.
Пространства имен:

  • начинающиеся с текстовой строки и слеша (/), такие как amouat/revealjs В репозитории Docker Hub это образы, выгруженные конкретным пользователем.
  • имена без префиксов и слешей, принадлежат пространству имен «root», управляемому компанией Docker Inc.
  • имена с префиксами в виде имени хоста или IP-адреса представляют образы, хранящиеся в сторонних реестрах (не в Docker Hub). Например, localhost:5000/wordpress

Docker сохраняет аутентификационную информацию в файле .dockercfg, расположенном в вашем домашнем каталоге.

Создание архива образа из существующего образа

Создаем Dockerfile 

FROM alpine:latest
ARG NODE_ENV=production2
ENV NODE_ENV=${NODE_ENV}
RUN mkdir /var/www
RUN echo $NODE_ENV > /var/www/first.txt
CMD ["cat", "/var/www/first.txt"]

Собираем образ 

docker build -t bobrobot:1.0 .

 Сохраняем образ, копируем и устанавливаем на нужной системе, и запускаем

docker save bobrobot:1.0 > bobrobot:1.0.tar
docker load -i bobrobot\:1.0.tar
docker run bobrobot:1.0

Команды

Команда Доп. пар. Описание
docker login
Регистрация/вход на сервер реестра. По умолчанию Docker Hub. 
docker login https://hub.bobrobotirk.ru
docker logout
Выход из реестра Docker. По умолчанию Docker Hub.
docker pull
Загружает заданный образ из реестра. Реестр определяется по имени образа, по умолчанию принимается Docker Hub.
docker push
Выгружает образ или репозиторий в заданный реестр. При отсутствии тега выгружаются все образы указанного репозитория в заданный реестр. 
docker push hub.bobrobotirk.ru/testimage
docker search
Выводит список общедоступных репозиториев из реестра Docker Hub
docker build .


-t Определение имени репозитория и тега
docker tag <current> <in hub>
Устанавливается соответствие имени с образом, который ссылается на образ в репозитории Docker Hub. 
docker tag testimage hub.bobrobotirk.ru/testimage

Локальный hub (теория из разных источников, кое-что устаревшее)

Пример

На серверной стороне: 

mkdir dockertest_certs
openssl req -newkey rsa:4096 -nodes -sha256 -subj "/CN=dockertest" -addext "subjectAltName = DNS:dockertest" -keyout dockertest_certs/domain.key -x509 -days 365 -out dockertest_certs/domain.crt
docker run -d -p 5000:5000 -v $(pwd)/dockertest_certs:/certs -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt -e REGISTRY_HTTP_TLS_KEY=/certs/domain.key --restart=always --name registry registry
docker run --entrypoint htpasswd httpd:2 -Bbn testuser testpassword >> auth/htpasswd #добавить пользователя

На клиентской стороне (из-под root): 

mkdir -p /etc/docker/certs.d/dockertest:5000
#добавить в /etc/hosts запись о сервере dockertest
scp sergey@dockertest:/home/sergey/dockertest_certs/domain.crt /etc/docker/certs.d/dockertest:5000/ca.crt
service docker restart

Перелинковать на клиенте образ на новый хаб и загрузить его 

docker tag amouat/identidock:0.1 dockertest:5000/identidock:0.1
docker push dockertest:5000/identidock:0.1

Пример docker-compose.yml для запуска локального реестра

services:
 registry:
  restart: always
  image: registry
  ports:
   - "5000:5000"
  environment:
   REGISTRY_HTTP_TLS_CERTIFICATE: /certs/domain.crt
   REGISTRY_HTTP_TLS_KEY: /certs/domain.key
   REGISTRY_AUTH: htpasswd
   REGISTRY_AUTH_HTPASSWD_PATH: /auth/htpasswd
   REGISTRY_AUTH_HTPASSWD_REALM: Registry Realm
  volumes:
   - ./dockertest_certs:/certs
   - ./auth:/auth

Практический запуск регистра

Поскольку это пока что тестовый хаб, решил сделать сертификат LetsEncrypt. На dns сервере сделал запись сайта hub.bobrobotirk.ru. Прокинул порты 443 и 8090 до виртуальной машины.  Создал папки 

mkdir data
mkdir auth
mkdir certs

В папку certs скопировал сертификат и ключ. Для создания пользователей установил утилиту 

sudo apt-get install apache2-utils

Создал пользователя testuser с паролем StrongPassword

htpasswd -Bbn testuser StrongPassword > auth/htpasswd

Для добавления пользователей: 

htpasswd -Bb auth/htpasswd user2 password2

Создал docker-compose.yaml 

services:
  registry-server:
    image: registry:2.8.2
    container_name: registry-server
    restart: always
    ports:
      - "443:5000" # Перенаправление HTTPS-трафика
    environment:
      REGISTRY_HTTP_HEADERS_Access-Control-Allow-Origin: '["https://hub.bobrobotirk.ru"]'
      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_AUTH: htpasswd
      REGISTRY_AUTH_HTPASSWD_REALM: Registry Realm
      REGISTRY_AUTH_HTPASSWD_PATH: /auth/htpasswd
      REGISTRY_HTTP_TLS_CERTIFICATE: /certs/cert.crt
      REGISTRY_HTTP_TLS_KEY: /certs/key.key
      REGISTRY_STORAGE_DELETE_ENABLED: "true"
    volumes:
      - ./data:/var/lib/registry # Для сохранения данных реестра
      - ./auth:/auth                     # Для файла htpasswd
      - ./certs:/certs                  # Для SSL сертификатов

  registry-ui:
    image: joxit/docker-registry-ui:main
    container_name: registry-ui
    restart: always
    ports:
      - "8090:80" # Интерфейс доступен по порту 8090
    environment:
      SINGLE_REGISTRY: "true"
      REGISTRY_TITLE: "BobRobotIRK Docker Registry"
      DELETE_IMAGES: "true"
      SHOW_CONTENT_DIGEST: "true"
      NGINX_PROXY_PASS_URL: "https://hub.bobrobotirk.ru" # URL реестра
      SHOW_CATALOG_NB_TAGS: "true"
      CATALOG_MIN_BRANCHES: "1"
      CATALOG_MAX_BRANCHES: "1"
      TAGLIST_PAGE_SIZE: "100"
      REGISTRY_SECURED: "true" # Реестр защищен авторизацией
      CATALOG_ELEMENTS_LIMIT: "1000"
    depends_on:
      - registry-server

И по адресу http://hub.bobrobotirk.ru:8090/ появился web интерфейс с авторизацией.

Авторизовался с другого сервера 

docker login https://hub.bobrobotirk.ru

Создал Dockerfile 

FROM alpine:latest
ARG NODE_ENV=production2
ENV NODE_ENV=${NODE_ENV}
RUN mkdir /var/www
RUN echo $NODE_ENV > /var/www/first.txt
CMD ["cat", "/var/www/first.txt"]

Собрал образ (пора переходить на buildx)

docker build -t testimage .

Точка обозначает расположение Dockerfile)

Он появился в списке образов 

docker images
REPOSITORY   TAG       IMAGE ID       CREATED         SIZE
testimage    latest    1f3755f48bea   3 minutes ago   7.83MB

Добавил тег образу 

docker tag testimage hub.bobrobotirk.ru/testimage

Загрузил образ на hub 

docker push hub.bobrobotirk.ru/testimage

Да, образ отобразился в списке. Теперь на третьем сервере авторизовался на hub.bobrobotirk.ru и попробовал запустить контейнер из образа

services:
  testapp:
    image: hub.bobrobotirk.ru/testimage

Образ скачался и контейнер запустился. Повторить это все просто, а в первый раз потратил на это один день.

P.s. Второй вариант, в случае наличия внешнего nginx reverse proxy + https termination 

services:
  http-registry-server:
    image: registry:2.8.2
    container_name: http-registry-server
    restart: no
    ports:
      - "${HUB_BACKEND_PORT}:5000" # Перенаправление HTTP-трафика
    environment:
      REGISTRY_AUTH: htpasswd
      REGISTRY_AUTH_HTPASSWD_REALM: Registry Realm
      REGISTRY_AUTH_HTPASSWD_PATH: /auth/htpasswd
      REGISTRY_STORAGE_DELETE_ENABLED: "true"
      REGISTRY_HTTP_ADDR: 0.0.0.0:5000
      REGISTRY_HTTP_NET: "tcp"  # Явно указываем протокол
      REGISTRY_HTTP_HEADERS_Access-Control-Allow-Origin: '["*"]'
      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"]'
    volumes:
      - ./data:/var/lib/registry # Для сохранения данных реестра
      - ./auth:/auth                     # Для файла htpasswd

  http-registry-ui:
    image: joxit/docker-registry-ui:main
    container_name: http-registry-ui
    restart: no
    ports:
      - "${HUB_BACKEND_WEB_PORT}:80"
    environment:
      NGINX_PROXY_PASS_URL: "http://${HUB_BACKEND_IP}:${HUB_BACKEND_PORT}"
      SINGLE_REGISTRY: "true"
      REGISTRY_TITLE: "${WEB_TITLE}"
      DELETE_IMAGES: "true"
      SHOW_CONTENT_DIGEST: "true"
      SHOW_CATALOG_NB_TAGS: "true"
      CATALOG_MIN_BRANCHES: "1"
      CATALOG_MAX_BRANCHES: "1"
      TAGLIST_PAGE_SIZE: "100"
      REGISTRY_SECURED: "true" # Реестр защищен авторизацией
      CATALOG_ELEMENTS_LIMIT: "1000"
    depends_on:
      - http-registry-server

 

Примеры

Загрузка образа с тегом latest в репозиторий amouat/revealjs из реестра Docker Hub. 

docker pull amouat/revealjs:latest 

Загрузка образа из неофициального реестра. 

docker pull gcr.io/google-containers/git-sync:v3.1.5

Определение имени репозитория identidock и тега 0.1 для образа, собранного из локального dockerfile. 

docker build -t "identidock:0.1" .

Устанавливается соответствие имени amouat/identidock с образом, который ссылается на имя пользователя amouat в репозитории Docker Hub.

docker tag "identidock:0.1" "amouat/identidock:0.1"

Ссылки

Настройка локального hub