Private Docker Registry - CloudCommandos/JohnChan GitHub Wiki

Introduction

Docker Registry allows you to store your Docker container images in your private nodes for security or to support offline Docker instances. In this guide we will set up a containerized Docker Registry hosted by a single node Docker Swarm instance.

Assumptions

  • Your private Docker Registry will run on an Ubuntu 18.04 server with IP 192.168.3.12

Install Docker and Run in Swarm Mode

sudo apt update
sudo apt install \
    apt-transport-https \
    ca-certificates \
    curl \
    gnupg-agent \
    software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

For x86_64 / amd64 systems, add docker package repository

sudo add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) \
   stable"
sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io

Initialize your Docker node as a Docker Swarm manager

sudo docker swarm init --advertise-addr 192.168.3.12

Check that the swarm is formed (You should only have 1 node in this case)

sudo docker node ls

Set Up Docker Registry

Create work directory

mkdir -p /opt/dockerswarm/registry
cd /opt/dockerswarm/registry

Create TLS certs folder

mkdir ca
mkdir certs
cd ca

Create CA

apt-get install -y openssl
openssl req -x509 -sha256 -nodes -days 99999 -newkey rsa:2048 -subj '/O=rootca Inc./CN=registry' -keyout registry_ca.key -out registry_ca.crt

Create self-signed cert (make sure that the IP SANs has the correct IP)

openssl req -out registry.csr -newkey rsa:2048 -nodes -keyout registry.key -subj "/CN=registry/O=registry"
openssl x509 -req -extfile <(printf "subjectAltName=IP:192.168.3.12,DNS:your_registry.com,DNS:your_registry.com:5443") -days 99999 -CA registry_ca.crt -CAkey registry_ca.key -set_serial 0 -in registry.csr -out registry.crt
openssl x509 -in registry.crt -text -noout

Move self-signed cert into certs folder

mv registry.* /opt/dockerswarm/registry/certs

Add your_registry.com into hosts file

nano /etc/hosts
...
192.168.3.12    your_registry.com
...

Create Docker config to trust private registry

nano /etc/docker/daemon.json
{ "insecure-registries" : ["your_registry.com:5443"], "allow-nondistributable-artifacts": ["your_registry.com:5443"] }

Create Docker Stack YAML

cd /opt/dockerswarm/registry
nano docker-stack.yml
version: "3.8"
services:

  redis:
    image: registry:2
    ports:
      - "5443:443"
    volumes:
      - registry-data:/var/lib/registry
      - ./certs:/certs
    environment:
      - REGISTRY_HTTP_ADDR=0.0.0.0:443
      - REGISTRY_HTTP_TLS_CERTIFICATE=/certs/registry.crt
      - REGISTRY_HTTP_TLS_KEY=/certs/registry.key
    deploy:
      replicas: 1
      restart_policy:
        condition: on-failure

volumes:
  registry-data:

Deploy the Docker Registry

docker stack deploy --compose-file docker-stack.yml registry

Test the Registry

docker pull hello-world:latest

Check that you have the hello-world:latest image

docker images

Tag the image with repository as your private registry

docker tag hello-world:latest your_registry.com:5443/my-hello

Push it to your private registry

docker push your_registry.com:5443/my-hello

Delete the image

docker delete your_registry.com:5443/my-hello

Pull the image from your private registry

docker pull your_registry.com:5443/my-hello