{"id":9415,"date":"2019-02-10T04:16:43","date_gmt":"2019-02-10T04:16:43","guid":{"rendered":"http:\/\/www.appservgrid.com\/paw92\/?p=9415"},"modified":"2019-02-10T04:16:43","modified_gmt":"2019-02-10T04:16:43","slug":"how-to-setup-private-docker-registry-on-ubuntu-18-04-lts","status":"publish","type":"post","link":"https:\/\/www.appservgrid.com\/paw92\/index.php\/2019\/02\/10\/how-to-setup-private-docker-registry-on-ubuntu-18-04-lts\/","title":{"rendered":"How to Setup Private Docker Registry on Ubuntu 18.04 LTS"},"content":{"rendered":"<p>Docker Registry or &#8216;Registry&#8217; is an open source and highly scalable server-side application that can be used to store and distribute Docker images. It was a server-side application behind the Docker Hub. In most use cases, a Docker Registry is a great solution if you want to implement the CI\/CD system on your application development. The Private Docker Registry gives more performances for the development and production cycle by centralizing all your custom Docker images of application in one place.<\/p>\n<p>In this tutorial, we&#8217;re going to show you how to install and configure a Private Docker Registry on a\u00a0Ubuntu 18.04 server.\u00a0We will use an Nginx web server and\u00a0protect the Registry with a username and password (basic auth).<\/p>\n<p><strong>Prerequisites<\/strong><\/p>\n<ul>\n<li>Ubuntu 18.04 server<\/li>\n<li>Root privileges<\/li>\n<\/ul>\n<p><strong>What we will do?<\/strong><\/p>\n<ol>\n<li>Install Dependencies<\/li>\n<li>Install Docker and Docker-compose<\/li>\n<li>Setup Private Docker Registry<\/li>\n<li>Testing<\/li>\n<\/ol>\n<h2 id=\"step-install-package-dependencies\">Step 1 &#8211; Install Package Dependencies<\/h2>\n<p>First of all, we&#8217;re going to install some packages dependencies for deploying the Private Docker Registry.<\/p>\n<p>Install packages dependencies using the following command.<\/p>\n<pre class=\"command\"><code spellcheck=\"false\">sudo apt install -y gnupg2 pass apache2-utils httpie<\/code><\/pre>\n<p>The gnupg2 and pass packages will be used to store the password authentication to the docker registry. And the apache2-utils will be used to generate the basic authentication, and httpie will be used for testing.<\/p>\n<h2 id=\"step-install-docker-and-dockercompose\">Step 2 &#8211; Install Docker and Docker-compose<\/h2>\n<p>Now we&#8217;re going to install the docker and docker-compose from the official Ubuntu repository.<\/p>\n<p>Install Docker and Docker-compose by running the following command.<\/p>\n<pre class=\"command\"><code spellcheck=\"false\">sudo apt install -y docker.io docker-compose -y<\/code><\/pre>\n<p>Once the installation is finished, start the docker service and add it to the boot time.<\/p>\n<pre class=\"command\"><code spellcheck=\"false\">sudo systemctl start docker\r\nsudo systemctl enable docker<\/code><\/pre>\n<p>The Docker is up and running, and the Docker-compose has been installed. Check using the command below.<\/p>\n<pre class=\"command\"><code spellcheck=\"false\">docker version\r\ndocker-compose version<\/code><\/pre>\n<p>And you will be displayed version of Docker and Docker-compose installed on your system.<\/p>\n<p><a id=\"img-11\" class=\"fancybox\" href=\"https:\/\/www.howtoforge.com\/images\/how_to_setup_private_docker_registry_on_ubuntu_1804_lts\/big\/11.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.howtoforge.com\/images\/how_to_setup_private_docker_registry_on_ubuntu_1804_lts\/11.png\" alt=\"Install Docker\" width=\"500\" height=\"370\" \/><\/a><\/p>\n<h2 id=\"step-setup-private-docker-registry\">Step 3 &#8211; Setup Private Docker Registry<\/h2>\n<p>In this step, we&#8217;re going to configure the Docker Registry environment by creating some directories environment, and create some configuration including the docker-compose.yml, nginx virtual host and additional configuration etc.<\/p>\n<p><strong>&#8211; Create Project Directories<\/strong><\/p>\n<p>Create a new directory for the project called &#8216;registry&#8217; and create the &#8216;nginx&#8217; and &#8216;auth&#8217; directories inside.<\/p>\n<pre class=\"command\"><code spellcheck=\"false\">mkdir -p registry\/{nginx,auth}<\/code><\/pre>\n<p>After that, go to the directory &#8216;registry&#8217; and create new directories again inside &#8216;nginx&#8217;.<\/p>\n<pre class=\"command\"><code spellcheck=\"false\">cd registry\/\r\nmkdir -p nginx\/{conf.d\/,ssl}<\/code><\/pre>\n<p>And as a result, the project directories look like the following picture.<\/p>\n<pre class=\"command\"><code spellcheck=\"false\">tree<\/code><\/pre>\n<p><a id=\"img-21\" class=\"fancybox\" href=\"https:\/\/www.howtoforge.com\/images\/how_to_setup_private_docker_registry_on_ubuntu_1804_lts\/big\/21.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.howtoforge.com\/images\/how_to_setup_private_docker_registry_on_ubuntu_1804_lts\/21.png\" alt=\"Create directories for Docker Registry\" width=\"500\" height=\"278\" \/><\/a><\/p>\n<p><strong>&#8211; Create Docker-compose Script<\/strong><\/p>\n<p>Now we want to create a new docker-compose.yml script for deploying the Docker Registry.<\/p>\n<p>Go to the &#8216;registry&#8217; directory and create a new configuration file &#8216;docker-compose.yml&#8217;.<\/p>\n<pre class=\"command\"><code spellcheck=\"false\">cd registry\/\r\nvim docker-compose.yml<\/code><\/pre>\n<p>Firstly, define the compose version that you want to use and the service.<\/p>\n<pre><code spellcheck=\"false\">version: '3'\r\nservices:<\/code><\/pre>\n<p>After that, add the first service named &#8216;registry&#8217;. The Docker Registry service will be using the docker image that&#8217;s provided by docker team &#8216;registry:2. It will mount the docker volume &#8216;registrydata&#8217; and the local directory named &#8216;auth&#8217; that contains basic authentication file &#8216;registry.passwd&#8217;. And the last, it will run on the custom docker image named &#8216;mynet&#8217; and expose the port 5000 on both container and host.<\/p>\n<pre>#Registry\r\n  registry:\r\n    image: registry:2\r\n    restart: always\r\n    ports:\r\n    - \"5000:5000\"\r\n    environment:\r\n      REGISTRY_AUTH: htpasswd\r\n      REGISTRY_AUTH_HTPASSWD_REALM: Registry-Realm\r\n      REGISTRY_AUTH_HTPASSWD_PATH: \/auth\/registry.passwd\r\n      REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY: \/data\r\n    volumes:\r\n      - registrydata:\/data\r\n      - .\/auth:\/auth\r\n    networks:\r\n      - mynet<\/pre>\n<p>Next, the configuration of &#8216;nginx&#8217; service that will run HTTP and HTTPS ports and mount the local directory &#8216;conf.d&#8217; for virtual host configuration, and the &#8216;ssl&#8217; for ssl certificates.<\/p>\n<pre>#Nginx Service\r\n  nginx:\r\n    image: nginx:alpine\r\n    container_name: nginx\r\n    restart: unless-stopped\r\n    tty: true\r\n    ports:\r\n      - \"80:80\"\r\n      - \"443:443\"\r\n    volumes:\r\n      - .\/nginx\/conf.d\/:\/etc\/nginx\/conf.d\/\r\n      - .\/nginx\/ssl\/:\/etc\/nginx\/ssl\/\r\n    networks:\r\n      - mynet<\/pre>\n<p>And the last, define the custom network &#8216;mynet&#8217; with bridge driver and the &#8216;registrydata&#8217; with a local driver.<\/p>\n<pre>#Docker Networks\r\nnetworks:\r\n  mynet:\r\n    driver: bridge\r\n#Volumes\r\nvolumes:\r\n  registrydata:\r\n    driver: local<\/pre>\n<p>Save and close the configuration.<\/p>\n<p>Below is the complete configuration:<\/p>\n<pre>version: '3'\r\nservices:\r\n\r\n#Registry\r\n  registry:\r\n    image: registry:2\r\n    restart: always\r\n    ports:\r\n    - \"5000:5000\"\r\n    environment:\r\n      REGISTRY_AUTH: htpasswd\r\n      REGISTRY_AUTH_HTPASSWD_REALM: Registry-Realm\r\n      REGISTRY_AUTH_HTPASSWD_PATH: \/auth\/registry.passwd\r\n      REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY: \/data\r\n    volumes:\r\n      - registrydata:\/data\r\n      - .\/auth:\/auth\r\n    networks:\r\n      - mynet\r\n\r\n#Nginx Service\r\n  nginx:\r\n    image: nginx:alpine\r\n    container_name: nginx\r\n    restart: unless-stopped\r\n    tty: true\r\n    ports:\r\n      - \"80:80\"\r\n      - \"443:443\"\r\n    volumes:\r\n      - .\/nginx\/conf.d\/:\/etc\/nginx\/conf.d\/\r\n      - .\/nginx\/ssl\/:\/etc\/nginx\/ssl\/\r\n    networks:\r\n      - mynet\r\n\r\n#Docker Networks\r\nnetworks:\r\n  mynet:\r\n    driver: bridge\r\n#Volumes\r\nvolumes:\r\n  registrydata:\r\n    driver: local<\/pre>\n<p><strong>&#8211; Configure Nginx Virtual Host<\/strong><\/p>\n<p>After creating the docker-compose script, we will create the virtual host and additional configuration for the nginx service.<\/p>\n<p>Go to &#8216;nginx\/conf.d\/&#8217; directory and create a new virtual host file called &#8216;registry.conf&#8217;.<\/p>\n<pre class=\"command\"><code spellcheck=\"false\">cd nginx\/conf.d\/\r\nvim registry.conf<\/code><\/pre>\n<p>Paste the following configuration.<\/p>\n<pre>upstream docker-registry {\r\n    server registry:5000;\r\n}\r\n\r\nserver {\r\n    listen 80;\r\n    server_name registry.hakase-labs.io;\r\n    return 301 https:\/\/registry.hakase-labs.io$request_uri;\r\n}\r\n\r\nserver {\r\n    listen 443 ssl http2;\r\n    server_name registry.hakase-labs.io;\r\n\r\n    ssl_certificate \/etc\/nginx\/ssl\/fullchain.pem;\r\n    ssl_certificate_key \/etc\/nginx\/ssl\/privkey.pem;\r\n\r\n    # Log files for Debug\r\n    error_log  \/var\/log\/nginx\/error.log;\r\n    access_log \/var\/log\/nginx\/access.log;\r\n\r\n    location \/ {\r\n        # Do not allow connections from docker 1.5 and earlier\r\n        # docker pre-1.6.0 did not properly set the user agent on ping, catch \"Go *\" user agents\r\n        if ($http_user_agent ~ \"^(docker\\\/1\\.(3|4|5(?!\\.[0-9]-dev))|Go ).*$\" )  {\r\n            return 404;\r\n        }\r\n\r\n        proxy_pass                          http:\/\/docker-registry;\r\n        proxy_set_header  Host              $http_host;\r\n        proxy_set_header  X-Real-IP         $remote_addr;\r\n        proxy_set_header  X-Forwarded-For   $proxy_add_x_forwarded_for;\r\n        proxy_set_header  X-Forwarded-Proto $scheme;\r\n        proxy_read_timeout                  900;\r\n    }\r\n\r\n}<\/pre>\n<p>Save and close.<\/p>\n<p>Next, create an additional configuration to increase the max_body_size on nginx. This will allow you to upload docker images with max size 2GB.<\/p>\n<pre class=\"command\"><code spellcheck=\"false\">vim additional.conf<\/code><\/pre>\n<p>Paste configuration below.<\/p>\n<pre><code spellcheck=\"false\">client_max_body_size 2G;<\/code><\/pre>\n<p>Save and close.<\/p>\n<p><strong>&#8211; Configure SSL Certificate and Basic Authentication<\/strong><\/p>\n<p>Copy SSL certificate files of your domain to the &#8216;ssl&#8217; directory.<\/p>\n<pre class=\"command\"><code spellcheck=\"false\">cp \/path\/to\/ssl\/fullchain.pem ssl\/\r\ncp \/path\/to\/ssl\/privkey.pem ssl\/<\/code><\/pre>\n<p>Now go to the &#8216;auth&#8217; directory and generate the new password file &#8216;registry.passwd&#8217;.<\/p>\n<pre class=\"command\"><code spellcheck=\"false\">cd auth\/<\/code><\/pre>\n<p>Generate a new password for user hakase.<\/p>\n<pre class=\"command\"><code spellcheck=\"false\">htpasswd -Bc registry.passwd hakase\r\nTYPE THE STRONG PASSWORD<\/code><\/pre>\n<p><a id=\"img-31\" class=\"fancybox\" href=\"https:\/\/www.howtoforge.com\/images\/how_to_setup_private_docker_registry_on_ubuntu_1804_lts\/big\/31.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.howtoforge.com\/images\/how_to_setup_private_docker_registry_on_ubuntu_1804_lts\/31.png\" alt=\"Password protect the registry\" width=\"500\" height=\"340\" \/><\/a><\/p>\n<p>And the environment setup for deploying Private Docker Registry has been completed.<\/p>\n<p>Below is the screenshot of our environment files and directories.<\/p>\n<pre class=\"command\"><code spellcheck=\"false\">tree<\/code><\/pre>\n<p><a id=\"img-41\" class=\"fancybox\" href=\"https:\/\/www.howtoforge.com\/images\/how_to_setup_private_docker_registry_on_ubuntu_1804_lts\/big\/41.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.howtoforge.com\/images\/how_to_setup_private_docker_registry_on_ubuntu_1804_lts\/41.png\" alt=\"Directory list\" width=\"500\" height=\"327\" \/><\/a><\/p>\n<p><strong>&#8211; Run Docker Registry<\/strong><\/p>\n<p>Run the Docker Registry using the docker-compose command below.<\/p>\n<pre class=\"command\"><code spellcheck=\"false\">docker-compose up -d<\/code><\/pre>\n<p>And you will get the result as below.<\/p>\n<p><a id=\"img-51\" class=\"fancybox\" href=\"https:\/\/www.howtoforge.com\/images\/how_to_setup_private_docker_registry_on_ubuntu_1804_lts\/big\/51.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.howtoforge.com\/images\/how_to_setup_private_docker_registry_on_ubuntu_1804_lts\/51.png\" alt=\"Start docker Registry\" width=\"500\" height=\"381\" \/><\/a><\/p>\n<p>After that, make sure the registry and nginx service is up and running. Check using the following command.<\/p>\n<pre class=\"command\"><code spellcheck=\"false\">docker-compose ps\r\nnetstat -plntu<\/code><\/pre>\n<p>And you will be shown the &#8216;registry&#8217; service is running on port &#8216;5000&#8217;, and the &#8216;nginx&#8217; service will expose the HTTP and HTTPS ports as below.<\/p>\n<p><a id=\"img-61\" class=\"fancybox\" href=\"https:\/\/www.howtoforge.com\/images\/how_to_setup_private_docker_registry_on_ubuntu_1804_lts\/big\/61.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.howtoforge.com\/images\/how_to_setup_private_docker_registry_on_ubuntu_1804_lts\/61.png\" alt=\"Check Nginx service\" width=\"500\" height=\"221\" \/><\/a><\/p>\n<h2 id=\"step-testing\">Step 4 &#8211; Testing<\/h2>\n<p>Before we test our Private Docker Registry, we need to add the Root CA certificate to the docker itself and to the system.<\/p>\n<p>If you&#8217;re using the pem file certificate, export it to the .crt file using the OpenSSL command.<\/p>\n<pre class=\"command\"><code spellcheck=\"false\">openssl x509 -in rootCA.pem -inform PEM -out rootCA.crt<\/code><\/pre>\n<p>Now create a new directory for docker certificate and copy the Root CA certificate into it.<\/p>\n<pre class=\"command\"><code spellcheck=\"false\">mkdir -p \/etc\/docker\/certs.d\/registry.hakase-labs.io\/\r\ncp rootCA.crt \/etc\/docker\/certs.d\/registry.hakase-labs.io\/<\/code><\/pre>\n<p>And then create a new directory &#8216;\/usr\/share\/ca-certificate\/extra&#8217; and copy the Root CA certificate into it.<\/p>\n<pre class=\"command\"><code spellcheck=\"false\">mkdir -p \/usr\/share\/ca-certificates\/extra\/\r\ncp rootCA.crt \/usr\/share\/ca-certificates\/extra\/<\/code><\/pre>\n<p>After that, reconfigure the &#8216;ca-certificate&#8217; package and restart the Docker service.<\/p>\n<pre class=\"command\"><code spellcheck=\"false\">dpkg-reconfigure ca-certificates\r\nsystemctl restart docker<\/code><\/pre>\n<p><a id=\"img-71\" class=\"fancybox\" href=\"https:\/\/www.howtoforge.com\/images\/how_to_setup_private_docker_registry_on_ubuntu_1804_lts\/big\/71.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.howtoforge.com\/images\/how_to_setup_private_docker_registry_on_ubuntu_1804_lts\/71.png\" alt=\"Create SSL certificate\" width=\"500\" height=\"270\" \/><\/a><\/p>\n<p><strong>&#8211; Download Docker Image<\/strong><\/p>\n<p>Download new Docker image using the following command.<\/p>\n<pre class=\"command\"><code spellcheck=\"false\">docker pull ubuntu:16.04<\/code><\/pre>\n<p>When it&#8217;s complete, tag the image for the private registry with the command below.<\/p>\n<pre class=\"command\"><code spellcheck=\"false\">docker image tag ubuntu:16.04 registry.hakase-labs.io\/ubuntu16<\/code><\/pre>\n<p>Check again the list of Docker images on the system and you will get new images as below.<\/p>\n<pre class=\"command\"><code spellcheck=\"false\">docker images<\/code><\/pre>\n<p><a id=\"img-81\" class=\"fancybox\" href=\"https:\/\/www.howtoforge.com\/images\/how_to_setup_private_docker_registry_on_ubuntu_1804_lts\/big\/81.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.howtoforge.com\/images\/how_to_setup_private_docker_registry_on_ubuntu_1804_lts\/81.png\" alt=\"Download Docker Image\" width=\"500\" height=\"265\" \/><\/a><\/p>\n<p><strong>&#8211; Push Image to Private Local Registry<\/strong><\/p>\n<p>Log in to the Private Docker Registry using the following command.<\/p>\n<pre class=\"command\"><code spellcheck=\"false\">docker login https:\/\/registry.hakase-labs.io\/v2\/<\/code><\/pre>\n<p>Type the username and password based on the &#8216;registry.htpasswd&#8217; file.<\/p>\n<p>Now check the available of docker image on the Registry.<\/p>\n<pre class=\"command\"><code spellcheck=\"false\">http -a hakase https:\/\/registry.hakase-labs.io\/v2\/_catalog<\/code><\/pre>\n<p>And there is no docker image on the Registry.<\/p>\n<p><a id=\"img-91\" class=\"fancybox\" href=\"https:\/\/www.howtoforge.com\/images\/how_to_setup_private_docker_registry_on_ubuntu_1804_lts\/big\/91.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.howtoforge.com\/images\/how_to_setup_private_docker_registry_on_ubuntu_1804_lts\/91.png\" alt=\"Push Image to Private Local Registry\" width=\"500\" height=\"381\" \/><\/a><\/p>\n<p>Now push our custom image to the Private Docker Registry.<\/p>\n<pre class=\"command\"><code spellcheck=\"false\">docker push registry.hakase-labs.io\/ubuntu16<\/code><\/pre>\n<p>Check again and make sure you get the &#8216;ubuntu16&#8217; docker image on the Private Repository.<\/p>\n<pre class=\"command\"><code spellcheck=\"false\">http -a hakase https:\/\/registry.hakase-labs.io\/v2\/_catalog<\/code><\/pre>\n<p><a id=\"img-101\" class=\"fancybox\" href=\"https:\/\/www.howtoforge.com\/images\/how_to_setup_private_docker_registry_on_ubuntu_1804_lts\/big\/101.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.howtoforge.com\/images\/how_to_setup_private_docker_registry_on_ubuntu_1804_lts\/101.png\" alt=\"Registry Push\" width=\"500\" height=\"321\" \/><\/a><\/p>\n<p>And finally, the installation and configuration of Private Docker Registry with Nginx and Basic Authentication has been completed successfully.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Docker Registry or &#8216;Registry&#8217; is an open source and highly scalable server-side application that can be used to store and distribute Docker images. It was a server-side application behind the Docker Hub. In most use cases, a Docker Registry is a great solution if you want to implement the CI\/CD system on your application development. &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/www.appservgrid.com\/paw92\/index.php\/2019\/02\/10\/how-to-setup-private-docker-registry-on-ubuntu-18-04-lts\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;How to Setup Private Docker Registry on Ubuntu 18.04 LTS&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-9415","post","type-post","status-publish","format-standard","hentry","category-linux"],"_links":{"self":[{"href":"https:\/\/www.appservgrid.com\/paw92\/index.php\/wp-json\/wp\/v2\/posts\/9415","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.appservgrid.com\/paw92\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.appservgrid.com\/paw92\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.appservgrid.com\/paw92\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.appservgrid.com\/paw92\/index.php\/wp-json\/wp\/v2\/comments?post=9415"}],"version-history":[{"count":1,"href":"https:\/\/www.appservgrid.com\/paw92\/index.php\/wp-json\/wp\/v2\/posts\/9415\/revisions"}],"predecessor-version":[{"id":9416,"href":"https:\/\/www.appservgrid.com\/paw92\/index.php\/wp-json\/wp\/v2\/posts\/9415\/revisions\/9416"}],"wp:attachment":[{"href":"https:\/\/www.appservgrid.com\/paw92\/index.php\/wp-json\/wp\/v2\/media?parent=9415"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.appservgrid.com\/paw92\/index.php\/wp-json\/wp\/v2\/categories?post=9415"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.appservgrid.com\/paw92\/index.php\/wp-json\/wp\/v2\/tags?post=9415"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}