Docker реестр для Python: локальное и облачное хранение образов
Организация хранения 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:2Docker 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