Lets Encrypt + Haproxy
I've used a few different approaches for renewing the Let's Encrypt certs for my domain over the years, but I recently found this great docker image that encapsulates everything into a single container.
Steps
Create an haproxy cfg file
Here's my Haproxy config file, slightly modified from the one provided in the repo since I'm serving my site on port 8080 locally. I've stored it in /etc/haproxy/haproxy.cfg
global
maxconn 20480
############# IMPORTANT #################################
## DO NOT SET CHROOT OTHERWISE YOU HAVE TO CHANGE THE ##
## acme-http01-webroot.lua file ##
# chroot /jail ##
#########################################################
lua-load /etc/haproxy/acme-http01-webroot.lua
#
# SSL options
ssl-default-bind-ciphers AES256+EECDH:AES256+EDH:!aNULL;
tune.ssl.default-dh-param 4096
# workaround for bug #14 (Cert renewal blocks HAProxy indefinitely with Websocket connections)
hard-stop-after 3s
# DNS runt-time resolution on backend hosts
resolvers docker
nameserver dns "127.0.0.11:53"
defaults
log global
mode http
timeout connect 5000ms
timeout client 50000ms
timeout server 50000ms
option forwardfor
option httplog
# never fail on address resolution
default-server init-addr last,libc,none
frontend http
bind *:80
mode http
acl url_acme_http01 path_beg /.well-known/acme-challenge/
http-request use-service lua.acme-http01 if METH_GET url_acme_http01
redirect scheme https code 301 if !{ ssl_fc }
frontend https
bind *:443 ssl crt /etc/haproxy/certs/ no-sslv3 no-tls-tickets no-tlsv10 no-tlsv11
http-response set-header Strict-Transport-Security "max-age=16000000; includeSubDomains; preload;"
default_backend www
backend www
server ghost localhost:8080 check
http-request add-header X-Forwarded-Proto https if { ssl_fc }
Run the docker container
Once you have the haproxy file set up, run the following command:
DOMAINS="[YOUR COMMA SEPARATED LIST OF DOMAINS]"
EMAIL="[YOUR EMAIL]"
docker run --name haproxy -d \
--net="host" \
-e CERTS=$DOMAINS \
-e EMAIL=$EMAIL \
-e STAGING=false \
--restart=always \
-v /home/ubuntu/haproxy:/etc/haproxy \
-p 80:80 -p 443:443 \
ghcr.io/tomdess/docker-haproxy-certbot:master
That's it! The container runs a cron job that checks your cert weekly and updates it if required