Search code examples
basic-authenticationdocker-registry

Self-hosted docker-registry does not request authentication at root domain, i.e. registry.mydomain.com


Along with some node.js apps, I have a self-hosted docker registry served by ubuntu, nginx-proxy, and acme-companion. Basic auth for the registry is setup using htpasswd. If I try to navigate to the root domain, such as https://myregistry.com, authentication is not required. If attempting to open https://myregistry.com/v2 or https://myregistry.com/v2/_catalog authentication is requested. Is this expected? If not, how can I pinpoint the reason this happens?

Since authentication succeeds (and fails) when it should on the /v2 and /v2/_catalog paths, I assume the credentials and htpasswd file + location are valid.

# compose-registry.yml

version: '3.8'
services:
  registry.mydomain.com:
    image: registry:2.8
    platform: linux/amd64
    container_name: registry.mydomain.com
    restart: always
    expose:
    - 5000
    depends_on:
      - nginx-proxy
      - acme-companion
    environment:
      VIRTUAL_HOST: registry.mydomain.com
      LETSENCRYPT_HOST: registry.mydomain.com
      REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY: /data
      REGISTRY_AUTH: 'htpasswd'
      REGISTRY_AUTH_HTPASSWD_REALM: 'basic-realm'
      REGISTRY_AUTH_HTPASSWD_PATH: '/auth/registry.mydomain.com'
    volumes:
      - data:/data
      - /home/lala/docker-registry/auth:/auth
    networks:
      - registry
volumes:
  data:
networks:
  registry:

Solution

  • The OCI distribution-spec does not specify any behavior for the / endpoint, only /v2/ and below. So OCI registries are free to handle that endpoint any way they wish.

    The behavior of the distribution project is going to be related to how they have defined their router/mux in Go, but I didn't spend enough time digging through their code to find the specific location of the behavior difference. If you want your application to be portable to other registries, I'd avoid using an undefined endpoint and stick to /v2/.