Semir Teskeredzic
Posted on June 6, 2021
Dockerized applications and automated pipelines mean that you will eventually need a docker registry sooner or later.
What is a Docker Registry?
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.
Docker Hub
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
Create your own private registry
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.
Prerequisites
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
Installing & Configuring
Since we have to run registry from a docker image there are two ways we will go through here,
- Quick - running with
docker
command from the CLI - Using docker-compose - running with the
yml
file usingdocker-compose
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
Quick
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.
Using docker-compose
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 CTRL+X
then Y
and then ENTER
Run the docker-compose with:
$ docker-compose up
Now your docker registry is up and running.
Configure HTTP Authentication
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
:
$ 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
Secure your host server with SSL
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 certbot
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 firewall
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'
Nginx file Upload size
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.
Posted on June 6, 2021
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.