Docker & Letsencrypt
Update 2019-03-21
The steps below have been implemented with docker-compose in this post
Hippo Toes
We want to run the GitLab CE docker container on our QNAP and access it over HTTPS. One way to do this is to use nginx to proxy connections through to the github container with SSL termination happening in nginx. If we use the nginx-proxy container and docker-letsencrypt-nginx-proxy-companion we can automate the management of the certificates associated with the gitlab.hippo-toes.com (and other) hostnames.
Conceptually, the docker-gen container (part of nginx-proxy) watches docker for containers starting and stopping with special environment variable set. When it sees one of these it applies those variables to a template nginx configuration and reloads nginx. The letsencrypt proxy companion piggy-backs on this behaviour and communicates with the letsencrypt service to issue certificates for the newly proxied services.
nginx
This is the stock nginx container with a label applied and some volumes shared from the qnap to provide a persistent configuration.
docker create -p 10080:80 -p 10443:443 --name nginx \
-v /share/container-vols/nginx/etc/nginx/nginx.conf:/etc/nginx/nginx.conf \
-v /share/container-vols/nginx/etc/nginx/conf.d:/etc/nginx/conf.d \
-v /share/container-vols/nginx/etc/nginx/vhost.d:/etc/nginx/vhost.d \
-v /share/container-vols/nginx/etc/nginx/certs:/etc/nginx/certs:ro \
-v /share/Web-fyodor/hippo-toes:/usr/share/nginx/html \
--label com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy \
--restart always nginx
nginx-gen
The docker-gen container monitors the docker.sock
so that it can react when
other containers are started or stopped. It takes a template as a read only
volume and generates new nginx server configurations based on that. It can also
notify nginx to reload it’s configuration as needed.
docker create --name nginx-gen --volumes-from nginx --restart always\
-v /share/container-vols/nginx/nginx.tmpl:/etc/docker-gen/templates/nginx.tmpl:ro \
-v /var/run/docker.sock:/tmp/docker.sock:ro \
--label com.github.jrcs.letsencrypt_nginx_proxy_companion.docker_gen \
jwilder/docker-gen -notify-sighup nginx -watch -wait 5s:30s \
/etc/docker-gen/templates/nginx.tmpl /etc/nginx/conf.d/default.conf
nginx-letsencrypt
The letsencrypt-nginx-proxy-companion works in a similar way to nginx-gen, but will communicate with letsencrypt to issu certificates.
docker create --name nginx-letsencrypt --volumes-from nginx --restart always\
-v /share/container-vols/nginx/etc/nginx/certs:/etc/nginx/certs:rw \
-v /var/run/docker.sock:/var/run/docker.sock:ro \
-e NGINX_DOCKER_GEN_CONTAINER="nginx-gen" -e NGINX_PROXY_CONTAINER="nginx" \
jrcs/letsencrypt-nginx-proxy-companion
gitlab-ce
This is our first service container. The VIRTUAL_HOST environment variable is caught by nginx-get to build a configuration file and LETSENCRYPT_HOST and LETSENCRYPT_EMAIL are used to request certificates. The configurations generated by the nginx-gen and nginx-letsencrypt containers can get all of the information the need (network address and ports) from the docker socket.
docker create -p 11022:22 -p 11080:80 -p 11443:443 --restart always \
--name gitlab-ce-1 \
-v /share/container-vols/gitlab/log:/var/log/gitlab \
-v /share/container-vols/gitlab/data:/var/opt/gitlab \
-v /share/container-vols/gitlab/backups:/var/opt/gitlab/backups \
-v /share/container-vols/gitlab/etc:/etc/gitlab \
-e VIRTUAL_HOST="gitlab.hippo-toes.com" \
-e LETSENCRYPT_HOST="gitlab.hippo-toes.com" \
-e LETSENCRYPT_EMAIL="hippo@hippo-toes.com" gitlab/gitlab-ce:latest
This site
This is kind of circular, but the letsencrypt container is so convenient that we’ll just fire up another nginx instance and point the proxy at that to serve the static HTML for this site
docker create -p 13080:80 --name nginx-fyodor --restart always\
-v /share/Web-fyodor/hippo-toes/public:/usr/share/nginx/html:ro \
-e VIRTUAL_HOST="fyodor.hippo-toes.com,hippo-toes.com" \
-e LETSENCRYPT_HOST="fyodor.hippo-toes.com,hippo-toes.com" \
-e LETSENCRYPT_EMAIL="hippo@hippo-toes.com" \
-t nginx