Docker реестр для Python: локальное и облачное хранение образов

Раздел: Администрирование -> docker

Организация хранения Python образов в Docker registry

Docker registry - это система для хранения и распространения контейнерных образов. Для Python‑разработчиков использование собственного реестра позволяет контролировать версии базовых образов, ускорять развёртывание и обеспечивать безопасность поставки (например, образ python:3.10-slim). В этой статье рассматриваются различные способы работы с реестром, включая развёртывание локального сервера, использование публичных и облачных сервисов, а также дополнительные меры защиты.

Основной способ: запуск локального реестра на базе официального образа registry:2

Как создать и использовать собственный Docker registry для Python образов без обращения к внешним серверам?

Наиболее эффективное решение - запустить контейнер реестра на любой машине (локальной или серверной). Для примера используется порт 5000 и образ registry:2. После запуска реестра с ним можно взаимодействовать как с любым другим реестром Docker.

docker run -d -p 5000:5000 --name my-registry registry:2

Docker registry python (работа с docker registry для python образов)

Затем Python‑образ (например, официальный python:3.10-slim) помещается в локальный реестр с помощью тегирования и отправки:

docker pull python:3.10-slim
docker tag python:3.10-slim localhost:5000/my-python:3.10-slim
docker push localhost:5000/my-python:3.10-slim

После успешной отправки образ доступен для извлечения на этой же машине:

docker pull localhost:5000/my-python:3.10-slim

Типичная ошибка: при попытке отправить образ на удалённый сервер (не localhost) возникает сообщение http: server gave HTTP response to HTTPS client. Это связано с тем, что Docker по умолчанию требует HTTPS для всех реестров, кроме localhost. Решение - явно указать реестр как insecure (неподписанный) в конфигурации демона Docker.

Для этого необходимо отредактировать файл /etc/docker/daemon.json (или создать его) и добавить адрес реестра в список insecure-registries:

{
  "insecure-registries" : ["my.registry.example.com:5000"]
}

После изменения требуется перезапуск Docker: sudo systemctl restart docker

Вариант 1: использование Docker Hub в качестве реестра

Как опубликовать Python образ на Docker Hub (включая приватные репозитории)?

Docker Hub - крупнейший публичный реестр, предоставляющий бесплатные публичные репозитории и платные приватные. Для начала требуется регистрация на hub.docker.com, затем аутентификация из командной строки:

docker login

После этого образ тегируется именем пользователя и названием репозитория, а затем отправляется:

docker tag python:3.10-slim myusername/my-python:3.10-slim
docker push myusername/my-python:3.10-slim

Приватные репозитории создаются через веб-интерфейс Docker Hub (Settings -> Create Repository -> Private). Отправка и извлечение требуют аутентификации.

Проблема: ограничение бесплатной учётной записи (один приватный репозиторий). Для коммерческого использования часто выбирают платный тариф или облачные решения.

Вариант 2: облачные реестры (AWS ECR, GCR, Azure Container Registry)

Как настроить отправку Python образов в Amazon Elastic Container Registry (ECR)?

Облачные провайдеры предлагают управляемые реестры с интеграцией IAM. Для ECR необходимо создать репозиторий через AWS CLI или консоль, аутентифицироваться с помощью команды get-login-password и docker login:

aws ecr create-repository --repository-name my-python
aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin <account-id>.dkr.ecr.us-east-1.amazonaws.com
docker tag python:3.10-slim <account-id>.dkr.ecr.us-east-1.amazonaws.com/my-python:3.10-slim
docker push <account-id>.dkr.ecr.us-east-1.amazonaws.com/my-python:3.10-slim

Аналогичные шаги для GCR (gcloud auth configure-docker) и Azure CR (az acr login).

Ошибка: отсутствуют права доступа к облачному реестру. Необходимо настроить IAM‑роли или сервисные учётные записи.

Вариант 3: реестр с аутентификацией (htpasswd)

Как защитить приватный Docker registry для Python образов с помощью пароля?

Используется базовая аутентификация HTTP. Сначала создаётся файл htpasswd с помощью утилиты htpasswd из пакета apache2-utils (или runnable контейнера):

docker run --entrypoint htpasswd registry:2 -Bbn user password > auth/htpasswd

Затем реестр запускается с монтированием этого файла и переменными окружения REGISTRY_AUTH и REGISTRY_AUTH_HTPASSWD_REALM:

docker run -d -p 5000:5000 --name secure-registry \
  -v $(pwd)/auth:/auth \
  -e "REGISTRY_AUTH=htpasswd" \
  -e "REGISTRY_AUTH_HTPASSWD_REALM=RegistryRealm" \
  -e "REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd" \
  registry:2

Теперь для отправки образа потребуется docker login localhost:5000 (с указанием созданного пользователя и пароля).

Проблема: передача пароля в открытом виде. Рекомендуется использовать TLS (см. следующий вариант).

Вариант 4: реестр с TLS (самоподписанный сертификат)

Как настроить безопасное шифрование трафика для Docker registry с помощью самоподписанного сертификата?

Создание сертификата (CN = адрес реестра):

mkdir certs
openssl req -newkey rsa:4096 -nodes -sha256 -keyout certs/domain.key -x509 -days 365 -out certs/domain.crt -subj "/CN=my.registry.example.com"

Запуск реестра с монтированием сертификатов и указанием порта 443:

docker run -d -p 443:443 --name tls-registry \
  -v $(pwd)/certs:/certs \
  -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \
  -e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \
  registry:2

Клиент должен доверять самоподписанному сертификату. Для этого на клиентской машине сертификат добавляется в доверенные или указывается опция --insecure при docker login (не рекомендуется).

Ошибка: certificate signed by unknown authority. Решается копированием domain.crt в /etc/docker/certs.d/<адрес_реестра>:443/ca.crt на каждом клиенте.

Вариант 5: использование Harbor для управления реестром

Как организовать хранение Python образов с веб-интерфейсом, сканированием уязвимостей и разграничением доступа?

Harbor - расширенный реестр с поддержкой проектов, ролей, репликации и встроенной проверки безопасности. Развёртывается через docker-compose или Helm. Подробная инструкция выходит за рамки данной статьи, но общий принцип: после установки Harbor пользователь получает URL вида hub.mydomain.com, где может создавать проекты и работать с образами через стандартный docker push/pull после аутентификации.

Проблема: сложность начальной настройки и требования к инфраструктуре (база данных, хранилище).

Расширенные примеры работы с Docker registry для Python образов

Автоматизация тегирования и отправки Python образа с указанием версии

Часто требуется присваивать образом теги, соответствующие версиям приложения или базового Python. Ниже приведён скрипт на Bash, который собирает образ на основе Dockerfile, получает версию из файла VERSION и отправляет его в локальный реестр.

Пример
#!/bin/bash
# Файл: push_python.sh
REGISTRY="localhost:5000"
IMAGE_NAME="my-python-app"
VERSION=$(cat VERSION)  # например, 1.2.3

# Сборка образа
docker build -t ${REGISTRY}/${IMAGE_NAME}:${VERSION} .

# Добавление дополнительных тегов
docker tag ${REGISTRY}/${IMAGE_NAME}:${VERSION} ${REGISTRY}/${IMAGE_NAME}:latest

# Отправка
docker push ${REGISTRY}/${IMAGE_NAME}:${VERSION}
docker push ${REGISTRY}/${IMAGE_NAME}:latest

echo "Образ ${IMAGE_NAME}:${VERSION} успешно отправлен в ${REGISTRY}"

Результат выполнения (пример):

The push refers to repository [localhost:5000/my-python-app]
4a2b1c3d...: Pushed
...
1.2.3: digest: sha256:abc123... size: 1234
latest: digest: sha256:abc123... size: 1234
Образ my-python-app:1.2.3 успешно отправлен в localhost:5000

Использование Docker Compose для запуска реестра с аутентификацией и TLS

Следующий docker-compose.yml разворачивает реестр с базовой аутентификацией и самоподписанным сертификатом.

Пример
version: '3.8'

services:
  registry:
    image: registry:2
    ports:
      - "443:443"
    environment:
      REGISTRY_HTTP_TLS_CERTIFICATE: /certs/domain.crt
      REGISTRY_HTTP_TLS_KEY: /certs/domain.key
      REGISTRY_AUTH: htpasswd
      REGISTRY_AUTH_HTPASSWD_REALM: RegistryRealm
      REGISTRY_AUTH_HTPASSWD_PATH: /auth/htpasswd
    volumes:
      - ./certs:/certs
      - ./auth:/auth
      - registry-data:/var/lib/registry

volumes:
  registry-data:

Запуск: docker-compose up -d. Для генерации htpasswd используется команда:

Пример
docker run --rm --entrypoint htpasswd registry:2 -Bbn admin secret > auth/htpasswd

Создание репликации образов между реестрами (синхронизация)

Если требуется дублировать Python образы из одного реестра в другой (например, из Docker Hub в локальный), можно воспользоваться инструментом skopeo или buildah. Пример использования skopeo для копирования образа:

Пример
skopeo copy docker://python:3.10-slim docker://localhost:5000/python:3.10-slim --dest-tls-verify=false

Для реестра с аутентификацией добавляются параметры --src-creds и --dest-creds:

Пример
skopeo copy \
  docker://python:3.10-slim \
  docker://my.registry.example.com/python:3.10-slim \
  --src-creds=user:pass --dest-creds=admin:secret \
  --dest-tls-verify=false

Вывод skopeo (сокращённый):

Getting image source signatures
Copying blob 123abc... done
Copying config 456def... done
Writing manifest to image destination

Очистка старого контента в реестре (garbage collection)

При активном использовании реестра накапливаются ненужные слои. Для освобождения места выполняется сборка мусора. Реестр должен быть остановлен, затем запускается команда внутри контейнера:

Пример
docker stop my-registry
docker run --rm -v registry-data:/var/lib/registry registry:2 garbage-collect /var/lib/registry/config.yml --dry-run

Параметр --dry-run позволяет посмотреть, какие blobs будут удалены без фактического удаления. После проверки команда выполняется без --dry-run.

Результат (пример фрагмента):

INFO[0000] Deleting blob: sha256:123abc...
INFO[0000] Deleting blob: sha256:456def...
Blobs marked for deletion: 23

Работа с Docker registry для Python образов - comments

En
Docker registry python (python)