Hey there! My name is John and I‘m a cloud infrastructure engineer. If you‘re looking to run your own private Docker registry, you‘ve come to the right place! In this comprehensive guide, I‘ll walk you through everything you need to know to get your registry up and running on Ubuntu.
Why Use a Private Docker Registry?
Before we dive in, let‘s briefly discuss why you may want to run a private registry in the first place.
The main benefit of a private registry is increased security and control over your Docker images. When you use the public Docker Hub to store images, anyone can access them. With a private registry, images are only accessible to your servers that you explicitly grant access to.
Other reasons to use a private registry include:
Compliance: If you have regulatory requirements to control access to data and code, private registries help meet compliance mandates.
Performance: Pulling images from a registry inside your network can be faster than pulling from public registries across the internet.
Reliability: You aren‘t dependent on the uptime and availability of a third party registry service.
According to Docker‘s 2021 survey, 49% of respondents currently use a private registry, up from 29% in 2019. So private registries are certainly gaining popularity!
Alright, let‘s talk about what you‘ll need before getting started:
Two Ubuntu 18.04 servers – You‘ll need one server to run the registry itself, and another to act as a client for pushing/pulling images. Having two separate servers mimics a real-world scenario more closely.
Root access – We‘ll be installing software and running Docker commands, so root access on both servers is required. If you only have a regular user account, you can prefix commands with
Static IP addresses – To simplify networking, configure a static IP on both servers. This allows us to use hostnames to refer to them, rather than hardcoding IPs.
Configuring Hostname Resolution
With our two Ubuntu servers ready, let‘s configure hostname resolution so they can communicate.
On both servers, add an entry to
/etc/hosts mapping the IP to a hostname:
# On registry server echo "192.168.0.100 registry-server" >> /etc/hosts # On client server echo "192.168.0.100 registry-server" >> /etc/hosts
Make sure to use the actual IPs of your servers.
This allows us to access the registry by a hostname instead of IP, which is much nicer!
Now we‘re ready to install Docker, which we‘ll need on both servers.
Docker doesn‘t actually come pre-installed on Ubuntu 18.04. So we‘ll add Docker‘s official repo and install it:
# Install prereqs apt-get install apt-transport-https ca-certificates curl software-properties-common -y # Add Docker‘s GPG key curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - # Add Docker repo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" # Install Docker CE apt-get update && apt-get install docker-ce -y
This adds Docker‘s repository, updates our package list, and installs the
docker-ce package which contains the Docker daemon and CLI.
Let‘s verify Docker is installed and running:
systemctl status docker
You should see output like:
● docker.service - Docker Application Container Engine Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled) Active: active (running) since Thu 2021-07-15 15:08:27 UTC; 4min ago
Looking good! Docker is installed and running.
Docker Usage Trends
In case you‘re curious, here are some quick stats on Docker adoption:
As of April 2021, Docker has over 13 million active developers using the platform and over 5 million nodes actively running Docker containers. [Source]
So it‘s safe to say Docker is a critical skill for developers and sysadmins!
Running the Registry Container
With Docker installed on our server, let‘s pull and run the official Docker registry image.
The registry is available as a container distributed by Docker themselves, making setup easy:
# Pull registry image docker pull registry # Run registry container docker run -d \ -p 5000:5000 \ --restart=always \ --name registry \ -v /opt/data:/var/lib/registry \ registry
Let‘s break this down:
-druns the container in detached mode
-p 5000:5000publishes port 5000
--restart=alwaysrestarts if the container crashes
-v /opt/data:/var/lib/registrymounts a host volume for storage
registryis the image name
The registry will now persist images to the
Check the status:
You should see the registry container running on port 5000.
Our private Docker registry server is ready to go!
Creating a Sample Docker Image
Now let‘s head over to our client server and create a sample Dockerized application image to push to the registry.
First, create a
FROM ubuntu:18.04 RUN apt-get update && apt-get install -y nginx EXPOSE 80 EXPOSE 443 ENTRYPOINT ["nginx", "-g", "daemon off;"]
This will build an image running Nginx on Ubuntu 18.04.
Now build the image using
docker build -t app-image .
Give it a minute or two to complete the build.
We should now have a local image called
app-image. Confirm it built:
You should see the new
app-image in the list.
Before pushing to the registry, we need to tag it with the registry‘s hostname:
docker tag app-image registry-server:5000/app-image:v1
This re-tags it using the registry server hostname, image name, and a version tag.
Pushing to the Private Registry
The moment we‘ve been waiting for! Let‘s push our image up to the private registry:
docker push registry-server:5000/app-image:v1
It will chunk the image into layers and push them up one by one.
Once complete, our image is now stored safely in our private registry!
Pulling Images from the Registry
As one final test, let‘s switch back over to our registry server and pull the image:
docker pull registry-server:5000/app-image:v1
This will fetch the image metadata, layers, and manifest from the registry.
Check it downloaded:
You should see the
app-image listed locally now.
And that‘s it! We‘ve successfully setup a private Docker registry and pushed/pulled images from it. Nice work!
Tips for Production Environments
I wanted to share some quick tips if you‘re looking to run a registry in production:
Use TLS – Encrypt connections to the registry using HTTPS certificates. HTTP traffic is unencrypted and insecure.
Enable authentication – Require login credentials to push and pull images. This prevents unauthorized access.
Use cloud object storage – Rather than local storage, use S3 or a similar service as the backing store. This allows for larger capacity and redundancy.
Scale horizontally – Run multiple registry server instances behind a load balancer to distribute load.
Enable garbage collection – Automatically clean up old, unused images to save disk space.
Use a Docker registry service – For hands-off management, use a managed registry service like AWS ECR, GitLab Registry, or Google Container Registry.
Hopefully these tips give you some ideas on hardening your registry for production use cases!
Let‘s recap what we covered in this comprehensive guide:
- Why use a private registry – Improved security, performance, reliability
- Prerequisites – Two Ubuntu servers, IP addresses, hostname resolution
- Installing Docker – Add repo, install Docker engine
- Running registry container – Pulled, ran, and mounted registry image
- Creating sample image – Dockerfile,
docker build, tagging for registry
- Pushing image – Uploading layers to private registry
- Pulling image – Downloading layers from registry
We took a sample Dockerized app through the full workflow – from image creation, to private registry, and back down locally.
I hope this guide gave you a good introduction to Docker registries and a how-to on setting up your own private registry on Ubuntu. Let me know if you have any other questions!
If you‘re looking to become an expert in containerization technology like Docker, I highly recommend checking out my Container Masterclass course. It takes you from beginner to pro with hands-on labs and projects.
Thanks for reading and happy Dockerizing!