Joxit/docker-registry-ui

DELETE woes (again)

robertdahlem opened this issue · 2 comments

Hello,

I'm aware of #104 and the FAQ regarding DELETE.

In #207 I read:

Solution 1: Use the UI as proxy, you should not have CORS errors... (use NGINX_PROXY_PASS_URL)

So I thought I give it a try.

My registry and registry-ui are on the same host. I have the registry on port 443, the UI on port 8080 and httpd as reverse proxy on port 8443.

# registry-compose.yml:
registry:
  restart: always
  image: registry:2
  ports:
    - 443:5000
  environment:
    REGISTRY_AUTH: htpasswd
    REGISTRY_AUTH_HTPASSWD_PATH: /auth/htpasswd
    REGISTRY_AUTH_HTPASSWD_REALM: My Docker Registry
    REGISTRY_HTTP_HEADERS_Access-Control-Allow-Origin: '[https://docker-registry.my.domain:8443]'
    REGISTRY_HTTP_HEADERS_Access-Control-Allow-Credentials: '[true]'
    REGISTRY_HTTP_HEADERS_Access-Control-Allow-Methods: '[HEAD, GET, OPTIONS, DELETE]'
    REGISTRY_HTTP_HEADERS_Access-Control-Allow-Headers: '[Authorization, Accept]'
    REGISTRY_HTTP_HEADERS_Access-Control-Max-Age: '[1728000]'
    REGISTRY_HTTP_HEADERS_Access-Control-Expose-Headers: '[Docker-Content-Digest]'
    REGISTRY_HTTP_TLS_CERTIFICATE: /certs/docker-registry.my.domain.chain.cer
    REGISTRY_HTTP_TLS_KEY: /certs/docker-registry.my.domain.key
    REGISTRY_STORAGE_DELETE_ENABLED: "true"

  volumes:
    - /app/docker/registry/auth:/auth:Z
    - /app/docker/registry/certs:/certs:Z
    - /app/docker/registry/data:/var/lib/registry:Z
# registry-ui-compose.yml
registry-ui:
  image: joxit/docker-registry-ui
  ports:
    - 8080:80
  environment:
    - DELETE_IMAGES=true
    - NGINX_PROXY_PASS_URL=https://docker-registry.my.domain
    - REGISTRY_TITLE=docker-registry.my.domain
    - REGISTRY_URL=https://docker-registry.my.domain
    - SINGLE_REGISTRY=true
# httpd-registry-ui.conf
Listen 8443 https
<VirtualHost *:8443>
        ServerName docker-registry.my.domain

        SSLEngine on
        SSLCertificateFile      /etc/pki/tls/certs/docker-registry.my.domain.cer
        SSLCertificateKeyFile   /etc/pki/tls/private/docker-registry.my.domain.key
        SSLCertificateChainFile /etc/pki/ca-trust/source/anchors/my.domain.chain.crt

        <Location />
                require all granted
        </Location>

        ProxyPass        "/" "http://127.0.0.1:8080/"
        ProxyPassReverse "/" "http://127.0.0.1:8080/"
</VirtualHost>

The location part in etc/nginx/conf.d/default.conf within the running container is enabled, so NGINX_PROXY_PASS_URL seems to have done its thing:

    location /v2 {
        # Do not allow connections from docker 1.5 and earlier
        # docker pre-1.6.0 did not properly set the user agent on ping, catch "Go *" user agents
        if ($http_user_agent ~ "^(docker\/1\.(3|4|5(?!\.[0-9]-dev))|Go ).*$" ) {
            return 404;
        }
        proxy_set_header Host "$http_host";
        proxy_pass https://docker-registry.my.domain;
    }

Unforunatley I still see an 401 reponse code for OPTIONS in the registry log:

time="2021-10-13T10:54:07.914407291Z" level=warning msg="error authorizing context: basic authentication challenge for realm "My Docker Registry": invalid authorization credential" go.version=go1.11.2 http.request.host=docker-registry.my.domain http.request.id=73c27e30-a1e6-44a8-9bac-1f583af79d84 http.request.method=OPTIONS http.request.referer="https://docker-registry.my.domain:8443/" http.request.remoteaddr="172.16.39.68:51849" http.request.uri="/v2/alpine/manifests/sha256:69704ef328d05a9f806b6b8502915e6a0a4faa4d72018dc42343f511490daf8a" http.request.useragent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Safari/537.36" vars.name=alpine vars.reference="sha256:69704ef328d05a9f806b6b8502915e6a0a4faa4d72018dc42343f511490daf8a"
172.16.39.68 - - [13/Oct/2021:10:54:07 +0000] "OPTIONS /v2/alpine/manifests/sha256:69704ef328d05a9f806b6b8502915e6a0a4faa4d72018dc42343f511490daf8a HTTP/2.0" 401 87 "https://docker-registry.my.domain:8443/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Safari/537.36"

The IP address 172.16.39.68 tells me that the request came from my browser, not from nginx within registry-ui. I would have expected the latter.

Am I missing something?

Regards,
Robert

Joxit commented

Hello,

Thank you for using my project 😄

To avoid CORS, the registry and the UI must have the same host AND port.
That means your UI must be on default HTTPS port (443), you can configure your apache httpd server.
The second solution is to remove the REGISTRY_URL option, since you added NGINX_PROXY_PASS_URL, the UI will communicate with your registry through port 8443

I am not sure how two processes can listen() on the same port without specifying different IP addresses and without triggering EADDRINUSE.

But removing REGISTRY_URL did the trick, thank you!

Maybe it would be helpful to point to this issue from the FAQ.