Seft host docker registry on VPS - Part 1

While you're working with registries, you might hear the terms registry and repository as if they're interchangeable. Even though they're related, they're not quite the same thing. A registry is a centralized location that stores and manages container images, whereas a repository is a collection of related container images within a registry. Think of it as a folder where you organize your images based on projects. Each repository contains one or more container images.
The first, we need to know what, why we use docker registry.
What is a Docker Registry?
A Docker registry is a service that stores and distributes Docker images. It is an essential component in the Docker ecosystem, providing a centralized location to manage and share container images.
Is is a storage and content delivery system that holds named Docker images, available in different tagged versions. Users can push images to the registry and pull images from the registry.
Why Use a Docker Registry?
1.Centralized Image Management:
A Docker registry provides a centralized location to store and manage Docker images. This makes it easier to organize, version, and share images across different environments and teams.
2.Efficient Image Distribution:
Docker registries enable efficient distribution of Docker images. Instead of manually transferring images between systems, you can push images to the registry and pull them from any location with network access.
3.Version Control:
Docker registries support versioning of images through tags. This allows you to maintain multiple versions of an image, making it easier to roll back to previous versions if needed.
4.Collaboration
A Docker registry facilitates collaboration among development teams. Team members can push their images to the registry and share them with others, ensuring consistency and reproducibility across different environments.
5.Deployment Automation
Docker registries are often integrated into CI/CD pipelines. This allows for automated building, testing, and deployment of Docker images, streamlining the development and deployment process.
6.Security
Using a private Docker registry allows you to control access to your images. You can implement authentication and authorization mechanisms to ensure that only authorized users can push or pull images.
Benefits of Using a Docker Registry:
• Centralized Storage: Keeps Docker images in one place, making them easy to find and manage.
• Efficient Sharing: Simplifies sharing images between teams or environments without manual file transfers.
• Version Management: Tracks different image versions using tags for easy updates or rollbacks.
• Collaboration: Enables teams to work together seamlessly by accessing shared images in the registry.
• CI/CD Integration: Automates image building, testing, and deployment in development pipelines.
• Enhanced Security: Restricts image access with authentication and authorization controls.
Simple Example:
Imagine a software team developing a web app.
1.Without a Docker Registry:
Each developer has to manually share their Docker images via email or external drives, leading to confusion about which version is the latest and wasting time.
2.With a Docker Registry:
• Developer A builds a new app image and tags it webapp:v2.0.
• They push the image to the registry.
• Developer B pulls webapp:v2.0 from the registry and runs it without needing extra steps.
• Later, the CI/CD pipeline automatically deploys webapp:v2.0 to production, ensuring everyone uses the same version.
This streamlines collaboration, ensures consistency, and integrates smoothly with deployment workflows.
Hope that your guys have some info about docker registry so how to use docker registry?
Here are some popular Docker registries, both public and private, that you can use to store and manage your Docker image
Docker Hub
GitHub Container Registry
Google Container Registry (GCR)
Amazon Elastic Container Registry (ECR)
Azure Container Registry (ACR)
Each Docker registry has its own set of limits and considerations and special those have fee. The docker hub do have limit but we need to public the image but there are situations where you will not want your image to be publicly available. Images typically contain all the code necessary to run an application, so using a private registry is preferable when using proprietary software. This is reason I written this blogs.
In this tutorial, you will set up and secure your own private Docker Registry. You will use docker compose to define configurations to run your Docker containers and Nginx to forward server traffic from the internet to the running Docker container. Once we completed this tutorial, we will be able to push a custom Docker image to owner private registry and pull the image securely from a remote server.
What stuff do we need to have:
In the server, create folder to setup docker compose for docker registry
1mkdir ~/docker-registry
Create and open a file called docker-compose.yml by running:
1nano docker-compose.yml //OR sudo vim docker-compose.yml
Add config for ~/docker-registry/docker-compose.yml, which define a basic instance of a Docker Registry:
1version: "3"
2
3services:
4 registry:
5 container_name: asta-registry # Name of the service
6 image: registry:2 # Image of the service
7 ports:
8 - "5500:5000" # Port mapping => host:container
9 environment:
10 REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY: /var/lib/registry
11 volumes:
12 - registry-data:/var/lib/registry # Volume mapping => host:container
13
14volumes:
15 registry-data:
Run docker compose
1docker-compose up -d
Output:
1~/docker-registry# docker compose up
2
3WARN[0000] /root/docker-registry/docker-compose.yml: the attribute version is obsolete..
4[+] Running 6/6
5✔ registry Pulled 32.1s
6✔ dc0decf4841d Pull complete 12.1s
7✔ 6cb0aa443e23 Pull complete 12.4s
8✔ 813676e291ef Pull complete 12.7s
9✔ dc2fb7dcec61 Pull complete 17.5s
10✔ 916205650bfe Pull complete 17.5s
11[+] Running 3/3
12✔ Network docker-registry_default Created 0.1s
13✔ Volume "docker-registry_registry-data" C... 0.0s
14✔ Container docker-registry-registry-1 Cre... 0.2s
15....
Verify the Registry is Running:
You can verify that the registry is running by accessing it in your web browser or using
1curl http://<your-vps-ip>:5500/v2/
or on check directly on server
1curl 127.0.0.1:5500/v2/
Output logs:
1~/docker-registry# docker logs asta-registry --tail 100
2[02/Dec/2024:04:50:30 +0000] "GET /v2 HTTP/1.1" 301 39 "" "curl/7.81.0"
Setup basic authentication:
Install apache2-utils
1sudo apt-get update && sudo apt-get install apache2-utils
Create the .htpasswd file and add a user - admin
1sudo sh -c "echo -n 'admin:' >> /etc/nginx/basic-auth/.htpasswd"
Config password
1sudo sh -c "openssl passwd -apr1 >> /etc/nginx/basic-auth/.htpasswd"
You will be prompted to enter and confirm a password - confirm password for the user admin.
Check config account after run cli above:
1cat /etc/nginx/basic-auth/.htpasswd
Output
1# cat /etc/nginx/basic-auth/.htpasswd
2admin:$apr1$yakYFrZz$9o/Pr1OoQzMhzqG3OJWE51
Note: Setting up basic authentication for your Docker registry is important to secure access to your registry. Without authentication, anyone who knows the address of your registry can push or pull images, which can lead to unauthorized access and potential security risks
Configure Nginx:
Edit your Nginx configuration file (e.g., /etc/nginx/sites-available/default) to include the following configuration
1server {
2 listen 80;
3 server_name your-domain.com; # Change this to your domain - e.g. registry.astalife.co
4 return 301 https://$host$request_uri;
5}
6
7server {
8 listen 443 ssl;
9 server_name your-domain.com;
10
11 ssl_certificate /etc/nginx/certs/cert.crt; # Change this to your SSL certificate
12 ssl_certificate_key /etc/nginx/certs/cert.key; # Change this to your SSL certificate key
13
14 location / {
15 auth_basic "Private Docker Registry";
16 auth_basic_user_file /etc/nginx/basic-auth/.htpasswd;
17
18 proxy_pass http://localhost:5500; # change correct port config in docker compose
19 proxy_set_header Host $host;
20 proxy_set_header X-Real-IP $remote_addr;
21 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
22 proxy_set_header X-Forwarded-Proto $scheme;
23 }
24}
Restart Nginx to apply the changes:
1sudo systemctl restart nginx
Now you can verify the Registry is Running:
1curl https://your-domain/v2
Response should be returned {}
Public image
Now that your Docker Registry server is up and running, and accepting large file sizes, you can try pushing an image to it. Since you don’t have any images readily available, you’ll use the ubuntu image from Docker Hub, a public Docker Registry, to test.
From server create test image
1root@84737:~# docker commit $(docker ps -lq) test-image
Check the image
1root@84737:~# docker image ls
2REPOSITORY TAG IMAGE ID CREATED SIZE
3test-image latest 40e310570178 About a minute ago 25.4MB
The new image is now available locally, and you’ll push it to your new container registry. First, you have to log in:
1docker login https://your_domain
In my case, I use ~ docker login https://registry.astalife.co. Then enter user name and password that we configured above
1root@84737:~# docker login https://registry.astalife.co
2Username: admin
3Password:
4WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
5Configure a credential helper to remove this warning. See
6https://docs.docker.com/engine/reference/commandline/login/#credential-stores
7
8Login Succeeded
Once we’re logged in, tag the created image:
1docker tag test-image your_domain/test-image
2#(example in my case) docker tag test-image registry.astalife.co/test-image
Finally, push the newly tagged image to your registry:
1docker push your_domain/test-image
Output:
1root@84737:~# docker push registry.astalife.co/test-image
2Using default tag: latest
3The push refers to repository [registry.astalife.co/test-image]
4a29d2590f411: Pushed
57827cbf539f4: Pushed
6....
7latest: digest: sha256:f11fb5228b787b42fa6553a2ba....e9dee size: 1570
Open https://registry.astalife.co/v2/_catalog to check iamge pushed
Output:
1{"repositories":["test-image"]}
Pull image from private registry from client:
Now that we’ve pushed an image to your private registry, we can pull from it.
On the client, log in with the username and password you set up previously:
1docker login https://your_domain
Pulling the test-image by running:
1docker pull your_domain/test-image
2Using default tag: latest
3latest: Pulling from test-image
4dc0decf4841d: Pull complete
56cb0aa443e23: Pull complete
6....
7Status: Downloaded newer image for registry.astalife.co/test-image:latest
8registry.astalife.co/test-image:latest
Check docker image
1docker images
2REPOSITORY TAG IMAGE ID CREATED SIZE
3registry.astalife.co/test-image latest 40e310570178 28 minutes ago 25.4MB
Now you can use this image from the client to.
Conclusion
In this post we set up our own private Docker Registry, and published a Docker image to it. By Docker containers in your workflow, you can ensure that the image containing the code will result in the same behavior on any machine, whether in production or in development and avoid some limit such as Bandwidth, Storage.
Get more code setup: https://github.com/AstaDK/private-docker-registry/tree/feat/private-registry-ss1