How to set up a private docker registry on Debian 11
Docker Registry is a stateless, highly scalable server-side application that stores and lets you distribute Docker images.
Step 1. Installing and configuring the docker registry
Docker Registry is an application with multiple components, so you will use Docker Compose to manage it. To start an instance of the registry, you’ll set up a docker-compose.yml file to define it and the location on the disk where your registry will store its data.
You’ll store the configuration in a docker-registry directory on the host server. Create it by running:
mkdir ~/docker-registry
Navigate to it:
cd ~/docker-registry
Then, create a subdirectory called data, where your registry will store its images:
mkdir data
Create and open a file called docker-compose.yml by running:
nano docker-compose.yml
Add the following lines, which define a primary instance of a Docker Registry:
version: '3'
services:
registry:
image: registry:latest
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
restart: always
In our docker-compose.yml file, we see several lines of code. In the section services, we define our services. In this example, we have only one service named registry. For the registry service, we are using the latest image version. Under the ports, we map port 5000 on the host to port 5000 of the container, allowing us to send a request to 5000 on the server and have the request forwarded to the docker registry. The environment section defines where we will store the docker registry data. The docker registry data store the information on the host’s file system.
Hint: How to protect your private docker registry.
With this command, you can create HTTP Authentication for the sites it manages, which you can use to limit access to your docker registry.
htpasswd -Bc ~/docker-registry/auth/registry.password username
Save and close the file.
You can now start the configuration by running:
docker compose up -d
Step 2. Setting up nginx port forwarding
As part of the prerequisites, you enabled HTTPS at your domain. To expose your secured Docker Registry there, you must configure Nginx to forward traffic from your domain to the registry container.
You have already set up the /etc/nginx/sites-available/your_domain
file containing your server configuration. Open it for editing by running:
nano /etc/nginx/sites-available/your_domain
Find the existing location
block and change into this one:
...
location / {
# Do not allow connections from docker 1.5 and earlier
# docker pre-1.6.0 did not properly set the user agent on ping, catch "Go *" user agents
if ($http_user_agent ~ "^(docker\/1\.(3|4|5(?!\.[0-9]-dev))|Go ).*$" ) {
return 404;
}
proxy_pass http://localhost:5000;
proxy_set_header Host $http_host; # required for docker client's sake
proxy_set_header X-Real-IP $remote_addr; # pass on real client's IP
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 900;
}
...
Save and close the file when you’re done. Apply the changes by restarting Nginx:
systemctl restart nginx
If you receive an error message, double-check the configuration you’ve added.
To confirm that Nginx is properly forwarding traffic to your registry container on port 5000, run it:
docker compose up -d
Then, in a browser window, navigate to your domain and access the v2 endpoint like so:
https://your_domain/v2
The browser will load an empty JSON object:
{}
Step 3. Increasing file upload size for Nginx
Before you can push an image to the registry, you need to ensure that your registry can handle large file uploads. The default size limit of file uploads in Nginx is 1 MB, which is insufficient for Docker images. To raise it, you’ll modify the main Nginx config file located at /etc/nginx/nginx.conf
.
Open it for editing:
nano /etc/nginx/nginx.conf
Add the highlighted line to the http
section:
...
http {
client_max_body_size 16384m;
...
}
...
The client_max_body_size parameter is now set to 16384m, making the maximum upload size equal to 16GB.
Save and close the file.
Restart Nginx to apply the configuration changes:
systemctl restart nginx
In this step, you updated the file size allowed by Nginx. You can now upload large images to your Docker Registry without Nginx blocking the transfer or erroring out.