Docker Registry
Introduce
The Docker registry is where images are stored during container startup. Most people are using existing images and if you don't know, it is hosted at the official Docker hub. However, there are some limitations when using docker hub as follows:
– Server located abroad (different from Vietnam)
– Charge for private images. You cannot publicize internal images, so you only have to choose private images. If you have a few projects, the cost is not high. But if you develop in a microservice direction, there will be a few dozen to a few hundred private images. If you rent in a package, it is completely uneconomical.
With the above two limitations, most companies deploy their own registry because the registry is also open source. You rent/buy a server, vps and start the image registry 2.0 and you're done, and there are many instructions online showing you how to build such a private registry. However, the registry you built is almost impractical and is only for testing. The content of this article is aimed at a production registry installation that means real running, not for testing, which requires a number of requirements such as a private, short domain name, https support, backup and ACL (Access Control) support. List).
Introducing some Docker Registry services
We will evaluate a number of registry service providers. Here I will talk about the main features and overview of the services based on the following criteria.
Workflow (build/deploy, collaboration, ease of use, and visibility)
Authentication and authorization
Availability and performance
Expense
Docker Hub
Working process:
Integration with Github and BitBucket
Familiar model like Github
Repository link, for automatic builds
Full documentation, easy to use
Authentication and authorization:
Organizations can be created
Lack of access control for each user
Lacks support for external authentication providers, for example LDAP, SAML and OAuth
Availability and performance:
Stable performance
price:
Cheap and independent use
Working process:
The interface is easy to use, intuitive and streamlined
Automatic build
There are announcements about events
Authentication and authorization:
Ability to create organizations and teams
Pass-through access control
Only supports authentication via OAuth
Availability and performance:
No support
price:
Relatively inexpensive and self-contained
Artifactory
Working process:
All in one
Easy for beginners to use
Authentication and authorization:
Comprehensive authentication capabilities
Availability and performance:
Remote repository cho HA
price:
High cost
Google Container Registry
Working process:
Not compatible with Docker client
Little support for integration with build and deployment
Authentication and authorization:
Control access with GCS ACL
Enhanced security through short-term token auth
Supports LDAP synchronization
Performance and availability:
Use available HA of Google cloud storage
price:
Low cost
Deploy Docker Registry
1. Domain name and SSL Certificate for Docker Registry
Domain
You need to choose a domain name for your registry. You can buy a domain name and create an A record to return to the IP of your VPS/Server. For example, I chose the domain name infra.framgia.vn as my registry.
SSL Certificate
Because the private registry supports https by default, you need to have an SSL Certificate for your domain. You can buy SSL from an SSL service provider such as GeoTrust, RapidSSL, Verisign... Here I use a free SSL service called letsencypt . How to create a cert is very simple, just download the script and run it.
wget https://dl.eff.org/certbot-auto
chmod a+x certbot-auto
/path/to/certbot-auto certonly --standalone -d example.com
After creating SSL, it will be saved in the following path
/etc/letsencrypt/archive/[domain_name]/
Here is the certificate I generated:

As shown above, you will use the fullchain1.pem and privkey1.pem bundle files to be able to configure https.
To facilitate the steps to run containers, rename the bundle crt file to “cert.pem” file and the .key file to “key.pem”. Proceed to the step of initializing the private registry.
2. Installation
To set up security for the Docker Registry it is best to use Docker Compose. This way we can easily run Docker Registry on a container and let Nginx handle and communicate with the outside world. Install docker-compose:
curl -L "https://github.com/docker/compose/releases/download/1.8.1/docker-compose-$(uname -s)-$(uname -m)" > /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
Because we will use Nginx for authentication, to store the list of usernames and passwords we want to access the registry. We will install the apache2-utils package which contains htpasswd utilities that can easily generate basic authenticate:
sudo apt-get -y install apache2-utils
First create a directory where the files will be stored:
mkdir ~/docker-registry
mkdir data
mkdir nginx
Create docker-compose.yml file as follows:
nginx:
image: "nginx:1.9"
ports:
- 443:443
links:
- registry:registry
volumes:
- ./nginx/:/etc/nginx/conf.d:ro
registry:
image: registry:2
ports:
- 127.0.0.1:5000:5000
environment:
REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY: /data
volumes:
- ./data:/data
Nginx container
image : image nginx 1.9
ports : Nginx container port 443 will map to port 443 of the host machine.
links : When Nginx container runs, it will link to the registry container with the hostname being the registry and regardless of the IP of the registry container. Actually, Docker has inserted /etc/hosts in the nginx container hostname of the container registry.
volumes : stores nginx config files on the host computer, the /etc/nginx/conf.d/ folder on the container will be mounted into the ~/docker-registry/nginx directory on the host machine.
Create a registry.conf file with the following content:
nano ~/docker-registry/nginx/registry.conf
upstream docker-registry {
server registry:5000;
}
server {
listen 443;
server_name infra.framgia.vn;
# SSL
ssl on;
ssl_certificate /etc/nginx/conf.d/cert.pem;
ssl_certificate_key /etc/nginx/conf.d/key.pem;
# disable any limits to avoid HTTP 413 for large image uploads
client_max_body_size 0;
# required to avoid HTTP 411: see Issue #1486 (https://github.com/docker/docker/issues/1486)
chunked_transfer_encoding on;
location /v2/ {
# 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;
}
# To add basic authentication to v2 use auth_basic setting plus add_header
auth_basic "registry.localhost";
auth_basic_user_file /etc/nginx/conf.d/registry.password;
add_header 'Docker-Distribution-Api-Version' 'registry/2.0' always;
proxy_pass http://docker-registry;
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;
}
}
Create a registry.password file containing registry login information
htpasswd -c registry.password USERNAME
Finally, Copy SSL certifcate, you will have a directory tree like this:

Registry container
image : registry version 2
port : Registry container port 5000 will map to port 5000 of the host machine and only listen on localhost (127.0.0.1)
environment : env on the Docker registry container is set to /data. Docker registry will check environment variables on startup and store data here.
3. Use private registry from client
Add certificate to client. You will copy the content of the cert.pem file and then add it to the client depending on the OS.
Mac OS X
Add
Use command:
sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain ~/new-root-certificate.crt
Windows
Add
Use command:
certutil -addstore -f "ROOT" new-root-certificate.crt
Linux (Free, Debian)
Add
Copy your CA to dir /usr/local/share/ca-certificates/
Use command:
sudo cp foo.crt /usr/local/share/ca-certificates/foo.crt
Update the CA store:
sudo update-ca-certificates
Linux (CentOs 6)
Add
Install the ca-certificates package:
yum install ca-certificates
Enable the dynamic CA configuration feature:
update-ca-trust force-enable
Add it as a new file to /etc/pki/ca-trust/source/anchors/:
cp foo.crt /etc/pki/ca-trust/source/anchors/
Use command:
update-ca-trust extract
Restart Kerio Connect to reload the certificates in the 32-bit version.
Linux (CentOs 5)
Add
Append your trusted certificate to file /etc/pki/tls/certs/ca-bundle.crt
cat foo.crt >> /etc/pki/tls/certs/ca-bundle.crt
Test by pushing and pulling images
Publish image tới docker registry




Pull image from docker registry

Last updated