Приватный Docker Registry с HTTPS и Nginx reverse proxy на Docker Compose
Приватный Docker Registry - вещь незаменимая, если вы не хотите тянуть образы из внешних репозиториев или хранить чувствительные артефакты где-попало. Но в реальной жизни одного registry:2 быстро становится мало: нужен HTTPS, удобный веб-интерфейс и нормальный вход снаружи без плясок с сертификатами.
В этой статье разберём, как собрать приватный Docker Registry с HTTPS, проксированием через Nginx и всем этим управлять с помощью Docker Compose.
- Установите Docker и Docker Compose на сервер.
- Создайте на сервере новую директорию и файл
docker-compose.ymlсо следующим содержимым:
version: '3'
services:
registry:
image: registry:2
restart: always
ports:
- 5000:5000
environment:
REGISTRY_HTTP_ADDR: 0.0.0.0:5000
REGISTRY_HTTP_TLS_CERTIFICATE: /certs/domain.crt
REGISTRY_HTTP_TLS_KEY: /certs/domain.key
volumes:
- ./data:/var/lib/registry
- ./certs:/certs
registry-ui:
image: joxit/docker-registry-ui:latest
restart: always
ports:
- 8080:80
environment:
REGISTRY_TITLE: My Registry
REGISTRY_URL: https://yourdomain.com:5000
REGISTRY_SSL: 'true'
depends_on:
- registry
volumes:
- ./certs:/etc/nginx/certs:ro
nginx:
image: nginx:latest
restart: always
ports:
- 443:443
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- ./certs:/etc/nginx/certs:ro
depends_on:
- registry
- registry-ui
portainer:
image: portainer/portainer-ce
ports:
- 9000:9000
restart: always
environment:
- TEAMS=1
volumes:
- /var/run/docker.sock:/var/run/docker.sock
Этот файл docker-compose.yml описывает четыре сервиса: registry, registry-ui, nginx и portainer.
registry запускает сам Docker Registry с включённым HTTPS, registry-ui предоставляет веб-интерфейс для управления Docker-образами, nginx работает как reverse proxy и обеспечивает HTTPS-шифрование для registry и его UI, а portainer добавляет веб-интерфейс для управления Docker-контейнерами.
Обратите внимание: в переменной окружения REGISTRY_URL нужно заменить yourdomain.com на ваш реальный домен.
3. Создайте новую директорию certs и сгенерируйте SSL-сертификат и ключ для вашего домена. Можно воспользоваться чем-то вроде openssl. Например:
mkdir certs openssl req -x509 -newkey rsa:4096 -keyout certs/domain.key -out certs/domain.crt -days 365 -subj "/CN=yourdomain.com"
Это создаст новый SSL-сертификат и ключ в директории certs.
4. В той же директории, где лежит docker-compose.yml, создайте файл nginx.conf со следующим содержимым:
worker_processes auto;
events {
worker_connections 1024;
}
http {
upstream registry {
server registry:5000;
}
server {
listen 443 ssl;
server_name yourdomain.com;
ssl_certificate /etc/nginx/certs/domain.crt;
ssl_certificate_key /etc/nginx/certs/domain.key;
location / {
proxy_pass http://registry-ui:80;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /v2/ {
proxy_pass http://registry;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# These headers are required for Docker to trust the registry
# certificate and enable client-side certificate validation
proxy_ssl_verify on;
proxy_ssl_trusted_certificate /etc/nginx/certs/domain.crt;
proxy_ssl_session_reuse off;
}
}
}
В этом примере nginx.conf настраивает Nginx reverse proxy, который слушает HTTPS-трафик на порту 443. Директива upstream задаёт бэкенд-сервер registry, указывающий на Docker Registry, запущенный на порту 5000.
Блок location / проксирует запросы в Docker Registry UI, который работает на порту 80. Блок location /v2/ проксирует запросы в бэкенд Docker Registry, описанный в upstream. В этом блоке также есть несколько дополнительных proxy_set_header, которые пробрасывают заголовки запроса - например IP клиента и исходный протокол (HTTP или HTTPS).
Директива proxy_ssl_verify on включает проверку клиентских сертификатов, а proxy_ssl_trusted_certificate задаёт SSL-сертификат, которому Nginx должен доверять при верификации клиентских сертификатов. Наконец, proxy_ssl_session_reuse off отключает переиспользование SSL-сессий - это нужно, чтобы избежать SSL-ошибок при клиентской проверке сертификатов.
Не забудьте заменить yourdomain.com на ваш домен, и скопировать SSL-сертификат и ключ в директорию /etc/nginx/certs внутри контейнера сервиса nginx.