INFO

Securing Your Domain: A Guide to Installing Certbot on Debian & Oracle Linux 7

If you’ve ever lost an afternoon to SSL/TLS configuration, you’re in good company. That’s exactly why I put together this guide.

In the following sections, we’ll configure Let’s Encrypt certificates using Certbot. Since Let’s Encrypt provides certificates free of charge, there’s no reason to leave a website unencrypted. We’ll automate renewals and make sure your website can communicate securely without requiring constant supervision. Because some things deserve attention and certificate expiration dates are not one of them.


Step 1: Install Certbot

The installation process varies slightly depending on your operating system and CPU architecture. In this guide, we use the standalone method to issue the certificate directly, without relying on a web server already running on the machine.

Debian / Ubuntu

sudo apt update
sudo apt install certbot -y

Oracle Linux 7 / RHEL 7 (Standard x86_64)

On standard instances, you need to enable the EPEL repository before installing via yum:

sudo yum install oracle-epel-release-el7 -y
sudo yum install certbot -y

Oracle Linux 7 on ARM (aarch64 / OCI Ampere)

ARM-based instances, very common in Oracle Cloud’s Free Tier often do not have a pre-compiled Certbot package available in EPEL. The cleanest workaround is installing via pip, pinning specific dependency versions to avoid compilation errors on Python 3.6:

# 1. Install Python 3 and PIP
sudo yum install python3 python3-pip -y

1. 2. Upgrade PIP and Setuptools
sudo pip3 install --upgrade pip setuptools

1. 3. Install specific dependency versions and Certbot
sudo pip3 install cryptography==3.3.2 pyOpenSSL certbot

1. 4. Create a symlink to run it globally
sudo ln -s /usr/local/bin/certbot /usr/bin/certbot

Note: you may see a WARNING about running pip as root. In a dedicated lab or isolated server environment, this is generally safe to proceed with.


Step 2: Open Port 80 for Validation

Certbot uses port 80 (HTTP) to validate domain ownership. Make sure it is open both on the local firewall and in your cloud provider’s network rules.

Local Firewall

Debian (UFW):

sudo ufw allow 80/tcp

Oracle Linux 7 (Firewalld):

sudo firewall-cmd --permanent --add-port=80/tcp
sudo firewall-cmd --reload

Cloud Provider Network Configuration

Regardless of local firewall settings, inbound traffic on port 80 must also be permitted at the network level whether through OCI Security Lists, AWS Security Groups, or Azure Inbound Rules.


Step 3: Run Certbot to Get the Certificate

Before running the command, confirm that your domain points to the server’s public IP via an A Record at your DNS provider. Wait for propagation, then proceed:

sudo certbot certonly --standalone -d yourdomain.com

Important: no web server or Docker container can be occupying port 80 during this process. If you have Docker mapped to that port, stop the service temporarily:

sudo systemctl stop docker docker.socket

Step 4: Where Are My Certificates?

After a successful issuance, Certbot will display the paths to the generated files. Keep these close, you will need them:

  • Full chain: /etc/letsencrypt/live/yourdomain.com/fullchain.pem
  • Private key: /etc/letsencrypt/live/yourdomain.com/privkey.pem

Step 5: Automating Renewal with Nginx Proxy Manager (Docker)

If you are running Nginx Proxy Manager (NPM) via Docker, it is possible to fully automate the renewal process straight from the terminal. When a certificate is added as a “Custom” provider in the NPM web interface, it gets copied into an internal container directory. The script below keeps everything in sync, no manual intervention required.

1. Create the automation script

sudo nano /usr/local/bin/renova_certbot_npm.sh

2. Paste the following content

Adjust the domain name, container name, and custom_ssl folder ID to match your environment:

#!/bin/bash

1. 1. Stop Docker to free up port 80
systemctl stop docker docker.socket

1. 2. Run Certbot silent renewal
/usr/bin/certbot renew --quiet

1. 3. Start Docker again
systemctl start docker

1. 4. Wait for the NPM container to fully boot
sleep 10

1. 5. Copy the real certificates into NPM (using -L to follow symlinks)
docker cp -L /etc/letsencrypt/live/yourdomain.com/fullchain.pem npm_container_name:/data/custom_ssl/npm-X/fullchain.pem
docker cp -L /etc/letsencrypt/live/yourdomain.com/privkey.pem npm_container_name:/data/custom_ssl/npm-X/privkey.pem

1. 6. Reload Nginx configuration
docker exec npm_container_name nginx -s reload

3. Make the script executable

sudo chmod +x /usr/local/bin/renova_certbot_npm.sh

4. Schedule it with Cron

sudo crontab -e

Add the following line to check twice a day:

0 0,12 * * * /bin/bash /usr/local/bin/renova_certbot_npm.sh

A note on the NPM web console: because the certificate was manually added as a “Custom” provider, the expiration date displayed in the interface will not update visually. This is expected behavior, what matters is that the actual certificate files on disk are continuously renewed and valid through the background script.


Final Thoughts

Properly implementing SSL/TLS is one of the most fundamental and most overlooked habits in system administration. An expired certificate does not warn you before it breaks production. It just breaks it. By automating renewals with a dedicated script and integrating directly with Docker via the command line, you eliminate human error, work around architectural limitations, and keep your proxies running without surprises.

No good sysadmin leaves the front door ajar. And no well-managed certificate expires without someone knowing about it.

Leave a Reply

Your email address will not be published. Required fields are marked *