I'm trying to deploy a generic registry instance (npm private registry + docker private registry) on an EC2 instance sitting behind an Elastic Load Balancer with nginx as a reverse proxy.
Doing so I want to be able to push npm packages and docker images respectively to registry.mydomain.org
and docker.mydomain.org
through https and with authentication.
To do so, I followed the following steps:
- I created an EC2 instance from the AWS console opening an HTTP port (e.g. 8080) from the security groups option
- I created a new Load Balancer with HTTPS connecting it to the HTTP port of the instance.
- I created a
docker-compose.yml
file with this configuration (I'm using verdaccio as npm private registry and registry:2 as docker registry:
version: '3' services: nginx: image: nginx:alpine container_name: nginx restart: always ports: - "80:80" volumes: - ./nginx:/etc/nginx/conf.d/ - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro links: - verdaccio:verdaccio - docker:docker verdaccio: image: verdaccio/verdaccio:latest container_name: verdaccio restart: always ports: - "4873:4873" volumes: - ./registry:/verdaccio/conf - ./database/verdaccio:/verdaccio/storage docker: image: registry:2 container_name: docker restart: always ports: - "5000:5000" volumes: - ./database/docker:/var/lib/registry
- The nginx configuration (nginx.conf) is:
events { worker_connections 1024; } http { upstream docker-registry { server docker:5000; } upstream npm-registry { server verdaccio:4873; } ## Set a variable to help us decide if we need to add the ## 'Docker-Distribution-Api-Version' header. ## The registry always sets this header. ## In the case of nginx performing auth, the header will be unset ## since nginx is auth-ing before proxying. map $upstream_http_docker_distribution_api_version $docker_distribution_api_version { '' 'registry/2.0'; } # Healtcheck server { listen 80; location /healthcheck { access_log off; return 200; } } server { # Server options listen 80; charset utf-8; client_max_body_size 0; server_name registry.mydomain.org; # Proxy settings location / { access_log /var/log/nginx/verdaccio.log; proxy_pass http://npm-registry; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-NginX-Proxy true; proxy_ssl_session_reuse off; proxy_redirect off; } } server { # Server options listen 80; charset utf-8; client_max_body_size 0; # required to avoid HTTP 411: see Issue #1486 (https://github.com/moby/moby/issues/1486) chunked_transfer_encoding on; server_name docker.mydomain.org; # Authentication auth_basic "Registry realm"; auth_basic_user_file /etc/nginx/conf.d/nginx.htpasswd; # Proxy settings location / { if ($http_user_agent ~ "^(docker\/1\.(3|4|5(?!\.[0-9]-dev))|Go ).*$" ) { return 404; } ## If $docker_distribution_api_version is empty, the header will not be added. ## See the map directive above where this variable is defined. add_header 'Docker-Distribution-Api-Version' $docker_distribution_api_version always; access_log /var/log/nginx/docker.log; proxy_pass http://docker-registry; proxy_read_timeout 900; } } }
- I created an
nginx.htpasswd
file with the encoded authentication infos.
Now, the registry is perfectly working. So if I visit https://registry.mydomain.org
I can see it and I can push npm packages to it through npm login --registry=https://registry.mydomain.org --scope=@myscope
Concerning the docker registry, however, while I can definitely log into it with docker login -u user -p password
but when I am trying to push an image to it the docker client enters in an infinite loop and continues trying uploading the images (with no success).
On the server side, the docker registry's logs does not show an useful info about what is going on since all the requests end in 202 HTTP statuses.
Any hint about how to solve it?