In this article, we will learn how to set up a private docker repository on Ubuntu 20.04.
Why private Docker Registry?
For smooth CI/CD development using the Docker platform, consider using a self-hosted Docker registry. For faster delivery and a secure infrastructure, it is recommended that you set up your own Docker private registry to store your Docker images and distribute them across your organization.
prerequisite
- 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 a private Docker Registry?
Docker Registry is a server-side application that allows you to store Docker images locally to a centralized location. By setting up your own Docker Registry server, you can pull and push docker images without connecting to Docker Hub, saving bandwidth and preventing security threats.
Before starting, make sure you have installed Docker and Docker-Compose on the client server and the local image server. If you need to verify whether the required software is installed, you can execute the following command to check the software version.
$ docker version
$ docker-compose version
Also, you need to make sure the docker service is started and set to enabled on startup
$ sudo systemctl start docker
$ sudo systemctl enable docker
Install and configure Docker Registry
To configure a private Docker Registry, follow these steps
Create Registry Directory
Create a new directory where all required configuration files will be stored
Create a new project directory myregistry and two subdirectories nginx and auth using the following command
$ mkdir -p myregistry/{nginx, auth}
Create two subdirectories conf.d and ssl in the nginx directory
$ cd my-registry/
$ mkdir -p nginx/{conf.d/, ssl}
Create Docker-Compose script and service
Create a docker-compose.yml file in the myregistry directory
$ vi docker-compose.yml
Define the service in the docker-compose.yml file
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
Set up nginx port forwarding
Create virtual host configuration for nginx service, go to nginx/conf.d directory created in above steps
$ cd nginx/conf.d/
Create an nginx virtual host file
$ vi myregistry.conf
Add the following
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 the server_name parameter with your own domain name and save the file
Increase nginx file upload size
By default, nginx uploads files with an upper limit of 1mb. When the docker image exceeds this limit, you need to increase the upload size in the nginx configuration file. In this example, I'll create an additional nginx configuration file with an upload limit of 2GB.
Go to the nginx configuration directory
$ cd myregistry/nginx/conf.d
$ vi additional.conf
Add the following lines and save the file
client_max_body_size 2G;
Configure SSL certificates and authentication
After creating the nginx configuration file, now we need to set up the SSL certificate. You should have a valid SSL certificate file with a private key. Copy your certificate file and private key to the nginx/ssl directory and execute the following command:
$ 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. It is not recommended to use a self-signed SSL certificate in a production environment.
To generate a 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, fill in the details and proceed.
Set up basic authentication
Go to the auth directory
$ cd auth
Execute the following command to create a password file, the user name is: linuxtechi
$ htpasswd -Bc registry.password linuxtechi
If the system prompts htpasswd command not found, please execute the following command in the terminal and try again
$ sudo apt install apache2-utils -y
Enter a strong password and enter it again to confirm the password
Run Docker Registry
You have completed the installation and can now build the Registry using the docker-compose command
Go to the myregistry directory
$ cd myregistry
Run the following command to build the image
$ docker-compose up -d
Docker Registry has started, verify with the following command
$ docker ps -a
Pull image from Docker Hub to private Registry
To store an image from Docker hub to a private registry, use the Docker pull command to pull the Docker image from Docker hub. In this example, I will pull the centos docker image.
$ docker pull centos
After successfully pulling the image from docker hub, mark it as a private registry
Markup syntax:
$ docker image tag [image name] registry.linuxtechi.com/[new-image-name]
Examples are as follows:
$ docker images tag centos registry.linuxtechi.com/linuxtechi-centos
Verify that the docker image is available locally
$ docker images
Push image to private registry
Now you need to push your local image to the private registry, first log in to the private registry with the following command
$ docker login https://registry.linuxtechi.com/v2/
Replace https://registry.linuxtechi.com with your own registry url
You will be prompted to enter your username and password and you will get a successful login message
Now you can push the image to your private registry with the following command
$ docker push registry.linuxtechi.com/linuxtechi-centos
After the push is complete, visit the url in the browser
https://registry.linuxtechi.com/v2/_catalog
Pull mirrors from private registry
You have pushed the local docker image to the private docker registry, in the same way, you can pull the docker image from the docker private registry to the local server.
Log in to your private registry server by running the following command
$ docker login https://registry.linuxtechi.com
Run the following command to pull the image
$ docker pull registry.linuxtechi.com/linuxtechi-centos