Ускоряем разработку: Локальный Docker Registry Mirror для всей команды

Зачем это нужно всей команде?

На самом деле я использую локальное зеркало не только для виртуальной машины с GitLab Runner'ом, но и на всех других машинах в сети указываю это зеркало. Зачем каждый раз качать одни и те же образы, если можно иметь локальную копию?

Данная проблема хоть и не частая, но, возможно знакома каждому:

Pulling docker image python:3.12...
Elapsed time: 15 minutes 59 seconds

Казалось бы, что сложного, скачать образ при деплое? Но по каким-то странным причинам это занимает столько времени. Можно конечно искать виноватых, кто старается запретить интернет своей цензурой, но проще решить проблему радикально.

Решение: Локальный кэш для всей команды или домашней студии!

Преимущества для всей команды

🚀 В 10-100 раз быстрее загрузка образов
📉 На 90% меньше интернет-трафика
🌐 Не зависит от доступности Docker Hub
👥 Все разработчики работают быстрее
💾 Повторное использование одних и тех же образов

Что такое Docker Registry Mirror?

Это локальный кэш-прокси для Docker образов. Первый раз образ качается из интернеты, а все последующие разы — из локального кэша, доступного всем в сети.

Настраиваем зеркало за 5 минут

1. Создаем структуру проекта

mkdir docker-registry-mirror
cd docker-registry-mirror
mkdir images config

2. docker-compose.yml

version: '3.8'

services:
  registry-mirror:
    image: registry:2
    container_name: docker-registry-mirror
    restart: unless-stopped
    env_file:
      - .env
    ports:
      - "5000:5000"
    environment:
      - REGISTRY_PROXY_REMOTEURL=https://registry-1.docker.io
      - REGISTRY_STORAGE_FILESYSTEM_MAXTHREADS=100
      - REGISTRY_PROXY_USERNAME=${DOCKERHUB_USERNAME:-}
      - REGISTRY_PROXY_PASSWORD=${DOCKERHUB_PASSWORD:-}
    volumes:
      - ./images:/var/lib/registry
      - ./config/config.yml:/etc/docker/registry/config.yml
    networks:
      - registry-net

networks:
  registry-net:
    driver: bridge

volumes:
  registry-data:
    driver: local

3. config/config.yml

version: 0.1
log:
  fields:
    service: registry
storage:
  cache:
    blobdescriptor: inmemory
  filesystem:
    rootdirectory: /var/lib/registry
http:
  addr: :5000
  headers:
    X-Content-Type-Options: [nosniff]
health:
  storagedriver:
    enabled: true
    interval: 10s
    threshold: 3
proxy:
  remoteurl: https://registry-1.docker.io
  username: ${DOCKERHUB_USERNAME}
  password: ${DOCKERHUB_PASSWORD}

4. .env файл

# Получите токен на hub.docker.com → Account Settings → Security → Access Tokens
DOCKERHUB_USERNAME=your_docker_id
DOCKERHUB_PASSWORD=your_access_token

Где взять Docker Hub токен? 🔑

  • Зайдите на hub.docker.com
  • Account Settings → Security → Access Tokens
  • "New Access Token" с правами Read Only
  • Используйте как пароль в .env файле

Запускаем зеркало

docker compose up -d

Настраиваем GitLab Runner

/etc/docker/daemon.json на ВМ с runner:

{
  "registry-mirrors": ["http://ip-зеркала:5000"],
  "insecure-registries": ["ip-зеркала:5000"]
}

Перезагружаем Docker:

sudo systemctl daemon-reload
sudo systemctl restart docker

Настройка других машин в сети

Для Windows/macOS (Docker Desktop):

Зайдите в Settings → Docker Engine и добавьте:

{
  "registry-mirrors": ["http://ip-зеркала:5000"],
  "insecure-registries": ["ip-зеркала:5000"]
}

Для Linux-машин:

# /etc/docker/daemon.json
{
  "registry-mirrors": ["http://ip-зеркала:5000"],
  "insecure-registries": ["ip-зеркала:5000"]
}

Предзагрузка популярных образов

На самом деле предзагрузку делать не обязательно, так как при первом запросе контейнеры скачаются и лягут на зеркале.
Создайте скрипт precache.sh:

#!/bin/bash
IMAGES=(
  "python:3.12"
  "python:3.12-slim"
  "node:20"
  "alpine:latest"
  "ubuntu:20.04"
  "nginx:latest"
  "redis:alpine"
  "postgres:13"
)

for image in "${IMAGES[@]}"; do
  echo "Precaching $image..."
  docker pull $image
  echo "---"
done

Выдайте права на запуск и запустите:

chmod +x precache.sh
./precache.sh

Как это работает в команде?

[Разработчик 1] ←→ [Registry Mirror] ←→ [Internet]
[Разработчик 2] ←→ [Registry Mirror]
[GitLab Runner] ←→ [Registry Mirror]

Первый разработчик качает образ → образ сохраняется в зеркале → остальные берут из кэша, включая Gitlab Runner.

Проверяем работу зеркала

# Смотрим что в кэше
curl http://localhost:5000/v2/_catalog

# Тестируем скорость
time docker pull python:3.12

# Статистика использования
docker logs docker-registry-mirror | grep "response completed"

Результаты

До: 15+ минут на pull образа
После: 10-30 секунд!

time docker pull python:3.12
3.12: Pulling from library/python
Digest: sha256:9e5892d80651101df6f1fed0614fb8fcb43bb60ca48f1d6f9ef26e27db069d25
Status: Image is up to date for python:3.12
docker.io/library/python:3.12
docker pull python:3.12  0.02s user 0.02s system 2% cpu 1.570 total

Мониторинг и обслуживание

# Логи mirror
docker compose logs -f

# Размер кэша
du -sh images/

# Очистка старых образов (осторожно!)
docker exec docker-registry-mirror registry garbage-collect /etc/docker/registry/config.yml

Проблемы и решения

Ошибка: "http: server gave HTTP response to HTTPS client"

Скорее всего вы не указали адрес для не защищённого подключения.

{
  "insecure-registries": ["ip-зеркала:5000"]
}

Зеркале не отвечает

docker compose restart
curl http://localhost:5000/v2/_catalog

Выводы

Локальное зеркало — это:
✅ Ускорение сборок в 10-100 раз
✅ Снижение интернет-трафика
✅ Независимость от доступности Docker Hub
✅ Простота настройки и обслуживания
Время сборок больше не будет вас беспокоить! 🎉


Как можно отблагодарить:

  • Оформить удобную для вас подписку на Boosty.to
  • Разово поддержать через DonationAlerts
12550login-checkУскоряем разработку: Локальный Docker Registry Mirror для всей команды

Добавить комментарий