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

Quay.io

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:

Screenshot at Oct 24 17-29-25.png

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