Docker Registry - самый простой и быстрый в развертке способ хранения образов Docker. Для запуска "вручную" достаточно выполнить две команды на хосте с установленным Docker:

mkdir -p /mnt/registry; chown 777 /mnt/registry
sudo docker run -p 5000:5000 --name registry -v /mnt/registry:/var/lib/registry -e REGISTRY_STORAGE_DELETE_ENABLED=true --rm registry:2

Ваши файлы обрезов будут храниться по пути /mnt/registry, а сам registry будет доступен без SSL на порту 5000. Можно запушить в него первый образ:

sudo docker pull debian:12
sudo docker tag debian:12 127.0.0.1:5000/test-image
sudo docker push 127.0.0.1:5000/test-image

Но Docker Resgistry без SSL работает только со своего же хоста (127.0.0.1). Если же попытаться с другого сервера запушить туда образ, Вы получите ошибку:

$ sudo docker pull debian:12
$ sudo docker tag debian:12 10.0.0.3:5000/test-image-12 #где 10.0.0.3 - ip адрес вашего registry
$ sudo docker push 10.0.0.3:5000/test-image-12
Using default tag: latest
The push refers to repository [10.0.0.3:5000/test-image-12]
Get "https://10.0.0.3:5000/v2/": http: server gave HTTP response to HTTPS client

Дело в том, что docker по умолчанию хочет использовать HTTPS с SSL. Вы можете на каждом сервере, который использует ваш registry внести его в список исключений в файле /etc/docker/daemon.json:

{
 "insecure-registries" : ["10.0.0.3:5000"]
}

И тогда, после перезапуска docker вы сможете использовать registry без https:

$ sudo systemctl restart docker
$ sudo docker push 10.0.0.3:5000/test-image-12
Using default tag: latest
The push refers to repository [10.0.0.3:5000/test-image-12]
aa904f36746c: Pushed
latest: digest: sha256:d1fbb74d3e14bce3a324a08c0e89ba99285c28a6886c295871d86f853e1821fc size: 529

Конечно вписывать registry в исключения на каждом из серверов, где вы используете docker не так удобно. Поэтому следует настроить SSL. Оптимальнее всего это сделать с помощью nginx.

Настройка nginx для docker registry

Для того, чтобы у Docker Registry работал HTTPS есть два способа - можно просунуть сертификат внутрь контейнера с registry, а можно снаружи поставить nginx. Nginx будет более полезен, так как удобно интегрируется с certbot, имеет свои логи в удобном формате, и предоставляет прочие плюсы полноценного Web-сервера. Конфигурация nginx для работы с Docker Registry простая, хотя и имеет несколько обязательных неочевидных опций. Ниже приведу пример полной конфигурации nginx для Docker Registry:

map $upstream_http_docker_distribution_api_version $docker_distribution_api_version {
    '' 'registry/2.0';
}

upstream docker-registry {
    server 127.0.0.1:5000;
}

server {
    listen 443 ssl;
    server_name registry.example.com;

    access_log /var/log/nginx/registry.example.com.access.log;
    error_log /var/log/nginx/registry.example.com.access.log;

    ssl_certificate /etc/letsencrypt/live/registry.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/registry.example.com/privkey.pem;

    client_max_body_size 0; #обязательно
    chunked_transfer_encoding on; #обязательно

    location /v2/ {
      if ($http_user_agent ~ "^(docker\/1\.(3|4|5(?!\.[0-9]-dev))|Go ).*$" ) {
        return 404;
      }

      add_header 'Docker-Distribution-Api-Version' $docker_distribution_api_version always;

      proxy_pass                          http://docker-registry;
      proxy_set_header  Host              $http_host;   # required for docker client's sake
      proxy_set_header  X-Real-IP         $remote_addr; # pass on real client's IP
      proxy_set_header  X-Forwarded-For   $proxy_add_x_forwarded_for;
      proxy_set_header  X-Forwarded-Proto $scheme;
      proxy_read_timeout                  900;
    }
}

Как видите, в конфигурации учтены и особенности работы registry, и его клиента docker. Так же в конфигурацию можно добавить .well-known для работы с letsencrypt. Registry с HTTPS на 443ем порту можно использовать без каких либо донастроек со стороны машин с Docker:

$ sudo docker pull debian:12
$ sudo docker tag debian:12 registry.example.com/test-image-12-1
$ sudo docker push registry.example.com/test-image-12-1
Using default tag: latest The push refers to repository [registry.example.com/test-image-12] aa904f36746c: Pushed 
latest: digest: sha256:d1fbb74d3e14bce3a324a08c0e89ba99285c28a6886c295871d86f853e1821fc size: 529

Правила хорошего тона

Docker Registry - сервис корпоративного использования, а значит запустить его "вручную" и так оставить - некорректно. Рекомендую запускать его как и все другие сервисы с помощью штатного средства systemd и его утилиты управления systemctl. Создаем файлик /lib/systemd/system/registry.service с содерижмым для запуска registry:

[Unit]
Description=Docker Registry
After=network.target docker.service

[Service]
ExecStart=/usr/bin/docker run -p 5000:5000 --name registry -v /mnt/registry:/var/lib/registry -e REGISTRY_STORAGE_DELETE_ENABLED=true --rm registry:2
Restart=always
RestartSec=90s

[Install]
WantedBy=multi-user.target

Запускаем его и включаем в автоматический запуск при старте системы:

sudo systemctl start registry
sudo systemctl enable registry

Теперь мы можем его мониторить, он у нас автоматически штатно завершиться при выключении/перезагрузке, автоматически запуститься при старте системы, а в случае падения сам перезапуститься через 90 секунд.