How To Set Up a Private Docker Registry on Ubuntu?

How To Set Up a Private Docker Registry on Ubuntu?

Introduction

Private Docker registries make it easy to share and distribute Docker images between containers. Setting up a private registry helps speed up deployments and ensures smooth CI/CD workflows with Docker.

In this guide, we’ll learn how to set up and configure a private Docker registry that can be accessed externally.

Requirements:

– A server or VPS running Ubuntu.

– Root access to the server, or a user with sudo permissions to install packages and modify configurations.

What is a Private Docker Registry?

A private Docker registry is a storage system for Docker images hosted on a private server and accessible only to authorized users. It acts as a central repository for images, allowing authenticated Docker hosts to pull and push them.

When configured on a server, the private registry interacts with Docker Hub over the internet to pull or push images. It then stores these images locally and shares them securely with other authorized Docker hosts. Docker hosts can connect to the private registry, pull the required images, and use them to build containers.

Steps to Set Up a Private Docker Registry on Ubuntu

Follow these simple steps to set up a private Docker registry on an Ubuntu server.

Install Docker on Ubuntu

Docker is a platform that lets you package and run applications in lightweight, isolated containers. Containers are like virtual machines but more efficient and portable. Docker uses a client-server model, where the Docker daemon manages the containers.

Before You Begin

Remove old versions of Docker to avoid conflicts. This won’t delete your existing images, containers, or networks. Run:

# apt-get remove docker docker-engine docker.io containerd runc

Remove old versions of Docker

If you get the error message “E: Unable to locate package docker-engine“. It means that the Docker is not installed on your Ubuntu system.

Install Docker from the Official Repository

To get the latest stable version of Docker, install it from the official Docker repository. Here’s how:

Step 1: Update the Package Repository

Run the following command to update the system and install the necessary updates:

# apt update

Update the Package Repository

Step 2: Install Required Packages

Install packages needed to securely download and manage Docker repositories:

# apt install apt-transport-https ca-certificates curl software-properties-common -y

Install Required Packages

This command:

– Enables apt to download packages over HTTPS.

– Installs curl for data transfers.

– Sets up tools for managing software.

Step 3: Add Docker’s GPG Key

A GPG key ensures the software is authentic. Add Docker’s GPG key by running:

# curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

Add Docker's GPG Key

If successful, the output will display OK.

Step 4: Add the Docker Repository

Add Docker’s official repository to your system:

# add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"

Add the Docker Repository

This updates the system to use the official Docker repository for installation.

Step 5: Verify the Installation Source

To confirm Docker will be installed from the correct repository:

# apt-cache policy docker-ce

Verify the Installation Source

This checks that Docker will come from the official repository, not Ubuntu’s default repository.

Step 6: Install Docker

Install Docker with the following command:

# apt install docker-ce -y

Install Docker

Wait for the installation to complete.

Step 7: Check Docker’s Status

Verify that Docker is installed and running:

# systemctl status docker

Check Docker's Status

Suppose you are receiving an error message Inactive (dead). It means that the service is in the stop status. You need to start it manually.

Step 8: Run the following command in the terminal to start the Docker service.

# systemctl start docker

Start the Docker service

Step 9: To start the Docker service automatically on boot, run the following command in the terminal.

# systemctl enable docker

Start the Docker service automatically

The output will confirm that the Docker service is active and set to start automatically on boot.

You’re now ready to use Docker and proceed to set up your private Docker registry!

Install Docker Compose on Ubuntu

Docker Compose is a tool that lets you manage multiple containers with a single command. It helps you define and run applications that rely on multiple services, such as caches, databases, or APIs.

Note: This guide explains how to install Docker Compose V2, which uses the docker-compose command. The older docker-compose command (V1) is no longer supported.

If you already have Docker installed on Linux, the recommended way to install Docker Compose is through the official Docker repository. Here’s how to do it.

Install Necessary Packages

Before adding the Docker repository, install some required packages:

Step 1: Update the package list:

# apt update

Step 2: Install certificate tools and curl:

# apt install ca-certificates curl

Install certificate tools and curl

Add Docker Repository

To get Docker Compose from the official Docker repository, follow these steps:

Step 1: Create the /etc/apt/keyrings directory and set proper permissions:

# install -m 0755 -d /etc/apt/keyrings

Set permissions

Step 2: Download the Docker GPG key:

# curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc

Download the Docker GPG key

Step 3: Set read permissions for the key:

# chmod a+r /etc/apt/keyrings/docker.asc

Set read permissions

Step 4: Add the Docker repository to your system:

# echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] \
https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

Add the Docker repository

Install Docker Compose Plugin

Now that the Docker repository has been added, follow these steps to install Docker Compose:

Step 1: Update the package list again:

# apt update

Step 2: Install the Docker Compose plugin:

# apt install docker-compose-plugin -y

Install the Docker Compose plugin

If it is already installed, then you will get a message that docker-compose-plugin is already the newest version.

Step 3: Verify the installation:

# docker compose version

Verify the installation

This will show the installed version of Docker Compose.

Docker Compose is now installed and ready to use for managing multi-container applications.

Install Nginx on Ubuntu

Nginx (pronounced “Engine X”) is an open-source web server. It works as a reverse proxy, directing client requests to the right server. Over time, it has added features like load balancing, scaling, and handling static files faster than Apache. These features improve performance and resource usage.

Steps to Install Nginx on Ubuntu

Step 1: Log in to your server using SSH with the root user:

Step 2: Before installing any software, update the package list to ensure you download the latest version. Run:

# apt update

Let the update process finish.

Step 3: Install Nginx by running:

# apt install nginx

Install Nginx

Wait for the system to download and install Nginx. Once done, you’re ready to use it.

Nginx is now installed and can be configured as needed!

Install and Set Up a Private Docker Registry

To host a private Docker registry, you need to set up the registry service, configure an Nginx server, and create security certificates. Follow these steps to set up the private registry.

Step 1: Create Registry Directories

Start by organizing your files in a proper directory structure. Here’s how:

1. Create the main directory for the registry and subdirectories for Nginx and authentication:

# mkdir -p registry/{nginx,auth}

Create the main directory

2. Inside the nginx folder, create additional directories for configuration and SSL certificates:

# mkdir -p registry/nginx/{conf.d,ssl}

Create additional directories

3. Navigate to the registry directory and check the folder structure:

# cd registry && tree

Registry directory

Note: If the tree command is not installed, you can receive an error message “-bash: tree: command not found”. You can install it with:

# apt install tree

Tree command

The output will show the complete directory structure for your private Docker registry.

Step 2: Create Docker Compose File and Define Services

To set up a private Docker registry, you’ll need a compose.yaml file to define the required services and configurations. Follow these steps to create and configure the file:

1. Create the compose.yaml file

Use a text editor to create a new file in the registry directory. For example, use Nano:

# nano compose.yaml

2. Add the Docker Compose Configuration

Paste the following content into the file:

version: '3'
services:
  registry:
    image: registry:2
    restart: always
    ports:
      - "5000:5000"
    environment:
      REGISTRY_AUTH: htpasswd
      REGISTRY_AUTH_HTPASSWD_REALM: Registry-Realm
      REGISTRY_AUTH_HTPASSWD_PATH: /auth/registry.passwd
      REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY: /data
    volumes:
      - registrydata:/data
      - ./auth:/auth
    networks:
      - mynet
  nginx:
    image: nginx:alpine
    container_name: nginx
    restart: unless-stopped
    tty: true
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx/conf.d/:/etc/nginx/conf.d/
      - ./nginx/ssl/:/etc/nginx/ssl/
    networks:
      - mynet
networks:
  mynet:
    driver: bridge
volumes:
  registrydata:
    driver: local

Add the Docker Compose Configuration

Explanation of the Configuration

Registry Service

– Image: Uses the Docker Registry image (registry:2).

– Restart Policy: restart: always ensures the service restarts automatically after a system reboot.

– Ports: Maps port 5000 inside the container to port 5000 on the host.

Environment Variables:

– Enables authentication (REGISTRY_AUTH) using the registry.passwd file.

Specifies the location for data storage.

– Volumes:

registrydata volume stores registry data.

Local auth directory holds the authentication file.

– Networks: Runs on the mynet Docker network.

Nginx Service

– Image: Uses the lightweight nginx:alpine image.

– Container Name: Named nginx for easy identification.

Ports:

Maps port 80 for HTTP.

Maps port 443 for HTTPS.

Volumes:

– Local conf.d directory for Nginx configuration files.

– Local ssl directory for SSL certificates.

Networks: Runs on the same mynet network as the registry service.

Networks and Volumes

– Network: mynet uses the bridge driver for service communication.

– Volume: registrydata uses the local driver to store registry data.

3. Save and Close the File

After adding the configuration, save the file (e.g., press Ctrl+O and Enter in Nano) and close it (e.g., press Ctrl+X).

Your Docker Compose file is now ready to set up the private registry and Nginx services.

Step 3: Set Up Nginx Port Forwarding

To configure Nginx for your Docker registry, you’ll need to set up a virtual host with specific server settings. Follow these steps:

1. Create a Virtual Host File

Create a new file called registry.conf in the nginx/conf.d directory:

# nano nginx/conf.d/registry.conf

2. Add the Configuration

Paste the following configuration into the file, replacing [domain] with your registry’s domain name (e.g., example.com):

upstream docker-registry {
    server registry:5000;
}
server {
    listen 80;
    server_name registry.[domain];
    return 301 https://registry.[domain]$request_uri;
}
server {
    listen 443 ssl http2;
    server_name registry.[domain];
    ssl_certificate /etc/nginx/ssl/fullchain.pem;
    ssl_certificate_key /etc/nginx/ssl/privkey.pem;
    error_log  /var/log/nginx/error.log;
    access_log /var/log/nginx/access.log;
    location / {
        if ($http_user_agent ~ "^(docker\/1\.(3|4|5(?!\.[0-9]-dev))|Go ).*$" )  {
            return 404;
        }
        proxy_pass                          http://docker-registry;
        proxy_set_header  Host              $http_host;
        proxy_set_header  X-Real-IP         $remote_addr;
        proxy_set_header  X-Forwarded-For   $proxy_add_x_forwarded_for;
        proxy_set_header  X-Forwarded-Proto $scheme;
        proxy_read_timeout                  900;
    }
}

Add the Configuration

3. Save and Exit

Save the file (e.g., press Ctrl+O and then Enter in Nano).

Exit the editor (e.g., press Ctrl+X).

Configuration Details:

1. Nginx to Registry Connection:

– Nginx connects to the Docker registry on port 5000 using the docker-registry upstream.

2. HTTP to HTTPS Redirection:

The first server block listens on port 80 and redirects all traffic to HTTPS.

3. Secure Connection:

– The second server block listens on port 443 and uses SSL certificates for secure communication.

– Specifies certificate files: /etc/nginx/ssl/fullchain.pem and /etc/nginx/ssl/privkey.pem.

4. User Agent Restriction:

– Blocks requests from older Docker clients (versions 1.5 and below) due to known issues.

5. Proxy Configuration:

– Passes client requests to the registry service.

– Adds headers like Host, X-Real-IP, and X-Forwarded-For for better request tracking.

Once this configuration is saved, Nginx will handle secure traffic for your private Docker registry.

Step 4: Increase Nginx File Upload Size

Nginx has a default file upload size limit of 1MB. Since Docker images are often larger, you’ll need to increase this limit. Follow these steps to raise the upload size to 2GB:

1. Create a New Configuration File

Open a new Nginx configuration file:

# nano nginx/conf.d/additional.conf

2. Set the Upload Limit

Add the following line to the file:

client_max_body_size 2G;

Set the Upload Limit

3. Save and Exit

– Save the file (e.g., press Ctrl+O and then Enter in Nano).

– Exit the editor (e.g., press Ctrl+X).

This will allow Nginx to accept files up to 2GB in size.

Step 5: Set Up Basic Authentication

Follow these steps to set up basic authentication:

1. Create the Authentication File

Navigate to the auth directory:

# cd auth

Create the Authentication File

2. Create a new password file named registry.passwd for your user:

# htpasswd -Bc registry.passwd [username]

Create a new password file

3. Set a Password

– Enter a strong password when prompted and confirm it by typing it again.

– The system will confirm the operation was successful.

Now, your basic authentication is configured for added security.

Step 6: Start Docker Registry

Now that everything is set up, follow these steps to run the Docker Registry and Nginx containers:

1. Start the Containers

Run the following command to launch the containers in the background (detached mode):

# docker compose up -d

Start the Containers

2. Verify the Services

Check if the registry and Nginx services are running by typing:

# docker compose ps

The output will display the running services and their assigned ports.

Push Docker Image to Private Registry

Follow these steps to upload a Docker image to your private registry:

Step 1: Log in to the Registry

Run the following command to log in to your private Docker registry:

# docker login https://registry.[domain]/v2/

For example, if your registry is at accucloudsupport.com, use:

# docker login https://registry.accucloudsupport.com/v2/

Log in to the Registry

Step 2: Enter Credentials

Provide the username and password you created earlier during setup.

Step 3: Push the Image

Use the following command to push an image to the private registry:

# docker push registry.[domain]/[new-image-name]

Push the Image

Pull Image from Docker Hub to Private Registry

Follow these steps to download an image from Docker Hub and store it in your private registry:

Step 1: Pull the Image

Use the docker pull command to download the image from Docker Hub:

# docker pull [image]

Pull the Image

Step 2: Tag the Image

Add a tag to the image to label it for your private registry:

# docker image tag [image] registry.[domain]/[new-image-name]

Tag the Image

Step 3: Verify the Image Locally

Check if the image is stored locally by listing all images:

# docker images

Verify the Image Locally

Conclusion

By following this guide, you’ve set up a private Docker registry on Ubuntu, configured Nginx, and added basic authentication. Now you can use it to manage Docker images and build containers on remote Docker hosts.