Private Docker Registry with Minio

Private Docker Registry with Minio #

We’re going to set up:

  • the official Docker registry container
  • using Minio (S3-compatible object storage) for storage
  • and configuring Quantum’s built-in Traefik for TLS and HTTP basic auth in front of the registry

You can then use that registry as a private registry for Quantum, for example.

Basic Setup #

First, generate an HTTP basic auth string by running:

$ echo $(htpasswd -nb user password) | sed -e s/\\$/\\$\\$/g
user:$$apr1$$qOsD9gYr$$gV7U8bj44LFu8TlA.tv6Q.

(the doubling of the $ signs is to escape docker-compose variable substitution). Choose a strong password, as this will be your registry login.

Also generate an access key (min 3 chars) and secret key (min 8 chars) for minio, for example via:

$ pwgen -sn 64
ZYWxIuGNt97RMcecKarquW5Wmh0WHvssO1zmEgSEZs2izZ9CAZJiqgT3X9xbzBVU
N8EBGWANv28IVmC5YOmWWGQL0ifQMgHujsiYAAN41tZdrX72DEIeLeGXTOx26Dvw
...

Then, create a docker-compose.yml, inserting these values at the appropriate points:

version: "3.8"

services:

  minio:
    image: minio/minio
    restart: always
    volumes:
      - minio-data:/data
    networks:
      - registry
    environment:
      MINIO_ACCESS_KEY: &access_key ZYWxIuGNt97RMcecKarquW5Wmh0WHvssO1zmEgSEZs2izZ9CAZJiqgT3X9xbzBVU
      MINIO_SECRET_KEY: &secret_key N8EBGWANv28IVmC5YOmWWGQL0ifQMgHujsiYAAN41tZdrX72DEIeLeGXTOx26Dvw
    # the mkdir creates the REGISTRY_STORAGE_S3_BUCKET
    entrypoint: /bin/sh
    command: -c 'mkdir -p /data/docker-registry && /usr/bin/minio server /data'

  registry:
    image: registry:2
    restart: always
    networks:
      - registry
      - public
    deploy:
      labels:
        traefik.enable: "true"
        traefik.docker.network: "public"
        traefik.port: "5000"
        traefik.frontend.auth.basic.users: "user:$$apr1$$qOsD9gYr$$gV7U8bj44LFu8TlA.tv6Q."
    environment:
      REGISTRY_STORAGE: s3
      REGISTRY_STORAGE_S3_ACCESSKEY: *access_key
      REGISTRY_STORAGE_S3_SECRETKEY: *secret_key
      REGISTRY_STORAGE_S3_REGIONENDPOINT: http://minio:9000
      REGISTRY_STORAGE_S3_BUCKET: docker-registry
      REGISTRY_STORAGE_S3_SECURE: "false"
      REGISTRY_STORAGE_S3_region: ignored-for-minio
      REGISTRY_STORAGE_REDIRECT_DISABLE: "true"

volumes:
  minio-data:

networks:
  registry:
  public:
    external:
      name: public

Now deploy it on Quantum, either

This will expose the registry on registry.your-server.docker.planetary-networks.de, and you can docker login there with the basic auth user/password.

Optional Configuration #

Expose the registry on your own domain #

For that, first set up your DNS to work with Quantum. Then, just add a label to tell traefik about the hostname:

--- registry-nonpublic.yml
+++ registry-customhost.yml
@@ -27,6 +27,7 @@
         traefik.docker.network: "public"
         traefik.port: "5000"
         traefik.frontend.auth.basic.users: "user:$$apr1$$qOsD9gYr$$gV7U8bj44LFu8TlA.tv6Q."
+        traefik.frontend.rule: "Host:storage.example.com"
     environment:
       REGISTRY_STORAGE: s3
       REGISTRY_STORAGE_S3_ACCESSKEY: *access_key

Make minio public #

You can use the minio installation as a general-purpose S3-compatible object store. Minio also ships with a web interface (the login is the access-key/secret-key combination). Set the following traefik labels to expose that on your server:

--- registry-nonpublic.yml
+++ registry-public.yml
@@ -9,6 +9,11 @@
       - minio-data:/data
     networks:
       - registry
+      - public
+    deploy:
+      labels:
+        traefik.enable: "true"
+        traefik.docker.network: "public"
+        traefik.port: "9000"
     environment:
       MINIO_ACCESS_KEY: &access_key ZYWxIuGNt97RMcecKarquW5Wmh0WHvssO1zmEgSEZs2izZ9CAZJiqgT3X9xbzBVU
       MINIO_SECRET_KEY: &secret_key N8EBGWANv28IVmC5YOmWWGQL0ifQMgHujsiYAAN41tZdrX72DEIeLeGXTOx26Dvw

Use the registry with quantum #

Just follow the setup instructions to tell Quantum about your new registry.

More users, better access control #

You can add more than one basic auth user to traefik.frontend.auth.basic.users (just separate them by commas (user:hash,user:hash,...)) but they will all have complete read and write access to the registry.

If you need more finely-grained access control, you might want to take a look at projects like Harbor or Portus. Alternatively, GitLab and GitHub also include a private docker registry.