How to Setup Docker Private Registry on Ubuntu 18 – A Comprehensive Guide

default image
This super in-depth guide will teach you step-by-step how to setup and configure a Docker private image registry on Ubuntu 18.04. You‘ll learn how to install Docker, run a registry container, create a sample Docker image, tag and push it to your private registry, and pull it back down. By the end, you‘ll have your own private Docker registry for storing images securely.

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 sudo.

  • 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.

If you need a cloud hosting provider, I recommend Vultr for affordable Ubuntu VPS servers. Use my affiliate link to get a $100 free credit!

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 " registry-server" >> /etc/hosts 

# On client server 
echo " 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!

Installing Docker

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 | sudo apt-key add -

# Add Docker repo
add-apt-repository "deb [arch=amd64] $(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.

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]

  • According to Stack Overflow‘s 2021 survey, Docker is the 3rd most popular technology that developers work with, behind only JavaScript and HTML/CSS. [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 \ 

Let‘s break this down:

  • -d runs the container in detached mode
  • -p 5000:5000 publishes port 5000
  • --restart=always restarts if the container crashes
  • -v /opt/data:/var/lib/registry mounts a host volume for storage
  • registry is the image name

The registry will now persist images to the /opt/data directory.

Check the status:

docker ps

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 Dockerfile:

FROM ubuntu:18.04

RUN apt-get update && apt-get install -y nginx


ENTRYPOINT ["nginx", "-g", "daemon off;"]  

This will build an image running Nginx on Ubuntu 18.04.

Now build the image using docker build:

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:

docker images

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:

docker images

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!


Written by