🔐 How to Automatically Renew and Deploy Let's Encrypt SSL Certificates for a Docker-based Python Web App
If you’re hosting a web server (like a Python/Django app via Docker) on a Linux server and using Let’s Encrypt SSL certificates, this guide walks you through obtaining, configuring, and automatically updating your certificates every 90 days.
We’ll use certbot
, crontab
, and a simple copy-deploy workflow. This example is based on a working production setup at webejs.iwant2study.org and specficially
webejs.iwant2study.org:8000
✅ Prerequisites
-
A Linux-based VPS/server (e.g. CentOS or RHEL)
-
Domain name (e.g.
webejs.iwant2study.org
) pointing to your server’s IP -
Docker container already running your web app (like
python manage.py runserver
) -
Apache running on port 443 (or similar) with port 80 accessible temporarily
-
certbot
installed
🧱 Step 1: Stop Apache Temporarily
Let’s Encrypt (via certbot
) needs exclusive access to port 80 to complete the challenge.
🔐 Step 2: Request the SSL Certificate via Certbot
Use the standalone
method:
-
Enter your email
-
Agree to the Terms of Service
-
Choose whether to share your email with EFF
-
Wait for the confirmation
✅ Output should include:
🔁 Step 3: Restart Apache
📁 Step 4: Copy Certificate Files to Your App Folder
the original folder for the certs are here
Copy the certificate and private key:
Adjust permissions (may not be necessary)
🛠 Step 5: Automate Renewal with crontab
Since Let’s Encrypt certificates are valid for 90 days, we automate checking and deploying renewed certs daily.
Open the root crontab editor:
If using
nano
:
-
Paste the following line:
This runs daily at 3:00 AM and:
-
Renews the certificate if needed
-
Deploys the updated cert/key to your Docker app path
Save and exit:
-
Ctrl + O
,Enter
(to write) -
Ctrl + X
(to quit)
✅ You can confirm with:
🔍 Step 6: Test Certificate Validity
Use OpenSSL to inspect:
Output:
Or, check in the browser at:
🔗 https://webejs.iwant2study.org
🧽 Optional Cleanup: Remove Temporary Copies
If you previously copied .pem
files for download:
Need to go inside server
-
Navigate to the webEJS Directory: Change the directory to the location where the webEJS server files are stored. This is usually done with the command:
cd webejs-1.1/webejs-server
-
Check Docker Logs: Before restarting, it’s advisable to check the Docker logs to diagnose any potential issues. The command below retrieves the last 100 lines of logs:
sudo docker compose logs --tail 100
-
Restart the Docker Containers: To resolve the issue, the Docker containers running webEJS need to be stopped and then restarted. This is done with the following commands:
sudo docker compose down && sudo docker compose up -d
The first command stops all running containers, and the second command restarts them in detached mode.
✅ Summary
Task | Command |
---|---|
Get cert | sudo certbot certonly --standalone -d yourdomain.com |
Copy cert | cp cert.pem → machine.crt , privkey.pem → machine.key |
Schedule renewal | sudo crontab -e with certbot renew line |
Test cert | openssl x509 -in machine.crt -noout -dates |