= Docker Registry = '''Registry''' is a simple container image registry container. <> ---- == Usage == {{{ docker run --detach --name registry --restart always \ --mount type=bind,src=/host/path/to/data/dir,dst=/var/lib/registry \ --env REGISTRY_STORAGE_DELETE_ENABLED=true \ --env REGISTRY_HTTP_HOST=http://registry.example.com \ --publish 0.0.0.0:80:5000 \ docker.io/library/registry:2 }}} Test the registry by accessing (either in a browser or through `curl(1)`) `http://registry.example.com/v2`. Pull the list of available container images with: {{{ curl -X GET http://registry.example.com/v2/_catalog }}} Pull the list of available tags for an image with: {{{ curl -X GET http://registry.example.com/v2/$IMAGE/tags/list }}} === Encryption === Docker Registry is a built-in encryption facility, but putting the registry behind a reverse proxy is significantly more straightforward and flexible. With [[HAProxy|haproxy(8)]]: {{{ global ssl-default-bind-options ssl-min-ver TLSv1.2 maxconn 1024 defaults mode http default-server init-addr none resolvers docker_dns nameserver docker 127.0.0.11:53 backend registry_backend server registry1 registry:5000 check resolvers docker_dns frontend http_frontend bind :::8080 v4v6 bind :::8443 v4v6 ssl crt /var/letsencrypt/registry.example.com.pem alpn h2,http1.1 http-request redirect scheme https unless { ssl_fc } acl registry hdr(host) -i registry.example.com use_backend registry_backend if registry }}} Then try deploying like: {{{ docker run --detach --name registry --restart always \ --mount type=bind,src=/host/path/to/data/dir,dst=/var/lib/registry \ --env REGISTRY_STORAGE_DELETE_ENABLED=true \ --env REGISTRY_HTTP_HOST=https://registry.example.com \ --env REGISTRY_HTTP_SECRET=somesecretpassphrase \ docker.io/library/registry:2 docker run --detach --name haproxy --restart always \ --mount type=bind,src=/host/path/to/letsencrypt/dir,dst=/var/letsencrypt,readonly \ --mount type=bind,src=/host/path/to/haproxy/conf/dir,dst=/usr/local/etc/haproxy,readonly \ --publish 80:8080 --publish 443:8443 \ haproxy:latest docker network create my-bridge docker network connect my-bridge registry docker network connect my-bridge haproxy }}} === Authentication === Docker Registry supports authentication, but only over encrypted connections. See the above section first. To setup authentication, first generate an `htpasswd` file. {{{ docker run --entrypoint htpasswd httpd:2 -Bbn $USER $PASSWD > /host/path/to/auth/dir/htpasswd }}} Then destroy and re-deploy the registry, now with some additional options and an additional bind mount. {{{ docker run --detach --name registry --restart always \ --mount type=bind,src=/host/path/to/data/dir,dst=/var/lib/registry \ --mount type=bind,src=/host/path/to/auth/dir,dst=/auth,readonly \ --env REGISTRY_AUTH=htpasswd \ --env "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \ --env REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \ --env REGISTRY_STORAGE_DELETE_ENABLED=true \ --env REGISTRY_HTTP_HOST=https://registry.example.com \ docker.io/library/registry:2 }}} To perform the same test as above, try: {{{ curl -X GET -u $USER:$PASSWD https://registry.example.com/v2/_catalog curl -X GET -u $USER:$PASSWD https://registry.example.com/v2/$IMAGE/tags/list }}} === High Availability === Update the `haproxy(8)` configuration above like: {{{ backend registry_backend server registry1 registry1:5000 check resolvers docker_dns server registry2 registry2:5000 check resolvers docker_dns }}} Then run as many containers as needed. {{{ docker run --detach --name registry1 --restart always \ --mount type=bind,src=/host/path/to/data/dir,dst=/var/lib/registry \ --env REGISTRY_STORAGE_DELETE_ENABLED=true \ --env REGISTRY_HTTP_HOST=https://registry.example.com \ --env REGISTRY_HTTP_SECRET=somesecretpassphrase \ docker.io/library/registry:2 docker network connect my-bridge registry1 docker run --detach --name registry2 --restart always \ --mount type=bind,src=/host/path/to/data/dir,dst=/var/lib/registry \ --env REGISTRY_STORAGE_DELETE_ENABLED=true \ --env REGISTRY_HTTP_HOST=https://registry.example.com \ --env REGISTRY_HTTP_SECRET=somesecretpassphrase \ docker.io/library/registry:2 docker network connect my-bridge registry2 }}} The `REGISTRY_HTTP_SECRET` environment variable has to be set explicitly to share the encrypted registry between processes. ---- CategoryRicottone