The short story is:

  • nginx

Installing is very simple:

curl | sh -s


wget -O - | sh -s

Issuing certificates is also relatively simple. I suggest using the DNS API mode to make things as seamless and interruption free as possible. DNS API also allows for wildcard certificates to be issued.

DNS API mode and all the supported DNS providers are documented here:

The official documentation for my DNS provider (CloudDNS) looks like this:

export CLOUDNS_AUTH_PASSWORD="YYYYYYYYY" --issue --dns dns_cloudns -d -d

The exact command line I use looks like this: --issue --dns dns_cloudns --ecc  -d '' -d '' --fullchain-file /etc/ssl/ --key-file /etc/ssl/private/ --reloadcmd 'systemctl reload nginx' --keylength ec-384 --dnssleep 60 --server zerossl

Let’s break down the parameters:

  • --issue That’s what we want to do
  • --dns dns_cloudns selects the DNS API module for my provider (ClouDNS)
  • --ecc –keylength ec-384 tells to use harder, better, faster, stronger ecliptic curve based keys (
  • -d ‘ tells what domains to include in its acme request. You can use as many domains as you like or just use a wildcard -d ‘*’ * --fullchain-file /etc/ssl/ and --key-file /etc/ssl/private/ tell to deposit the certificate and key in a pre-determined location. I will use these paths in my nginx config later.
  • --reloadcmd 'systemctl reload nginx' tells to reload the nginx config after having issued a certificate. This ensures that the new issue will be used by nginx.
  • --dnssleep 60 sleep for at least 60 seconds after setting up the DNS proof to allow the new DNS entries to propagate to all the servers. ClouDNS is kind of slow in this regard, CloudFlare was usually pretty fast and didn’t need this.
  • lastly --server zerossl which is entirely optional. opted [] to make ZeroSSL [] the new standard ACME server. You can of course switch back to LetsEncrypt at any point or even just for one single certificate request.

That’s it for the encryption side of things. Now let’s look at how it’s hooked up with nginx:

server {
	listen		80;
	listen		[::]:80;
	listen		443 ssl http2;
	listen		[::]:443 ssl http2;

	ssl_certificate		/etc/ssl/;
	ssl_certificate_key	/etc/ssl/private/;
	add_header Strict-Transport-Security "max-age=31536000;" always;

	access_log /var/log/nginx/;
	error_log /var/log/nginx/;

	root /var/www/blog;

(This is a sample configuration and should only be used as a starting point for your own customised config)

access_log, error_log and add_header directives are entirely optional but useful. ssl_certificate and ssl_certificate_key point to the paths I specified earlier.

This configuration is sufficient to make nginx serve HTTP over TLS with Everything is automated from here on out, will periodically check for expiration of certificates and re-issue as needed.