Note (2026): The old
letsencryptutility became Certbot. A modern setup usually uses Certbot plugins such as--nginx, HTTP-01/DNS-01 validation, and automated renewal throughcertbot renewvia cron or a systemd timer.
Why?
A secure connection has many advantages over good old HTTP: protection against traffic interception, protection against content substitution, better search ranking, and so on. I, for one, like the green icon in the address bar. In the past you had to pay for all that pleasure, so certificates were mostly seen only on large projects or payment systems, where the risk of data compromise is high and without a certificate people simply would not understand you. The letsencrypt.org project is meant to change this state of affairs once and for all.
Getting a free but fully functional certificate is now available to everyone. The project provides a command-line utility that can generate a key and a certificate and, in typical cases, even install that certificate into your web server configuration. The only serious difference from the usual paid certificates is a three-month lifetime. But this is not a minus; it is an intentional approach. The idea is that the server will be configured to automatically obtain a new certificate in place of the previous one, which should help fight key compromise.
Setup
The supplied command-line utility is said to be able to analyze and update Apache and nginx configs on its own, generating a new certificate and adding all the necessary settings for it. Obviously, this makes it possible to update typical configs with little blood spilled, but I think this approach is far from always justified. First, your config may be much more complex than a typical one, and there is no guarantee that automatic mode will cope with it. Second, it is good to have a full understanding of what is happening on your server and why, so that you can fix shortcomings or repeat the steps to get the result. Third, in my case nginx was wrapped inside a Docker container, and the utility definitely was not prepared for that. So we will act the old-fashioned way.
First, download the utility:
cd /opt
mkdir letsencrypt && cd letsencrypt
git clone https://github.com/letsencrypt/letsencrypt .
Now write a script that generates the certificate. Here /var/www/astgo is the directory with the application sources. Important: before creating the certificate, you need to free the ports, if they are occupied, so the utility can use them to confirm that you own the specified domain. In the example below, Docker containers are stopped for this, and after the certificate is renewed they need to be brought back up.
# /opt/update-cert.sh
(cd /var/www/astgo && docker-compose stop && docker-compose rm --force) &&
(cd /opt/ && ./letsencrypt/letsencrypt-auto certonly -d ast.rocks --email astartsky@gmail.com --standalone --renew-by-default --agree-tos --standalone-supported-challenges tls-sni-01) &&
cp /etc/letsencrypt/live/ast.rocks/cert.pem /var/www/astgo/build/nginx &&
cp /etc/letsencrypt/live/ast.rocks/chain.pem /var/www/astgo/build/nginx &&
cp /etc/letsencrypt/live/ast.rocks/fullchain.pem /var/www/astgo/build/nginx &&
cp /etc/letsencrypt/live/ast.rocks/privkey.pem /var/www/astgo/build/nginx &&
(cd /var/www/astgo/ && docker-compose build --no-cache && docker-compose up -d)
Let us look at the utility call in more detail:
- certonly — only generate the certificate; no automatic installation actions are required;
- -d — the domain for which the certificate will be generated;
- —email — the email address where Let’s Encrypt can contact you;
- —standalone — a separate web server will be started to confirm domain ownership;
- —renew-by-default — on a repeated call, a new certificate will not be created;
- —agree-tos — of course, on the first run you need to agree to the terms of service;
- —standalone-supported-challenges tls-sni-01 — allow port 443 to be used for domain validation;
After running the script, the coveted certificates will appear in the folders listed above. The only thing left is to point nginx configs at them. For example, like this:
ssl_stapling_verify on;
ssl_stapling on;
ssl_trusted_certificate /opt/chain.pem;
ssl_certificate_key /opt/privkey.pem;
ssl_certificate /opt/fullchain.pem;
listen 443 ssl;
It also makes sense to put a call to this script into cron every two months, so certificate renewal is fully automatic.