Dockerized applications and automated pipelines mean that you will eventually need a docker registry sooner or later.
It is essentially a place where you store Docker images organized in repositories. You can push images to the remote Docker registry and pull images where you want them.
Nifty service that Docker.com runs is Docker hub or a Docker Registry that has many things automated so you don't have to bother with configuring it on your own server (which we will get to in a bit).
Free tier is also fairly generous at Docker hub because it provides you with unlimited public repositories and one private repository. More private repositories are available in paid tiers and you can find pricing info here: Docker Pricing
If you want to house your Docker images on your own server, then you have to create a private registry or how the Docker documentation states it, deploy a registry server.
Before deploying a private registry, you will need to have several prerequisites checked:
- Server running Ubuntu (preferably latest Ubuntu 20.04) that is properly configured. You can read about it in the post here: Configure New Ubuntu Server
- Docker & Docker-compose properly installed on the server that will host the Docker registry. You can read about it here: Install Docker & Docker-compose on Ubuntu server
- Properly installed Nginx. You can read about it here: Install Nginx on Ubuntu server
- Domain name that resolves to your host server (where you will host registries)
- SSL Secured Nginx on your host server
Since we have to run registry from a docker image there are two ways we will go through here,
- Quick - running with
dockercommand from the CLI
- Using docker-compose - running with the
Before going through each one, go on and create a few directories to keep the things organized:
$ mkdir docker-registry $ cd ~/docker-registry $ mkdir data
While in our
docker-registry folder, we can run docker registry with just one line of code:
$ docker run -d -p 5000:5000 --restart=always --name registry registry:2
This will run our registry from the image
registry in background mode with the usage of the port 5000.
This is a great first step just to see it working. However it is not secure enough or configured enough for production-based environments.
Go on and stop the running container by running this command:
$ docker container stop registry
Proceed with removing the container alltogether:
$ docker container rm -v registry
If we want to store data to our host server filesystem instead of relying on the data inside the docker volume, we could use this command:
docker run -d \ -p 5000:5000 \ --restart=always \ --name registry \ -v ~/docker-registry/data:/var/lib/registry \ registry:2
Note: when writing a docker command in multiple lines just use backslash
\ at the end of the line and press enter.
You can write entire configuration in one
yml file and run it with docker-compose, this way you see the configuration more clearly and you are able to make modifications and see previous configurations.
While in your
docker-registry directory, create and enter edit mode using nano:
$ nano docker-compose.yml
You can now enter following code to the file:
version: '3' services: registry: image: registry:2 restart: always ports: - "5000:5000" environment: REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY: /data volumes: - ./data:/data
You can already see that we are using same image, utilizing same port and using volume location
~/data in our filesystem.
You can exit and save using
Y and then
Run the docker-compose with:
$ docker-compose up
Now your docker registry is up and running.
We can put HTTP Authentication with the Nginx using username and password so the access to our server hosting registries is secured with those credentials.
First update local packages:
$ sudo apt update
Then install a package we will use:
$ sudo apt install apache2-utils -y
We will store our credentials in separate folder so go create one and enter it:
$ mkdir ~/docker-registry/auth $ cd ~/docker-registry/auth
We will now enter following command and you replace
username with the username you want it to be:
$ htpasswd -Bc registry.password username
You will be prompted for password so enter it as required. If we used a docker-compose file, we need to update it to include credentials. Open docker-compose file using
$ nano ~/docker-registry/docker-compose.yml
Now alter existing docker-compose using following template:
version: '3' services: registry: image: registry:2 restart: always ports: - "5000:5000" environment: REGISTRY_AUTH: htpasswd REGISTRY_AUTH_HTPASSWD_REALM: Registry REGISTRY_AUTH_HTPASSWD_PATH: /auth/registry.password REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY: /data volumes: - ./auth:/auth - ./data:/data
Run your docker-compose:
$ docker-compose up
If you want to use inline CLI
docker command use this:
docker run -d \ -p 5000:5000 \ --restart=always \ --name registry \ -e REGISTRY_AUTH=htpasswd \ -e REGISTRY_AUTH_HTPASSWD_REALM=Registry \ -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/registry.password \ -v ~/docker-registry/data:/var/lib/registry \ registry:2
In order for docker-registry to function properly you must have secured HTTPS connection and that requires that you install a certificate provided by Certificate Authority. There is a free SSL certificate provided by Let's Encrypt and you can do this with the help of
Find the guide here: Certbot Ubuntu installation
Remember that you need to have a domain pointing to your host server IP address before being able to activate Let's encrypt.
Check the firewall status with the following command:
$ sudo ufw status
And make sure to allow all Nginx that includes HTTPS:
$ sudo ufw allow 'Nginx Full'
File upload size is set quite low for nginx when you freshly install and configure it. You need to increase that amount so you can push larger images to your docker registry. Open Nginx configuration:
$ sudo nano /etc/nginx/nginx.conf
Now edit the line that says
client_max_body_size in the
http section and set the value to
8000m which sets the maximum size to 8GB. Save changes and exit configuration.
After making any changes in Nginx configuration be sure to restart the Nginx:
$ sudo systemctl restart nginx
Congratulations! You now have a private docker registry that is password protected and HTTPS secured. You can push your own images there and pull it wherever you need them. Use
docker commands to login to your docker-registry just as you would with
Docker Hub, and use push and pull commands in the same way.
Thank you for reading.