MHOSTMHOST

Free SSL with Let's Encrypt (certbot)

Let's Encrypt issues trusted TLS certificates for free, and the certbot client does the rest: it proves you control the domain, obtains the certificate, turns on HTTPS in nginx or Apache, and sets up auto-renewal. By the end of this article you'll have working HTTPS in a few minutes — and won't need to think about certificate expiry again.

What you'll need

  • A domain whose A record already points at this VPS's public IP (no AAAA needed — mHost VPS are IPv4-only) — Let's Encrypt verifies domain ownership over HTTP, so DNS needs to be in place beforehand.
  • nginx or Apache already installed and configured, already serving the site over plain HTTP (port 80) with the right domain in server_name (nginx) or ServerName (Apache). Don't have a web server yet? You can install one with the ready-made LEMP/LAMP recipe (see the "Ready-made VMmanager 6 recipes" article) or manually — see the nginx and Apache articles.
  • SSH access as root or a user with sudo.
  • Open ports 80 (Let's Encrypt uses it to verify the domain) and 443 (HTTPS itself runs on it).
Important: open ports 80 and 443 in the firewall — otherwise Let's Encrypt won't be able to verify the domain, and browsers won't be able to reach HTTPS. On Ubuntu/Debian with ufw, see the "UFW firewall" article; on AlmaLinux/Rocky with firewalld: sudo firewall-cmd --permanent --add-service=http --add-service=https && sudo firewall-cmd --reload.
Tip: to check that the domain already points at this server, run dig +short example.com — it should return the same IP address shown on the server's card in VMmanager 6.

Step 1. Install certbot

Certbot's official documentation recommends installing it via snap — the same way on every distro, with the nginx and Apache plugins already built in (no need to install them separately). The certbot versions in the apt/dnf repositories are often noticeably out of date on LTS distros, which is why the snap package is certbot's own current recommendation.

Ubuntu 22.04/24.04 and Debian 11/12

bash
sudo apt update
sudo apt install snapd
Tip: on Ubuntu, snapd is usually already installed by default — the command above just makes sure it's up to date. On Debian you may need to reconnect over SSH after this so the updated PATH takes effect.

AlmaLinux / Rocky Linux 8/9

bash
sudo dnf install epel-release
sudo dnf upgrade
sudo dnf install snapd
sudo systemctl enable --now snapd.socket
sudo ln -s /var/lib/snapd/snap /snap

After that, reconnect over SSH — otherwise snap's paths won't be picked up.

From here it's the same on every system. If certbot was already installed from the OS package manager, remove it first so it doesn't conflict with the snap version:

  • Ubuntu/Debian: sudo apt-get remove certbot
  • AlmaLinux/Rocky: sudo dnf remove certbot

Install certbot itself and prepare the command:

bash
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/local/bin/certbot

Check that it's in place:

bash
certbot --version

Step 2. Get a certificate

Certbot finds the domains in your nginx/Apache configuration (server_name / ServerName) on its own, obtains the certificate, edits the config as needed, and turns on the HTTP-to-HTTPS redirect — all in a single command. You don't have to list the domains explicitly: certbot will show what it found and let you pick.

If you're using nginx

bash
sudo certbot --nginx -d example.com -d www.example.com

The first time it runs, certbot will ask for an email address (for important certificate notices) and ask you to agree to the Let's Encrypt terms of service. You can supply both up front and skip the prompts:

bash
sudo certbot --nginx -d example.com -d www.example.com -m you@example.com --agree-tos -n
Tip: to edit the nginx config yourself, obtain just the certificate — without automatically editing the configuration: sudo certbot certonly --nginx -d example.com -d www.example.com.

If you're using Apache

On Ubuntu/Debian, Apache's SSL module is already included — you just need to enable it and restart Apache:

bash
sudo a2enmod ssl
sudo systemctl restart apache2

On AlmaLinux/Rocky, the mod_ssl module needs to be installed as a separate package:

bash
sudo dnf install mod_ssl
sudo systemctl restart httpd

From here it's the same idea as with nginx:

bash
sudo certbot --apache -d example.com -d www.example.com
Tip: the certificate-only option, without automatically editing the Apache config — sudo certbot certonly --apache -d example.com -d www.example.com.

Certbot saves the certificate and private key under /etc/letsencrypt/live/example.com/ (fullchain.pem and privkey.pem) — you'll need these paths if you're configuring HTTPS manually (certonly mode).

Done: open https://example.com in a browser — you should see the padlock and no certificate warnings.

Step 3. Set up auto-renewal (systemd timer)

Let's Encrypt certificates are only valid for 90 days, so they need to be renewed regularly. There's nothing extra to configure: the certbot snap installs a systemd timer that checks all your certificates twice a day and renews the ones that are close to expiring.

Confirm the timer exists and is active:

bash
systemctl list-timers | grep certbot

You should see a line for snap.certbot.renew.timer with the time of its next run. For details on the timer itself:

bash
systemctl status snap.certbot.renew.timer
Tip: certbot keeps the settings each certificate was issued with (domains, plugin, email) in /etc/letsencrypt/renewal/example.com.conf — that's the file the timer uses on renewal, and you normally don't need to touch it by hand.

Step 4. Test renewal: certbot renew --dry-run

Instead of waiting for a certificate to actually expire, you can check that renewal will work: certbot simulates it against Let's Encrypt's staging server, without touching your real certificate.

bash
sudo certbot renew --dry-run

On success, the output ends with something like "Congratulations, all simulated renewals succeeded". If you get an error instead, it's usually a closed port 80 or a domain that no longer points at this server.

Tip: run this check right after issuing a certificate, and after any change to your web server or firewall configuration — so you catch a renewal problem before the old certificate actually expires.

What's next

HTTPS is set up and will renew itself. From here it's worth finishing the web server setup itself — see the nginx and Apache articles — and double-checking that the firewall has exactly the ports it needs open, in the "UFW firewall" article.