Docker одна из горячих тем в разработке. Большинство новых проектов строится именно на Docker. Как минимум, он отлично зарекомендовал себя для распространения ПО, например, наша система поиска по документам Ambar устанавливается с помощью docker-compose.


В начале работы над Ambar мы использовали публичный docker-репозиторий, но с ростом проекта и появлением enterprise версии мы задумались над созданием собственного приватного репозитория. В данной статье мы поделимся своим опытом развертывания селф-хостед репозитория: пошагово опишем весь процесс, попытаемся обойти все подводные камни.


Локальный docker-репозиторий


Итак, простейший Docker-репозиторий можно поднять одной командой


docker run -d -p 5000:5000 --restart=always --name registry registry:2

Для проверки репозитория зальем в него образ ubuntu.


  1. Сначала скачаем образ с официального репозитория и добавим ему тег localhost:5000/ubuntu.
  2. Запушим образ в наш новый репозиторий: docker push localhost:5000/ubuntu.

Хорошо, теперь мы умеем работать с локальным docker-репозиторием. Чтобы каждый раз не вспоминать команду запуска репозитория давайте создадим docker-compose.yml файл:


registry:
  restart: always
  image: registry:2
  ports:
    - 5000:5000  
  volumes:
    - /path/data:/var/lib/registry /* раздел который будет использоваться как хранилище для вашего репозитория*/

Чтобы запустить репозиторий достаточно ввести команду docker-compose up -d в директории с docker-compose файлом. С локальным репозиторием разобрались, перейдем к настройке SSL.


Настройка SSL


Зачем нужен SSL? Docker-репозиторий который доступен из интернета должен работать только через защищенное https соединение. Есть возможность обойти это ограничение, использовать самоподписанные сертификаты, но как показывает практика это работает через раз и легче один раз настроить все правильно, благо для тех у кого нет SSL сертификата я расскажу как использовать Letsencrypt. Стоит упомянуть что SSL является обязательным условием для работы аутентификации в репозитории.


Если у вас есть SSL сертификат — указываем путь к нему в docker-compose файле, смотрите листинг ниже.


registry:
  restart: always
  image: registry:2
  ports:
    - 5000:5000
  environment:
    REGISTRY_HTTP_TLS_CERTIFICATE: /certs/domain.crt
    REGISTRY_HTTP_TLS_KEY: /certs/domain.key
  volumes:
    - /path/data:/var/lib/registry 
    - /path/certs:/certs /* папка где хранитcя сертификат */

Если же SSL сертификата нет — лучший выход использовать Letsencrypt. В последних версиях docker он работает из коробки без предварительного создания сертификатов, правда рабочего примера я нигде не нашел, поэтому приведу его здесь.


registry:
  restart: always
  image: registry:2
  ports:
    - 443:5000 /* важно поменять порт с на 443, иначе letsencrypt работать не будет */
  environment:
    REGISTRY_HTTP_TLS_LETSENCRYPT_CACHEFILE: /cache.letsencrypt /* файл в котором будет храниться кэш letsencrypt*/
    REGISTRY_HTTP_TLS_LETSENCRYPT_EMAIL: hello@rdseventeen.com /* email, который будет использоваться для создания учетной записи в letsencrypt */    
  volumes:
    - /path/data:/var/lib/registry    

Стоит обратить внимание на то что для корректной работы Letsencrypt необходимо поменять порт с 5000 на 443. Расположение кеша Letsencrypt может быть любым.
Для тестирования нашего репозитория выполним следующие команды:


docker pull ubuntu
docker tag ubuntu myregistrydomain.com:443/ubuntu
docker push myregistrydomain.com:443/ubuntu
docker pull myregistrydomain.com:443/ubuntu

Настраиваем аутентификацию


Защитим наш репозиторий паролем. Для этого необходимо создать файл с паролями и указать его docker-репозиторию. Следующая команда создаст пользователя testuser с паролем testpassword, поместит их в файл и сохранит его в path/auth/htpasswd.


  docker run --entrypoint htpasswd registry:2 -Bbn testuser testpassword > path/auth/htpasswd

В docker-compose укажем путь к файлу с паролями и использование basic аутентификации


registry:
  restart: always
  image: registry:2
  ports:
    - 443:5000
  environment:
    REGISTRY_HTTP_TLS_LETSENCRYPT_CACHEFILE: /cache.letsencrypt
    REGISTRY_HTTP_TLS_LETSENCRYPT_EMAIL: hello@rdseventeen.com
    REGISTRY_AUTH: htpasswd
    REGISTRY_AUTH_HTPASSWD_PATH: /auth/htpasswd
    REGISTRY_AUTH_HTPASSWD_REALM: Registry Realm
  volumes:
    - /path/data:/var/lib/registry
    - /path/auth:/auth

Для того чтобы изменения вступили в силу необходимо перезапустить docker-репозиторий. Используем команду docker-compose restart. Логинимся в созданный репозиторий с помощью команды docker login myregistrydomain.com:443. После этого наш репозиторий будет доступен для скачивания хранящихся в нём образов.


Итог


В статье мы рассмотрели создание приватного docker-репозитория. Для глубокого изучения темы рекомендую ознакомиться с официальным мануалом и списком настроек репозитория.


Спасибо за внимание!

Поделиться с друзьями
-->

Комментарии (14)


  1. Rzhepish
    31.01.2017 16:21
    +2

    А какой-то cleaner для старых версий образов использовали?


    1. sochix
      31.01.2017 19:30

      Раньше у нас был Jenkins и в нем был скрипт который выполнялся каждый день и удалял старые образы. Сейчас мы перешли на Buddy Works — он умеет удалять старые образы за нас


  1. grossws
    01.02.2017 03:58
    +2

    Я уж надеялся на что-нибудь интересное (например, настройка OAuth2 для авторизации действий с образами), а тут меньше чем в минималистичной официальной документации.


  1. Lelik13a
    01.02.2017 06:28
    +2

    Перевод документации, а надеялся на интересное.
    И по моему, удобнее будет перед репозиторием поставить nginx и SSL часть и авторизацию вынести на него.


  1. AccessGranted
    01.02.2017 07:55

    Поднимал тоже свой репозиторий для использования в проде но понял что нет необходимости. Для базовых образов хватает и официального а собранные образы вместе с кодом льются на боевые сервера как архивы дабы размеры (от 100 до 200Mb) позволяют это делать.


  1. SchmeL
    01.02.2017 12:32
    +2

    используем jfrog artifactory — там уже есть приватный репозиторий.


  1. xkrt
    01.02.2017 15:10
    +1

    Советую посмотреть на harbor — registry + web ui + роли/права


  1. summerwind
    04.02.2017 19:05

    Подскажите, какой командой вы удаляете старый образ из приватного репозитория, прежде чем залить новый?


    1. D1abloRUS
      06.02.2017 12:51

      А для чего его удалять? залейте по верх с тем же тегом к примеру. Если идет версирование и старый тэг не нужен, можете через api и curl запросы это дело наскрептить. https://docs.docker.com/registry/spec/api/


      1. summerwind
        06.02.2017 14:45

        А вы сами хоть пробовали удалять образы через это api?) Какие бы запросы на удаление я не посылал — удаляется только метаинформация, но физически занятое место не освобождается. Пробовал чистить сборщиком мусора после выполнения запросов — тоже 0 эффекта.

        P. S. Ну очевидно же, что не хочется хранить кучу образов старых версий) Если сборки идут каждый день + приложение не одно, а их несколько + образы весят под 2 Гб — посчитайте, насколько быстро забьется даже терабайтный хард.


        1. D1abloRUS
          06.02.2017 16:03

          https://github.com/andrey-pohilko/registry-cli


          1. summerwind
            06.02.2017 17:16

            Это же просто обертка над api. Что принципиально нового она дает?


            1. D1abloRUS
              06.02.2017 17:31

              https://github.com/andrey-pohilko/registry-cli/blob/master/registry.py, открываем исходиник, читаем, как сделать чтобы место на hdd очищалось, после удаления тегов. и вот это еще заодно, чтобы удаление работало — https://github.com/andrey-pohilko/registry-cli#enable-image-deletion-in-docker-registry


              1. summerwind
                06.02.2017 17:49

                Я, конечно, попробую еще раз, но я вроде писал выше, что я пробовал запускать сборщик мусора после выполнения запросов и место не очищалось (REGISTRY_STORAGE_DELETE_ENABLED, само собой, true).