Docker private registry

January 9, 2018
OpenBSD Docker

Docker private registry

Small howto to explain how to create a private Docker registry behind a Nginx proxy. My setup will focus on OpenBSD (because it’s my main system).

With your account, you will push images but they will be in public mode (you only have 1 private repository). If you are ok with this, let’s go !

Please note that you can upgrade your plan to have more private repositories (infos)

But maybe you want more private repositories or you have confidential informations or whatever reasons you want.

If you want to use a private registry, you will have 2 options :

For the first case, please follow the documentation

We will folllow these steps:

$ doas adduser registry 
Use option ``-silent'' if you don't want to see all warnings and questions.

Reading /etc/shells
Check /etc/master.passwd
Check /etc/group

Ok, let's go.
Don't worry about mistakes. There will be a chance later to correct any input.
Enter username []: registry
Enter full name []: Docker private registry user
Enter shell csh ksh nologin sh [nologin]: 
Uid [1001]: 
Login group registry [registry]: 
Login group is ``registry''. Invite registry into other groups: guest no 
Login class      authpf bgpd daemon default pbuild staff unbound 
Enter password []: 
Disable password logins for the user? (y/n) [n]: y

Name:        registry
Password:    ****
Fullname:    Docker private registry user
Uid:         1001
Gid:         1001 (registry)
Groups:      registry 
Login Class: default
HOME:        /home/registry
Shell:       /sbin/nologin
OK? (y/n) [y]:  
Added user ``registry''
Copy files from /etc/skel to /home/registry
Add another user? (y/n) [y]: n
$ doas su -s /bin/sh - registry
Now get the source and compile the program. Please note that since Go 1.8, you no longer need to set the GOPATH variable ([source](
$ go get
$ ./go/bin/registry --version
./go/bin/registry v2.6.0+unknown
In this setup, i have chosen to deploy the registry program in the homedir of the user registry. So i will create a few directories to put configurations file.
$ mkdir -p ~/base/etc ~/base/auth

* */home/registry/base* : root directory
* */home/registry/base/etc* : directory for the config file
* */home/registry/base/auth* : directory for the htpassword file

    Of course feel free to change this 😏
Now get a default config file
$ cd ~/base/etc && wget -O config.yml
Edit the file to have it like this
version: 0.1
    service: registry
    blobdescriptor: inmemory
        rootdirectory: /home/registry/base
    addr: :5000
            X-Content-Type-Options: [nosniff]
            enabled: true
            interval: 10s
            threshold: 3
    realm: basic-realm
    path: /home/registry/base/auth/htpasswd
I have just added the *auth* section and modify the *rootdirectory*.

Now, create the *htpasswd* file :
$ htpasswd -c ~/auth/htpasswd pea
New password: 

Re-type new password: Adding password for user pea ```

Everything is configured. Launch the registry :
$ /home/registry/go/bin/registry serve /home/registry/base/etc/config.yml
WARN[0000] No HTTP secret provided - generated random secret. This may cause problems with uploads if multiple registries are behind a load-balancer.
To provide a shared secret, fill in http.secret in the configuration file or set the REGISTRY_HTTP_SECRET environment variable.
go.version=go1.9.2 version="v2.6.0+unknown"
INFO[0000] redis not configured                          go.version=go1.9.2 version="v2.6.0+unknown"

INFO[0000] Starting upload purge in 19m0s go.version=go1.9.2 version="v2.6.0+unknown” INFO[0000] using inmemory blob descriptor cache go.version=go1.9.2 version="v2.6.0+unknown” INFO[0000] listening on go.version=go1.9.2 version="v2.6.0+unknown” There is a warning about the *HTTP secret*. It's only important if you have multiples registries behind a load balancer. If this is the case or if you want to get red of this warning, simply add this line under *http:*yaml secret: YourSuperSecret ```

Your registry is now running... but not securised ! We need to setup SSL.

This setup is really basic. If you want to tune your config file, you will find more informations in the Docker [documentation](

NOTE: the registry program can handle TLS and Let’s Encrypt too but i’m more confident to have Nginx exposed to the world than the registry program…

server {
        listen       443 http2;
        listen       [::]:443 http2;
        server_name  registry.yourdomain.tld;

        ssl                  on;
        ssl_certificate      /etc/nginx/fullchain.pem;
        ssl_certificate_key  /etc/nginx/privkey.pem;

        location / {

That’s all !

HINT : you will have to increase the value of client_max_body_size in order to upload big images.

% docker login -u pea registry.xxxx.xxxx Password: Login Succeeded ``` You can check that the file ~/.docker/config.json has been created with your credentials.

**WARNING**: keep this file safe and with good permissions (600).

The push refers to repository [] 3fb66f713c9f: Pushed latest: digest: sha256:9ab547ed4d6475a45675f8a127dae347a50957f431a003164a5d1c825868c013 size: 528 ```

For the curious, i have chosen a quick and dirty way :

How to update your Thinkpad's bios with Linux or OpenBSD

September 12, 2018
OpenBSD Linux

Use constraints with Swarm

September 4, 2018

Setup a Let's encrypt certificate with Traefik

May 23, 2018
Docker traefik