Sep 16, 2020

Nginx, Let's Encrypt, IPv6, HTTP/2 and healthcheck

While working on the generic configuration set for Nginx/PHP/MySQL web applications in Docker, the most difficult problem I met was writing scripts and configuration files for Nginx. I need a simple, generic, small and reliable solution to issue and renew Let's Encrypt certificates in Docker, reload Nginx, support HTTP2 and IPv6.

Each of these tasks alone has a pretty straightforward solution. It became much more complicated when I started writing a generic solution one could copy-paste among different sites and domains.

A requirement for a solution to be generic means I don't want to build my own Nginx image, I want to use an official image from the Docker Hub: nginx:alpine. I use Acme.sh that just works everywhere.

A requirement to be simple means that I don't a separate container to issue certificates, no http proxy to process HTTP requests from Let'sEncrypt. 

And a requirement to be reliable means I don't pass a docker unix socket to a container to reload Nginx when the certificate is renewed

I use a posix sh script running in background in the Nginx container with a plain "webroot" method to pass Let's Encrypt authorization. I implement a healthcheck for Docker.

It has a limitation of scalability and replication: this solution is for a single Nginx service setup.

Here is a standalone pattern for Nginx configs:

https://github.com/grikdotnet/docker-patterns/tree/master/1.nginx-acme.sh-healthcheck