Каждый раз забываю порядок, поэтому записываю. Сначала nginx отдаёт только ACME-челлендж на 80 порту, затем выпускаем сертификат через webroot.
server {
listen 80;
server_name example.org;
location /.well-known/acme-challenge/ { root /var/www/acme; }
location / { return 301 https://$host$request_uri; }
}
certbot certonly --webroot -w /var/www/acme -d example.org
В Ubuntu certbot ставит systemd-таймер сам. Чтобы nginx подхватывал новый сертификат, достаточно одной строки в /etc/letsencrypt/cli.ini:
deploy-hook = systemctl reload nginx
Проверить, что всё сработает: certbot renew --dry-run.