In series of our previously published guides on Docker, we discussed around using Docker. In those guides we used Docker’s public repository to pull, push Docker images. We discussed about limitations of Docker Community Edition too. You Can Have Your Own Docker Registry on Own Cloud Server Instance with limitations of Docker Community Edition. Here is How Setup Private Docker Registry on Ubuntu 16.04 LTS Cloud Server. Here is official guide around registry :
1 2 | https://docs.docker.com/registry/ https://github.com/docker/docker-registry |
On that webpage, you’ll notice they talked about “Docker Trusted Registry (DTR)”, that is not available on Docker Community Edition. We have full command line.
How Setup Private Docker Registry on Ubuntu 16.04 LTS Cloud Server
Obviously, you’ll need have Docker installed on that machine. You can follow our first guide on Docker in case you are not used with Docker. Next, we need a web server software installed on that machine. We can run that web server in two ways. First way is installing on main server, which is less commonly done. You can follow our old guides to install Apache2 on Ubuntu 16.04. If you want Nginx, then follow guide to install Nginx on Ubuntu 16.04 (install only Nginx).
Second way is running a Nginx container inside Docker and linking it.
---
Now the practical running command part. We need some directories to be present :
1 2 3 4 5 | mkdir /docker-registry mkdir /docker-registry/data mkdir /docker-registry/nginx chown root:root /docker-registry cd /docker-registry |
We need Docker-Compose, Apache utilities and curl :
1 2 | apt-get -y install python-pip apt-get install -y docker-compose apache2-utils curl |
we can pull the Docker Registry image :
1 | sudo docker pull registry:latest |
and run it :
1 | sudo docker pull registry:latest |
Go to /Docker-Registry/Data
:
1 2 | cd .. cd /Docker-Regisry/Data |
Open :
1 | nano docker-compose.yml |
Content should look like this :
1 2 3 4 5 6 7 8 | registry: image: registry:2 ports: - 127.0.0.1:5000:5000 environment: REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY: /Data volumes: - ./Data:/Data |
Change 127.0.0.1
with your machine’s IP address. Save and close the file.
1 2 3 | cd .. cd /Docker-Registry sudo docker-compose up |
Press CTRL-C to shut down your Docker registry container. Run :
1 2 | mkdir /Docker-Registry/nginx nano /Docker-Registry/docker-compose.yml |
Add the following content into the top of the file:
1 2 3 4 5 6 7 8 | nginx: image: "nginx:1.9" ports: - 5043:443 links: - registry:registry volumes: - ./nginx/:/etc/nginx/conf.d:ro |
Save and close the file. create a new Nginx configuration file.
1 | nano /Docker-Registry/nginx/registry.conf |
Add the following content:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | upstream docker-registry { server registry:5000; }server { listen 443; server_name yourdomain.com;# SSL # ssl on; # ssl_certificate /etc/nginx/conf.d/domain.crt; # ssl_certificate_key /etc/nginx/conf.d/domain.key;# 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; } } |
Save and close the file. Run :
1 2 3 | cd /Docker-Registry # pwd sudo docker-compose up |
Two containers should be running.
We need a username-password based authentication method for Nginx frontend :
1 2 | cd /Docker-Registry/nginx sudo htpasswd -c registry.password USERNAME |
Now open the registry file :
1 | nano /Docker-Registry/nginx/registry.conf |
You need these lines to be active :
1 2 3 | auth_basic "registry.localhost"; auth_basic_user_file /etc/nginx/conf.d/registry.password; add_header 'Docker-Distribution-Api-Version' 'registry/2.0' always; |
Save and close the file. Test :
1 2 3 | cd /Docker-Registry sudo docker-compose up curl http://localhost:5043/v2/ |
On /Docker-Registry/nginx/registry.conf
, you’ll notice these lines :
1 2 3 | ssl on; ssl_certificate /etc/nginx/conf.d/domain.crt; ssl_certificate_key /etc/nginx/conf.d/domain.key; |
Those are intended to active to have full SSL support. You know how to obtain Let’s Encrypt SSL certificate on Ubuntu 16.04 for domain.
Basic steps for self-signed certificate is like below :
1 2 3 4 5 6 7 | cd /Docker-Registry/nginx openssl genrsa -out CA.key 2048 openssl req -x509 -new -nodes -key CA.key -days 10000 -out CA.crt openssl genrsa -out domain.key 2048 openssl req -new -key domain.key -out CA.csr openssl x509 -req -in CA.csr -CA CA.crt -CAkey CA.key -CAcreateserial -out domain.crt -days 10000 sudo cp CA.crt /usr/local/share/ca-certificates/ sudo update-ca-certificates |
Obviously, adjust Nginx settings. You have to restart Docker :
1 | sudo service docker restart |
You can copy CA.crt file from registry server to client machine by running the command :
1 2 | sudo scp /Docker-Registry/nginx/CA.crt root@client-machine:/usr/local/share/ca-certificates/ sudo service docker restart |
From client computer, if you run :
1 | sudo docker login https://YOUR-DOMAIN:5043 |
You’ll get expected output. Rest are written on Github’s that official repository’s documentation.