skip to Main Content

I have been over numerous tutorials and I cannot get htpasswd to work in my private Docker Registry.

Here is my folder structure:

├── auth
│   └── htpasswd
├── certs
│   ├── registry.my.domain.crt
│   ├── registry.my.domain.csr
│   └── registry.my.domain.key
├── data
└── docker-compose.yml

Maybe it’s not important, but I generated my files like this:

In auth folder:

htpasswd -Bc htpasswd username

In certs folder:

openssl req -new -newkey rsa:2048 -nodes -keyout registry.my.domain.key -out registry.my.domain.csr
openssl x509 -req -days 365 -in registry.my.domain.csr -signkey registry.my.domain.key -out registry.my.domain.crt

My docker-compose file:

version: '3.9'

services:
  registry:
    container_name: registry
    image: registry:2
    restart: always
    ports:
      - "5000:5000"
    environment:
      - "REGISTRY_HTTP_TLS_CERTIFICATE:/certs/registry.my.domain.crt"
      - "REGISTRY_HTTP_TLS_KEY:/certs/registry.my.domain.key"
      - "REGISTRY_AUTH:htpasswd"
      - "REGISTRY_AUTH_HTPASSWD_REALM:Registry"
      - "REGISTRY_AUTH_HTPASSWD_PATH:/auth/htpasswd"
      - "REGISTRY_STORAGE_DELETE_ENABLED=true"
    volumes:
      - "./data:/var/lib/registry"
      - "./certs:/certs"
      - "./auth:/auth"
    deploy:
      resources:
        limits:
          memory: 2048M

After I log in to registry.my.domain/v2/_catalog it shows all repositories that I uploaded, and it doesn’t ask me for authentification.
I can also push and pull to the registry from any machine.

How can I secure it so that it asks for password?

2

Answers


  1. I did the exact same scenario as you and it worked correctly. you can follow the below commands:

    1- creating certificate:

    openssl req 
     -newkey rsa:4096 -nodes -sha256 -keyout certs/domain.key 
     -addext "subjectAltName = DNS:registry.my.domain.com" 
     -x509 -days 365 -out certs/domain.crt
    

    2- Creating user and password for authentication

    docker run 
      --entrypoint htpasswd 
      httpd:2 -Bbn testuser testpassword > auth/htpasswd
    

    3- My docker compose file

    version: "3.9"
    services:
      registry:
      restart: always
      image: registry:2
      ports:
        - 5000:5000
      environment:
        REGISTRY_HTTP_TLS_CERTIFICATE: /certs/domain.crt
        REGISTRY_HTTP_TLS_KEY: /certs/domain.key
        REGISTRY_HTTP_ADDR: 0.0.0.0:5000
        REGISTRY_AUTH: htpasswd
        REGISTRY_AUTH_HTPASSWD_PATH: /auth/htpasswd
        REGISTRY_AUTH_HTPASSWD_REALM: Registry Realm
        VIRTUAL_PORT: 5000
        VIRTUAL_HOST: registry.my.domain.com
        LETSENCRYPT_HOST: registry.my.domain.com
      volumes:
        - /mnt/registry:/var/lib/registry
        - ./certs:/certs
        - ./auth:/auth
    

    4- run docker compose

    docker compose up -d
    

    5- Copy certificate (domain.crt) on destination client (node) and execute following commands:

    sudo cp certs/domain.crt  
      /etc/docker/certs.d/registry.my.domain.com:5000/ca.crt
    sudo cp certs/domain.crt 
      /usr/local/share/ca-certificates/registry.my.domain.com.crt
    sudo update-ca-certificates
    

    6- Now, you can login to your private registry

    docker login -u testuser -p testpassword registry.my.domain:5000
    

    7- Testing private registry

    docker pull busybox
    docker tag busybox registry.my.domain.com:5000/mybusybox
    docker push registry.my.domain.com:5000/mybusybox
    
    Login or Signup to reply.
  2. You are mixing the syntax on environment variables in the compose file. If you use an array, the separator is an = in a string. If you use a map, there’s a colon and space between the key and value. See the syntax of yaml files for more details of their syntax.

    This:

        environment:
          - "REGISTRY_HTTP_TLS_CERTIFICATE:/certs/registry.my.domain.crt"
          - "REGISTRY_HTTP_TLS_KEY:/certs/registry.my.domain.key"
          - "REGISTRY_AUTH:htpasswd"
          - "REGISTRY_AUTH_HTPASSWD_REALM:Registry"
          - "REGISTRY_AUTH_HTPASSWD_PATH:/auth/htpasswd"
          - "REGISTRY_STORAGE_DELETE_ENABLED=true"
    

    should be:

        environment:
          - "REGISTRY_HTTP_TLS_CERTIFICATE=/certs/registry.my.domain.crt"
          - "REGISTRY_HTTP_TLS_KEY=/certs/registry.my.domain.key"
          - "REGISTRY_AUTH=htpasswd"
          - "REGISTRY_AUTH_HTPASSWD_REALM=Registry"
          - "REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd"
          - "REGISTRY_STORAGE_DELETE_ENABLED=true"
    

    or

        environment:
          REGISTRY_HTTP_TLS_CERTIFICATE: /certs/registry.my.domain.crt
          REGISTRY_HTTP_TLS_KEY: /certs/registry.my.domain.key
          REGISTRY_AUTH: htpasswd
          REGISTRY_AUTH_HTPASSWD_REALM: Registry
          REGISTRY_AUTH_HTPASSWD_PATH: /auth/htpasswd
          REGISTRY_STORAGE_DELETE_ENABLED: "true"
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search