Docker Hub (hub.docker.com) provides a great and Free service for pushing, and pulling of course, Docker containers. Many of the major software providers use Docker Hub for their primary container distribution, and you yourself can create an account and push your own images.
They do, however, only allow one free private repository. This may not be an issue if you are only looking for hosting your images public. And that you also have taken the precaution not to include any secrets in the container image, accidental or otherwise…
Luckily, it’s a walk in the park to deploy an Ubuntu server and roll your own!
First, deploy your VM where you see fit. I can personally vouch for Linode.
Second, Install Docker Engine and Docker-Compose. Follow the Official Guide For Docker Engine and install Docker-Compose with:
~$ sudo apt install -y docker-compose
Third, Create directory structure and paste the following Docker-Compose YAML:
~$ mkdir -p ~/docker-registry/{auth,data}
~$ cat <<EOF > ~/docker-registry/docker-compose.yaml
> version: '3'
services:
registry:
restart: always
image: registry:2
ports:
- "5000:5000"
environment:
REGISTRY_AUTH: htpasswd
REGISTRY_AUTH_HTPASSWD_REALM: Registry
REGISTRY_AUTH_HTPASSWD_PATH: /auth/registry.password
REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY: /data
volumes:
- ./auth:/auth
- ./data:/data
> EOF
Forth, Install htpasswd and create your first docker-registry user.
~$ sudo apt install apache2-utils -y
~$ htpasswd -Bc ~/docker-registry/auth/registry.password [USERNAME]
... <Password>
Fifth, Its recommended to use NGinx as a, with HTTPS, reverse proxy. Here’s the configuration i use.
~$ sudo apt install nginx -y
~$ sudo cat <<EOF > /etc/nginx/sites-available/dockerreg
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name dockerreg.tld;
error_log /var/log/nginx/dockerreg-tld-error.log;
access_log /var/log/nginx/dockerreg-tld-access.log;
ssl_certificate /etc/letsencrypt/live/dockerreg.tld/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/dockerreg.tld/privkey.pem; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
ssl_session_timeout 1d;
ssl_session_cache shared:MozSSL:10m; # about 40000 sessions
ssl_session_tickets off;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
location / {
if ($http_user_agent ~ "^(docker\/1\.(3|4|5(?!\.[0-9]-dev))|Go ).*$" ) {
return 404;
}
proxy_pass http://localhost:5000;
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;
}
} > EOF
~$ sudo ln -s /etc/nginx/sites-available/dockerreg /etc/nginx/site-enabled/dockerreg
~$ sudo systemctl restart nginx
(Replace dockerreg with your own domain, and certificate of course)
Sixth, start the Docker Registry as daemon
~$ cd ~/docker-registry/ && docker-compose up -d
Seventh, test login to registry
~$ curl -X GET -u <user>:<pass> https://dockerreg.tld/v2/_catalog
You should get an “{}” as response
Eighth, login to your new Docker Registry! 🙂
~$ docker login dockerreg.tld
Username: ...
Password: ...
Ninth, push your first image!
# docker build.. docker tag..
~$ docker push dockerreg.tld/imagename
Tenth, your are done!
You can now pull the image when authenticated to your hosts/servers.
Build away ?