Run your own index and registry

In this section, we will perform the following steps to run our own index and registry, and finally, push the image:

  1. Deployment of the index components and the registry from GitHub.
  2. Configuration of nginx with the Docker Registry.
  3. Set up SSL on the web server for secure communication.

Step 1 – Deployment of the index components and the registry from GitHub

The index components include apache-utils and ngnix for password authentication and the SSL feature for HTTPS support. The user must note that the current version of the Docker registry supports only HTTP to connect to the registry. So, it is mandatory for the user to deploy and use Secure Sockets Layer (SSL) to secure the data. SSL creates an encrypted connection between a web server and the client's web browser that allows private data to be transmitted without the issues of eavesdropping, data tampering, or message forgery. This is a proven way of securing the data using SSL certificates that is widely accepted.

The Docker registry is a Python application, and we can install Python on the local Ubuntu machine from https://github.com/docker/docker-registry, using the following command:

$ sudo apt-get -y install build-essential python-dev 
       libevent-dev python-pip liblzma-dev swig libssl-dev

Now, install the Docker registry:

$ sudo pip install docker-registry

This will update the Docker registry in the Python package and update the configuration file in the following path:

$ cd /usr/local/lib/python2.7/dist-packages/config/

Copy the config_sample.yml file to config.yml:

$ sudo cp config_sample.yml config.yml

Docker, by default, saves its data in the /tmp directory, which can create problems because the /tmp folder is cleared on reboot on many Linux systems. Let's create a permanent folder to store our data:

$ sudo mkdir /var/docker-registry

Let's update our preceding config.yml file for this updated path for the following two locations. The updated code for the first location will look like this:

sqlalchemy_index_database:
    _env:SQLALCHEMY_INDEX_DATABASE:sqlite:////var/docker-registry/docker-registry.db

The following is the code for the second location:

local: &local
    storage: local
    storage_path: _env:STORAGE_PATH:/var/docker-registry/registry

The other default configuration of the config.yml file works fine.

Now, let's start the Docker registry using gunicorn. Gunicorn, also known as Green Unicorn, is a Python Web Server Gateway Interface (WSGI) HTTP server for Linux systems:

$ sudo gunicorn --access-logfile - --debug -k gevent -b 
       0.0.0.0:5000 -w 1 docker_registry.wsgi:application
01/Dec/2014:04:59:23 +0000 WARNING: Cache storage disabled!
01/Dec/2014:04:59:23 +0000 WARNING: LRU cache disabled!
01/Dec/2014:04:59:23 +0000 DEBUG: Will return docker-registry.drivers.file.Storage

Now, the Docker registry is up and running as a process on the user's local machine.

We can stop this process using Ctrl + C.

We can start a Linux service as follows:

  1. Make a directory for the docker-registry tool:
    $ sudo mkdir -p /var/log/docker-registry
    
  2. Create and update the file for the Docker registry configuration:
    $ sudo vi /etc/init/docker-registry.conf
    
  3. Update the following content in the file:
    description "Docker Registry"
    start on runlevel [2345]
    stop on runlevel [016]
    respawn
    respawn limit 10 5
    script
    exec gunicorn --access-logfile /var/log/docker-registry/access.log --error-logfile /var/log/docker-registry/server.log -k gevent --max-requests 100 --graceful-timeout 3600 -t 3600 -b localhost:5000 -w 8 docker_registry.wsgi:application
    end script
  4. After saving the file, run the Docker registry service:
    $ sudo service docker-registry start
    docker-registry start/running, process 25760
    
  5. Now secure this registry using apache-utils, by enabling the password protected feature, as shown here:
    $ sudo apt-get -y install nginx apache2-utils
    
  6. The user creates a login ID and password to access the Docker registry:
    $ sudo htpasswd -c /etc/nginx/docker-registry.htpasswd vinod1
    
  7. Enter the new password when prompted. At this point, we have the login ID and password to access the Docker registry.

Step 2 – Configuration of nginx with the Docker registry

Next, we need to tell nginx to use that authentication file (created in step 6 and step 7 of the previous section) to forward requests to our Docker registry.

We need to create the nginx configuration file. To do this, we need to follow these steps:

  1. We create the ngnix configuration file by running the following command:
    $ sudo vi /etc/nginx/sites-available/docker-registry
    

    Update the file with the following content:

    upstream docker-registry {
     server localhost:5000;
    }
    server {
     listen 8080;
     server_name my.docker.registry.com;
     # ssl on;
     # ssl_certificate /etc/ssl/certs/docker-registry;
     # ssl_certificate_key /etc/ssl/private/docker-registry;
     proxy_set_header Host       $http_host;   # required for Docker client sake
     proxy_set_header X-Real-IP  $remote_addr; # pass on real client IP
     client_max_body_size 0; # disable any limits to avoid HTTP 413 for large image uploads
     # required to avoid HTTP 411: see Issue #1486 (https://github.com/dotcloud/docker/issues/1486)
     chunked_transfer_encoding on;
     location / {
         # let Nginx know about our auth file
         auth_basic              "Restricted";
         auth_basic_user_file    docker-registry.htpasswd;
         proxy_pass http://docker-registry;
     } location /_ping {
         auth_basic off;
         proxy_pass http://docker-registry;
     }   location /v1/_ping {
         auth_basic off;
         proxy_pass http://docker-registry;
     }
    }
  2. Make the soft link and restart the ngnix service:
    $ sudo ln -s /etc/nginx/sites-available/docker-registry  
            /etc/nginx/sites-enabled/docker-registry
    $ sudo service nginx restart
    
  3. Let's check whether everything works fine. Run the following command, and we should get this output:
    $ sudo curl localhost:5000
    ""docker-registry server""
    

Great! So now we have the Docker registry running. Now, we have to check whether nginx worked as we expected it to. To do this, run the following command:

$ curl localhost:8080

This time, we will get an unauthorized message:

<html>
<head><title>401 Authorization Required</title></head>
<body bgcolor="white">
<center><h1>401 Authorization Required</h1></center>
<hr><center>nginx/1.4.6 (Ubuntu)</center>
</body>
</html>

Let's log in using the password created earlier:

$ curl vinod1:vinod1@localhost:8080
""docker-registry server""ubuntu@ip-172-31-21-44:~$

This confirms that your Docker registry is password protected.

Step 3 – Set up SSL on the web server for secure communication

This is the final step to set up SSL on a local machine, which hosts the web server for the encryption of data. We create the following file:

$sudo vi /etc/nginx/sites-available/docker-registry

Update the file with the following content:

server {
 listen 8080;
 server_name mydomain.com;
 ssl on;
 ssl_certificate /etc/ssl/certs/docker-registry;
 ssl_certificate_key /etc/ssl/private/docker-registry;

Note that my Ubuntu machine is available on the Internet with the name mydomain.com and SSL is set up with the path for a certificate and key.

Let's sign the certificate as follows:

$ sudo mkdir ~/certs
$ sudo cd ~/certs

The root key is generated using openssl, using the following command:

$ sudo openssl genrsa -out devdockerCA.key 2048
Generating RSA private key, 2048 bit long modulus
..........+++
....................+++
e is 65537 (0x10001)

Now we have the root key, let's generate a root certificate (enter whatever you'd like to at the Command Prompt):

$ sudo openssl req -x509 -new -nodes -key devdockerCA.key -days  
         10000 -out devdockerCA.crt

Then, generate a key for our server:

$ sudo openssl genrsa -out dev-docker-registry.com.key 2048

Now, we have to make a certificate signing request. Once we run the signing command, ensure that Common Name is our server name. This is mandatory and any deviation will result in an error:

$ sudo openssl req -new -key dev-docker-registry.com.key -out 
   dev-docker-registry.com.csr

Here, Common Name looks like mydomain.com. This is an Ubuntu VM running on AWS.

The output of the preceding command is shown as follows:

Country Name (2 letter code) [AU]:
State or Province Name (full name) [Some-State]:
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:mydomain.com
Email Address []:
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

The challenge password input is kept blank, and the user is also free to populate this. Then, we need to sign the certificate request, by running the following command:

$ sudo openssl x509 -req -in dev-docker-registry.com.csr -CA  
   devdockerCA.crt -CAkey devdockerCA.key -CAcreateserial -out 
    dev-docker-registry.com.crt -days 10000

Now that we've generated all the files we need for our certificate to work, we need to copy these files to the correct places.

First, copy the certificate and key to the paths where nginx is expecting them to be:

$ sudo cp dev-docker-registry.com.crt /etc/ssl/certs/docker-registry
$ sudo chmod 777 /etc/ssl/certs/docker-registry
$ sudo cp dev-docker-registry.com.key /etc/ssl/private/docker-registry
$ sudo chmod 777 /etc/ssl/private/docker-registry

Note that we have created self-signed certificates, and they are signed by any known certificate authority, so we need to inform the registry that this is a legitimate certificate:

$ sudo mkdir /usr/local/share/ca-certificates/docker-dev-cert
$ sudo cp devdockerCA.crt /usr/local/share/ca-certificates/docker-dev-cert
$ sudo update-ca-certificates
Updating certificates in /etc/ssl/certs... 1 added, 0 removed; done.
Running hooks in /etc/ca-certificates/updated....done.
ubuntu@ip-172-31-21-44:~/certs$

Let's restart nginx to reload the configuration and SSL keys:

$ sudo service nginx restart

Now, we will test the SSL certificate to check whether it works fine. Since mydomain.com is not an Internet address, add the entry in /etc/hosts file:

172.31.24.44 mydomain.com

Now run the following command:

$ sudo curl https://vinod1:[email protected]:8080
""docker-registry server""ubuntu@ip-172-31-21-44:~$

So if all went well, you should see something like this:

"docker-registry server"
Step 3 – Set up SSL on the web server for secure communication
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset