In this post, we are going to learn how to setup private docker registry on Ubuntu 20.04.
Why Private Docker Registry ?
For Smooth CI/CD development using the docker platform, consider using a self-hosted docker registry server. Docker registry is the repository where you can store your docker images and pull them to run applications on the server. For faster delivery as well as secure infrastructure, it is recommended to set up your own docker private registry to store your docker images and distribute among organizations.
Prerequisites
- User account with sudo privileges
- A server for Docker registry
- Nginx on the Docker Registry server
- A client server
- Docker and Docker-Compose on both servers.
What is Private Docker Registry?
Docker Registry is a Server-side application which allows you to store your docker images locally into one centralized location. By setting up your own docker registry server, you can pull and push docker images without having to connect to the Docker hub, saving your bandwidth and preventing you from security threats.
Also Read : How to Install Docker on Ubuntu 22.04 / 20.04 LTS
Before You start
Before starting, I ensure that you have installed Docker and Docker-Compose on both client server and local registry server. To verify you have installed required software, you can run the following commands to check the software version.
$ docker version
$ docker-compose version
Also, you need to ensure that docker service is started and is setup to enable at boot time:
$ sudo systemctl start docker $ sudo systemctl enable docker
Install and Configure Private Docker Registry
To configure Private Docker Registry, follow the steps:
Create Registry Directories
Configure your server that is going to host a private registry. Create a new directory that will store all the required configuration files.
Use the following command to create a new project directory ‘my-registry’ and two sub directories ‘nginx’ and ‘auth’. You can have your own assumption for the project name.
$ mkdir -p my-registry/{nginx, auth}
Now navigate to the project directory and create new directories inside nginx as:
$ cd my-registry/ $ mkdir -p nginx/{conf.d/, ssl}
Create Docker-Compose script and services
You need to create a new docker-compose.yml script that defines the docker-compose version and services required to set up a private registry.
Create a new file “docker-compose.yml” inside “my-registry” directory with vi editor.
$ vi docker-compose.yml
Define your service in the docker-compose file as:
services: #Registry registry: image: registry:2 restart: always ports: - "5000:5000" environment: REGISTRY_AUTH: htpasswd REGISTRY_AUTH_HTPASSWD_REALM: Registry-Realm REGISTRY_AUTH_HTPASSWD_PATH: /auth/registry.passwd REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY: /data volumes: - myregistrydata:/data - ./auth:/auth networks: - mynet #Nginx Service nginx: image: nginx:alpine container_name: nginx restart: unless-stopped tty: true ports: - "80:80" - "443:443" volumes: - ./nginx/conf.d/:/etc/nginx/conf.d/ - ./nginx/ssl/:/etc/nginx/ssl/ networks: - mynet #Docker Networks networks: mynet: driver: bridge #Volumes volumes: myregistrydata: driver: local
Save and close the file
Setup nginx Port forwarding
We need to create nginx virtual host configuration for nginx web service. Go to nginx/conf.d/ directory created in the above step.
$ cd nginx/conf.d/
Now create a nginx virtual host file with your text editor. In this example I am going to name it myregistry.conf. You can have your own assumption.
$ vi myregistry.conf
Add the following contents:
upstream docker-registry { server registry:5000; } server { listen 80; server_name registry.linuxtechi.com; return 301 https://registry.linuxtechi.com$request_uri; } server { listen 443 ssl http2; server_name registry.linuxtechi.com; ssl_certificate /etc/nginx/ssl/certificate.crt; ssl_certificate_key /etc/nginx/ssl/private.key; # Log files for Debug error_log /var/log/nginx/error.log; access_log /var/log/nginx/access.log; location / { if ($http_user_agent ~ "^(docker\/1\.(3|4|5(?!\.[0-9]-dev))|Go ).*$" ) { return 404; } proxy_pass http://docker-registry; proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_read_timeout 900; } }
Replace your domain name with server_name parameter and save the file.
Increase nginx file upload size
By default, nginx has a 1mb limit to upload files. As docker images exceed this limit, you need to increase the upload size in nginx configuration file. In this example, I am going to create an extra nginx configuration file with a 2GB upload limit .
Go to nginx configuration directory
$ cd myregistry/nginx/conf.d $ vi additional.conf
Add the following line and save the file
client_max_body_size 2G;
Configure SSL certificate and Authentication
After creating nginx configuration file, now we need to set up an ssl certificate . You should have a valid ssl certificate file with a private key. Copy your certificate file and private key to nginx/ssl directory as:
$ cd myregistry/nginx/ssl $ cp /your-ssl-certificate-path/certificate.crt . $ cp /your-private-key-path/private.key .
If you do not have a valid purchased ssl certificate, you can generate your own self signed ssl certificate. Remember that a self signed ssl certificate is not recommended for production environments. To generate self signed ssl certificate, run the following command:
$ sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout \ /etc/ssl/private/nginx-private.key -out /etc/ssl/certs/nginx-certificate.crt
You will be asked to submit some details like, Country code, domain name, email id. Fill up the details and continue.
Now setup Basic authentication as:
Go to auth directory
$ cd auth
Request a new password file named registry.password for your user. In this example I am going to use linuxtechi user.
$ htpasswd -Bc registry.password linuxtechi
If you get ‘htpasswd not found command‘, run the following command in your terminal and try again.
$ sudo apt install apache2-utils -y
Type a strong password and enter again to confirm your password. You have added a basic authentication user for docker registry.
Run Docker Registry
You have completed setup. You can build registry using docker-compose command.
Go to the directory, where we create docker-compose.yml file
$ cd myregistry
Now run the following command:
$ docker-compose up -d
Docker registry is now up, you can verify the running containers using following command:
$ docker ps -a
You will get following output:
Pull Image from Docker Hub to a Private registry
To store an image from Docker hub to private registry, use docker pull command to pull docker images from docker hub. In this example, I am going to pull docker image of centos.
$ docker pull centos
After successfully pulling images from docker hub, tag an image to label it for private registry.
In this example, I am going to tag centos images as : registry.linuxtechi.com/linuxtechi-centos
$ docker image tag [image name] registry.linuxtechi.com/[new-image-name]
Example:
$ docker images tag centos registry.linuxtechi.com/linuxtechi-centos
To check if docker image is locally available or not , run the following command.
$ docker images
Push docker image to private registry
You have pulled docker image from docker hub and created a tag for private registry. Now you need to push local docker image to private registry.
Firstly, Login to your private registry using following command:
$ docker login https://registry.linuxtechi.com/v2/
Use your own registry url in the place of ‘https://registry.linuxtechi.com’
You will be prompted for username and password; you will get login successful message as:
Now you can push your docker image to a private registry. To push image run the following command:
$ docker push registry.linuxtechi.com/linuxtechi-centos
Replace your image name after ‘docker push’
Once push is completed, you can go to browser and enter the url:
https://registry.linuxtechi.com/v2/_catalog
Replace registry.linuxtechi.com with your own url and provide basic authentication. You will find repositories list as :
Pulling docker image from Private Registry
You have pushed your local docker image to your private docker registry. In the same way you can pull docker images from your docker private registry to the local server.
Run the following command to login in your private registry server.
$ docker login https://registry.linuxtechi.com
Replace registry.linuxtechi.com with your own private registry url and provide basic authentication. Once the login is successful, run the following command to pull the docker image from private registry. In this example, I am going to pull previously pushed docker image in the local server. You can have your own assumption for docker image name.
$ docker pull registry.linuxtechi.com/linuxtechi-centos
You will have output similar as:
Conclusion:
In the article you have learned about how to host your own private docker registry. Also you got idea about how to pull images from docker hub to local server, tag the image and push into private registry. You have also learned how to pull docker images from private registry in the local server.
Also Read : How to Install KVM on Ubuntu 20.04 LTS Server (Focal Fossa)
Great guide but I found a small typo, the compose file has
REGISTRY_AUTH_HTPASSWD_PATH: /auth/registry.passwd
but then you create the htpasswd file as registry.password
needs to be
htpasswd -Bc registry.passwd linuxtechi
docker log:
msg=”error checking authorization: stat /auth/registry.passwd: no such file or directory”
ERROR: The Compose file ‘./docker-compose.yml’ is invalid because:
Unsupported config option for networks: ‘mynet’
Unsupported config option for volumes: ‘myregistrydata’
Unsupported config option for services: ‘registry’
Not working 🙁