Private Docker Registry Part 4: let’s secure the registry
Now that we have a registry with authentication and storing docker images to Azure Storage, we need to get this server out on it’s own, meaning we need to secure it with SSL.
NOTES:
- The reference material for this article can be found here
- We’ll base the haproxy and letsencrypt services on this previous article
The Services Definition
Important Assumption: You are running those docker commands from (or using docker-machine as explained in this article) a machine publicly accessible by the domain you want to get SSL certificates for.
version: '2'
services:
haproxy:
image: m21lab/haproxy:1.6.2
links:
- letsencrypt
volumes_from:
- letsencryptletsencrypt:
image: m21lab/letsencrypt:1.0
environment:
DOMAINS: 'YOUR_DOMAIN'
EMAIL: 'RECOVERYEMAIL@YOUR_DOMAIN'
OPTIONS: '--staging'registry:
volumes_from:
- letsencrypt:ro
environment:
REGISTRY_HTTP_SECRET: "your-http-secret"
REGISTRY_HTTP_TLS_CERTIFICATE: /etc/letsencrypt/live/LETSENCRYPT_DOMAINS_ENV_VAR/fullchain.pem
REGISTRY_HTTP_TLS_KEY: /etc/letsencrypt/live/LETSENCRYPT_DOMAINS_ENV_VAR/privkey.pem registry-ui:
environment:
FORCE_SSL: 'true'
ENV_REGISTRY_PROXY_FQDN: 'LETSENCRYPT_DOMAINS_ENV_VAR'
ENV_DOCKER_REGISTRY_USE_SSL: 1
Service Overrides
HAProxy
- Uses a different image which will be handling the SSL traffic.
- Links to the new letsencrypt service to route the challenges http requests to it
- Uses volumes_from letsenrypt service to read the received SSL certificates and dynamically load them
Let’s Encrypt
This services is used to generate valid CA signed SSL certificates for the domain hosting the registry. More information in the previous article
Registry
This service is the docker registry. A lot of configuration was required:
- Uses volumes_from letsenrypt service to read the received SSL certificates and dynamically load them
- Set registry service specific environment variables:
REGISTRY_HTTP_SECRET=secret: A randomly generated secret used to sign state that may be stored. More information about it here
REGISTRY_HTTP_TLS_CERTIFICATE=public key
REGISTRY_HTTP_TLS_KEY=private key:
Those must be mapped to the letsencrypt service volume
Registry UI (Docker Registry Frontend)
This service hosts a very simple docker UI name docker-registry-frontend by Konrad Kleine (thanks a lot!). In this service, not so much was required to be configured:
- Set the registry-ui environment variables:
FORCE_SSL=true: To make sure all the traffic redirected from the haproxy service is using SSL
ENV_REGISTRY_PROXY_FQDN=“DOMAIN”: The domain name you want to be displayed in the registry UI.
ENV_DOCKER_REGISTRY_USE_SSL=1: The registry must now be accessed using https
How to start it
To start the registry, from your domain accessible machine or using docker-machine to point your local docker environment to a domain accessible machine, simply run this command
docker-compose -f docker-compose.yml \
-f docker-compose.auth.yml \
-f docker-compose.azure.yml \
-f docker-compose.ssl.yml \
up -d
- The registry is reachable at DOMAIN:5000
- The registry UI is reachable https://DOMAIN, you’ll be asked for a password
IMPORTANT NOTES: The registry is:
- Running on your domain
- Authenticated using basic auth
- Storing all images in the Azure Storage Account you specified
- Using SSL
How to validate it works
Since we already pushed an image to the local repository once we setup the Azure Storage Account, this image is still there. We can pull it using the domain instead of local host to login/pull/logou
docker login -u <username> DOMAIN:5000
# enter your passworddocker pull DOMAIN:5000/<optional-username>/alpine:3.4docker logout DOMAIN:5000
We hope this series of articles helped you!