Running a private Docker registry with Nexus 3

Running a private Docker registry with Nexus 3

For quite a while I am looking for a private Docker registry server which is easy to set-up and fairly trivial to run in our IT infrastructure, e.g. being able to connect to our central LDAP server for user management. A few months back I realized that the next major version of Nexus will be able to host docker images. Since we already have a nexus instance running this seemed like a natural fit for us. Finally I found some time to play with the current M7 release which already offers the docker registry feature. 

Running Nexus is simple, all it requires is Java 1.8. To make things a bit more complicated tried to run Nexus in a docker container with haproxy in front. To be able to run Nexus 3 as a docker registry I needed to tweak haproxy because the docker registry in Nexus 3 is running on a different port. I needed to distinguish between regular requests for Nexus and the requests of the docker client hitting the docker registry. Luckily the docker client exposes itself in the user agent sent to the server. Thus I configured the haproxy frontend this way:

frontend haproxy-http
  bind 192.168.65.1:80
  acl host_is_nexus hdr(host) -i nexus.mydomain.loc
  acl client_is_docker hdr_sub(user-agent) -i docker

  mode http
  reqadd  X-Forwarded-Proto:\ http
  use_backend docker-backend if host_is_nexus client_is_docker
  use_backend nexus-backend if host_is_nexus !client_is_docker

frontend haproxy-https
  bind 192.168.65.1:443 ssl crt /etc/ssl/private/mydomain.loc.pem
  acl host_is_nexus hdr(host) -i nexus.mydomain.loc
  acl client_is_docker hdr_sub(user-agent) -i docker

  mode http
  reqadd  X-Forwarded-Proto:\ https
  use_backend docker-backend if host_is_nexus client_is_docker
  use_backend nexus-backend if host_is_nexus !client_is_docker


The regular nexus backend configuration looks like this:

backend nexus-backend
  balance leastconn
  cookie JSESSIONID prefix
  mode http
  option httpclose
  option forwardfor
  redirect  scheme https if !{ ssl_fc }
  server node1 127.0.0.1:8081

The backend configuration for the docker registry looks quite similar but hits a different port. The port needs to be configured in Nexus 3 during the hosted docker setup. Since SSL termination is done via haproxy the docker registry of Nexus 3 is configured for http access only. My first try to configure an https connection for the docker registry resulted in a org.sonatype.nexus.bootstrap.jetty.UnsupportedHttpSchemeException exception.

backend docker-backend
  balance leastconn
  cookie JSESSIONID prefix
  mode http
  option httpclose
  option forwardfor
  redirect  scheme https if !{ ssl_fc }
  server node1 127.0.0.1:8082


To connect to the private docker registry use the following command:

docker login nexus.mydomain.loc


In case the command above gives you a "client is newer than server" error, try to force the docker client to run with a different api version. In my case the server was running version 1.21:

DOCKER_API_VERSION=1.21 docker login nexus.mydomain.loc


Next up: Waiting for the final Nexus 3 release ;)


Eintrag von Stephan Hochdörfer am 06.05.2016

Tags: Docker, Nexus, haproxy

Diese Webseite verwendet Cookies, um die Bedienfreundlichkeit zu erhöhen. Mit der Nutzung unserer Webseite wird das Einverständnis erklärt, dass wir Cookies verwenden. Weitere Informationen.