Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Redirecting to docker registry with nginx

All I would like to do is control the top endpoint (MY_ENDPOINT where users will login and pull images. The registry and containers are being hosted (DOCKER_SAAS), so all I need is a seemingly simple redirect. Concretely, where you would normally do:

docker login -u ... -p ... DOCKER_SAAS
docker pull DOCKER_SAAS/.../...

I would like to allow:

docker login -u ... -p ... MY_ENDPOINT
docker pull MY_ENDPOINT/.../...

And even more optimally I would prefer:

docker login MY_ENDPOINT
docker pull MY_ENDPOINT/.../...

where the difference in the last item is that the endpoint contains a hashed version of the username and password, which is set into an Authorization header (using Basic) - so the user doesn't even need to worry about username and password, just their URL. I've tried a proxy_pass as we are already doing for basic packaging (using HTTPS), but that fails with a 404 (in part because we do not handle /v2 - do I need to redirect that through, also?). This led me to https://docs.docker.com/registry/recipes/nginx/, but this seems to only be pertinent if you are hosting the registry. Is what I am trying to do even possible?

like image 619
Justin Pihony Avatar asked Nov 06 '22 02:11

Justin Pihony


1 Answers

It sounds like there is also an Nginx or similar reverse-proxy-server in front of the DOCKER_SAAS. Does the infrastructure look like this?

[MY_ENDPOINT: nginx]  <--> ([DOCKER_SAAS ENDPOINT: ?] <--> [DOCKER_REGISTRY])

My guess is that since the server [DOCKER_SAAS ENDPOINT: ?] is apparently configured with a fixed domain name, it expects exactly that domain name in the request header (e.g. Host: DOCKER_SAAS.TLD). So the problem is probably that when proxying from [MY_ENDPOINT: nginx] to [DOCKER_SAAS ENDPOINT: ?] the wrong Host header is sent along, i.e. by default the host header MY_ENDPOINT.TLD is sent along, but it should be DOCKER_SAAS.TLD instead. E.g.:

upstream docker-registry {
  server DOCKER_SAAS.TLD:8443;
}

server {
  ...
  server_name MY_ENDPOINT.TLD;

  location / {
    proxy_pass https://docker-registry/;
    proxy_set_header Host DOCKER_SAAS.TLD; # set the header explicitly
    ...
  }
}

or

server {
  ...
  server_name MY_ENDPOINT.TLD;

  location / {
    proxy_pass https://DOCKER_SAAS.TLD:8443/;
    proxy_set_header Host DOCKER_SAAS.TLD; # set the header explicitly
    ...
  }
}

Regarding this:

And even more optimally I would prefer: docker login MY_ENDPOINT

This could be set on the proxy server ([MY_ENDPOINT: nginx]), yes. (The Authorization: "Basic ..." can be dynamically filled with the respective token extracted from the MY_ENDPOINT, and so on). However, the docker CLI would still ask for a username and password anyway. Yes, the user can enter dummy values (to make the CLI happy), or this would also work though:

docker login -u lalala -p 123 MY_ENDPOINT

But this would be inconsistent, and would rather confuse the users, imho. So better let it be...

like image 107
Kenan Güler Avatar answered Nov 15 '22 05:11

Kenan Güler