Building private Docker registry with basic authentication

by self-signed certificate, using it from OSX

deeeet
2 min readOct 3, 2014

If we can not use DockerHub (Public registry), we need to build private one. Docker provide Docker image for private registry, so it’s very easy to start to it.

$ docker run -p 5000:5000 registry
$ docker push docker-private.com:5000/test-image:latest

Easy, it’s done ! But it’s dangerous. Anyone who knows registry URL can push their own Docker images. So we need some authentication. Generally, we use Basic authentication because Docker client (docker login command) has function for it. Docker registry itself doesn’t have auth function, so we need to setup nginx or Appache in front of Docker registry as reverse proxy for Basic authentication.

In this case, we have some constrain (But, its reasonable):

  • To Basic authentication, docker client ask us to use SSL
  • Docker client verify secure certificate and we can’t allow insecure

If we use self-signed certification (for lazy), its’s a little hard and complicated steps. So I write procedures. For environment, we use Ubuntu for server, nginx for reverse proxy, client for OSX + boot2docker.

Server-side settings

We need 3 settings:

  • nginx
  • Password for Basic authentication
  • Serf-signed certification

nginx

For reverse proxy, we use nginx. Docker registry provides example of nginx configuration in its repository (https://github.com/docker/docker-registry/tree/master/contrib/nginx). So we use it directly.

$ git clone https://github.com/docker/docker-registry 
$ cp docker-registry/contrib/nginx/nginx_1–3–9.conf /etc/nginx/conf.d/.
$ cp docker-registry/contrib/nginx/docker-registry.conf /etc/nginx/.

password

We need to setup user and password for basic authentication.

$ htpasswd -bc /etc/nginx/docker-registry.htpasswd USERNAME PASSWORD 

Serf-signed certification

First, we need to initialise CA serial file and generate CA private and public keys:

$ echo 01 > ca.srl 
$ openssl genrsa -des3 -out ca-key.pem 2048
$ openssl req -new -x509 -days 365 -key ca-key.pem -out ca.pem

Now we have a CA, you can create a server key and certificate signing request (CSR).

$ openssl genrsa -des3 -out server-key.pem 2048 
$ openssl req -subj ‘/CN=<Your Hostname Here>’ -new -key server-key.pem -out server.csr
$ openssl x509 -req -days 365 -in server.csr -CA ca.pem -CAkey ca-key.pem -out server-cert.pem

We should remove the passphrase from server key:

$ openssl rsa -in server-key.pem -out server-key.pem 

Finally, we install server-key and server-cert:

$ cp server-cert.pem /etc/ssl/certs/docker-registry 
$ cp server-key.pem /etc/ssl/private/docker-registry

Client-side settings

Docker client verify secure certificate and we can’t allow insecure connection like cURL’s -k option. So we need to make our CA valid one (There are some Issues to allow insecure connection, but not realized. See more #2687, #5817 ).

If you use boot2docker on OSX, you need to setup it not on OSX but on boot2docker-vm. Here, we use CA public key which we generate above step (https://github.com/boot2docker/boot2docker/issues/347).

$ boot2docker ssh
$ cat ca.pem >> /etc/ssl/certs/ca-certificates.crt
$ /etc/init.d/docker restart

Thats all, now we can login to our private registry.

$ docker login https://docker-private.com

References

--

--

deeeet

Principal YAML engineer at Mercari platform group. https;://twitter.com/deeeet