Using your own Docker registry gives you a private place to store your Docker images. Whether you’re in a corporate environment or just want to reduce your reliance on Docker Hub, here’s how to get started with a registry implementation.
Docker Registry is a server-side system that stores and indexes Docker images. You “push”
The most famous public registry is Docker Hub. Using your own registry gives you control over image storage and access methods. It can also facilitate integration with third-party tools.
Managed services are available to help you quickly create registry installations. This guide focuses on how to host a registry yourself on your own server. The only requirements are that Docker and docker compose are installed on the computer hosting the registry.
Running a registry
The Docker Registry server is distributed as its own Docker image. You can get it from Docker Hub. The server is visible on port 5000; you must bind a host port to it for clients to connect.
You also need to set a volume so that Docker Hub has a place to permanently store uploaded images. Make sure you have enough free space on your host. An actively used registry can grow quickly.
Start making one
docker-compose.yml file to describe your implementation. You can customize the ports and file system paths according to your preferences. This example makes the registry accessible on port 5000. Images are stored in the
data folder in your workbook.
version: "3" services: registry: image: registry:2 ports: - 5000:5000 environment: - REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY: /data restart: unless-stopped volumes: - ./data:/data
Save and run the file
docker-compose up -d to start your registry. docker-compose gets the registry image from Docker Hub. It will then start a new container with your configuration.
Access your registry
You should now be able to use your registry. Tag an image using a path leading to your registry. You can use
localhost if you are working on the registry server itself. You should then be able to push the image to the registry.
docker tag my-image localhost:5000/my-image docker push localhost:5000/my-image
The image is now available in the registry. If you have your
data folder, you can see the layers that make up the image. You could get it from another machine by using
localhost with the network address of the server running the registry.
Set up authentication
The registry is currently not secured. Anyone can pull and push images! Let’s fix that by setting up authentication. Once configured, you will need to
docker login before you can interact with the registry.
Docker Registry’s standard approach to authentication uses HTTP Basic Auth. You must have one
htpasswd file – best done with the command from
sudo apt install apache2-utils mkdir auth htpasswd -Bc auth/.htpasswd my-username
This will create an authentication file for the user
my-usernameYou will be asked to provide a password. The
htpasswd file then becomes
Then update your
docker-compose.yml to configure the authentication system. You must specify the type of authentication used and the path to it
htpasswd File. This should be mounted as a new volume.
version: "3" services: registry: image: registry:2 ports: - 5000:5000 environment: - REGISTRY_AUTH: htpasswd - REGISTRY_AUTH_HTPASSWD_REALM: Registry Realm - REGISTRY_AUTH_HTPASSWD_PATH: /auth/.htpasswd - REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY: /data restart: unless-stopped volumes: - ./auth:/auth - ./data:/data
docker-compose up -d --force-recreate to recreate the active registry container using the new configuration. You should find that the Docker CLI now refuses to let you communicate with the registry.
Run to restore access
docker login localhost:5000You must adjust the registry URI if you are not running Docker on the same computer. Docker will ask you to provide your username and password. Use the values you set while creating it
Once authentication is successful, you can start pushing and retrieving images again. Docker caches your credentials, so you don’t have to repeat the authentication again
Set up SSL
You must add an SSL certificate for all but the most basic connections
localhostYou can add an SSL certificate to the registry by mounting the certificate in a volume and setting additional environment variables. Usually, you will need to update the port configuration so that the registry listens on 443, the default HTTPS port.
version: "3" services: registry: image: registry:2 ports: - 443:5000 environment: - REGISTRY_AUTH: htpasswd - REGISTRY_AUTH_HTPASSWD_REALM: Registry Realm - REGISTRY_AUTH_HTPASSWD_PATH: /auth/.htpasswd - REGISTRY_HTTP_ADDR: 0.0.0.0:443 - REGISTRY_HTTP_TLS_CERTIFICATE=/certs/cert.crt - REGISTRY_HTTP_TLS_KEY=/certs/cert.key - REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY: /data restart: unless-stopped volumes: - ./auth:/auth - ./certs:/certs - ./data:/data
Add your certificate files to
certs and restart the registry. It should come with HTTPS support again, using the included certificate file.
SSL via LetsEncrypt
The Registry server has built-in support for Let’s Encrypt. It allows you to automatically generate and renew your SSL certificates. To use Let’s Encrypt, you must public your registry on port 443.
REGISTRY_HTTP_TLS_LETSENCRYPT_HOSTS environment variables to add TLS support to your registry. Let’s Encrypt uses the email address as the contact person for your SSL certificates.
version: "3" services: registry: image: registry:2 ports: - 443:5000 environment: - REGISTRY_AUTH: htpasswd - REGISTRY_AUTH_HTPASSWD_REALM: Registry Realm - REGISTRY_AUTH_HTPASSWD_PATH: /auth/.htpasswd - REGISTRY_HTTP_TLS_LETSENCRYPT_EMAIL: email@example.com - REGISTRY_HTTP_TLS_LETSENCRYPT_HOSTS: [my-registry.com] - REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY: /data restart: unless-stopped volumes: - ./auth:/auth - ./certs:/certs - ./data:/data
Recreate the container with
docker-compose up -d --force-recreate to apply the change. The registry uses Let’s Encrypt to obtain an SSL certificate for the specified domains. It may take a few minutes for the certificate to be available.
Other ways to implement
Deployment with docker compose, HTTP Basic Auth and Let’s Encrypt is the easiest way to run a private container registry. However, other options are available, especially if you want more advanced access control.
Using Basic Auth doesn’t scale much beyond a handful of users. Alternatively, the server supports a delegated authentication routine that relies on external token servers. This is designed for scenarios where tight integration with organizational access control systems is required.
The registry server itself does not implement token authentication. Projects like docker_auth try to add this missing piece and provide a full-fledged auth system that can be implemented alongside the main registry.
Alternative projects aim to make managing your registry easier, without resorting to practical terminal commands. Portus is a SUSE project that offers a web frontend as well as its own user authentication system.