# Архивация образов и Хранилище образов (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 (теория из разных источников, кое-что устаревшее)**
[Пример](https://www.dmosk.ru/miniinstruktions.php?mini=docker-local-repo)
На серверной стороне:
```bash
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):
```bash
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
```
Перелинковать на клиенте образ на новый хаб и загрузить его
```bash
docker tag amouat/identidock:0.1 dockertest:5000/identidock:0.1
docker push dockertest:5000/identidock:0.1
```
Пример docker-compose.yml для запуска локального реестра
```yaml
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](http://bobrobotirk.ru/books/linux/page/sertifikat-ot-letsencrypt "Сертификат от 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
```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/](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
```yaml
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.
```bash
docker pull amouat/revealjs:latest
```
Загрузка образа из неофициального реестра.
```bash
docker pull gcr.io/google-containers/git-sync:v3.1.5
```
Определение имени репозитория identidock и тега 0.1 для образа, собранного из локального dockerfile.
```bash
docker build -t "identidock:0.1" .
```
Устанавливается соответствие имени amouat/identidock с образом, который ссылается на имя пользователя amouat в репозитории Docker Hub.
```bash
docker tag "identidock:0.1" "amouat/identidock:0.1"
```
**Ссылки**
[Настройка локального hub](https://www.dmosk.ru/miniinstruktions.php?mini=docker-local-repo)