Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
Ubuntu 20 - CERTBOT without SNAP/SNAPD

CERTBOT - Install using Python PIP

Install Certbot using Python PIP (Package Installer for Python) - without using SNAP, APT or SYSTEMD. (Debian/Ubuntu)

This guide will help you install LetsEncrypt / Certbot and a DNS plugin (certbot-dns-route53) using PIP under Debian/Ubuntu.

  • You should already be somewhat familiar with LetsEncrypt, Certbot and any plugin you might need.

  • This guide uses a DNS provider plugin (AWS Route53), but this is really about the install method - not plugins, or validation methods.

  • This pip Python install method should also work on other Linux distributions that support python3 + pip.

In my opinion, this is the best install method (as of now) as the APT version is always behind and I refuse to use SNAPD.

Brady Shea / bmatthewshea 28SEP2021
Last Updated: 17MAR2022

1. Install Python PIP, PIP dependencies and Certbot

Some cleanup first - just in case.
Ignore any 'not found' errors:

sudo apt remove --purge certbot*  # Purge any old certbots via apt.
sudo apt-add-repository --remove ppa:certbot/certbot  # Remove certbot repo.
sudo apt update && sudo apt autoremove  # Re-update and remove any orphaned packages.

Install Python pip:

sudo apt install python3-pip

Install Certbot using Python pip to a system area (sudo -H) - NOT the user area (/home/.local):

sudo -H pip3 install certbot

(IGNORE any warnings like "Running pip as the 'root' user can result in broken permissions..")

Optional - If you use AWS-Route53 DNS you'll need this. Or, pick your own plugin (if needed):

sudo -H pip3 install certbot-dns-route53

For errors such as:

ERROR: zope-component 5.0.1 has requirement zope.interface>=5.3.0a1, but you'll have zope-interface 4.7.1 which is incompatible.

Upgrade the individual python package mentioned in error:

sudo -H pip3 install zope.interface --upgrade

You should see: "Successfully installed zope.interface-5.4.0" depending on name-version.
Reinstalling certbot (using the pip3 command above) should give 0 errors. If so, continue on..

2. Create an AWS-IAM credentials file

Again, I include this here for completeness only.
This guide is really about installing certbot using pip. If you do not use Route53, skip this.


sudo mkdir /root/.aws && sudo chmod 700 /root/.aws
sudo touch /root/.aws/credentials && sudo chmod 600 /root/.aws/credentials
sudo nano /root/.aws/credentials # (Add your own IAM creds in this file and save.)

3. Dry Run and Execution

Running this will also write /etc/letsencrypt/ folders/files (if they don't exist):

sudo certbot certonly --dry-run --agree-tos --dns-route53 --cert-name example -d -d *

You should see: "The dry run was successful.". If so, execute same line w/o dry-run:

sudo certbot certonly --agree-tos --dns-route53 --cert-name example -d -d *

4. Optional, but recommended: Setup automatic renewal and "hooks"

-The Cronjob-

Setup a cron certbot renew job:

sudo nano /etc/cron.d/certbot

Add the following lines:

# Execute every Sunday with a delay of up to 1 day/86400 seconds:
0 0 * * SUN root test -x /usr/local/bin/certbot && perl -e 'sleep int(rand(86400))' && /usr/local/bin/certbot renew

-Renewal Hooks-

"Global" hook methods (affects all certificate renewals the same):

  • LetsEncrypt offers various way to execute a command/script using pre-hook and post-hook (run before or after certificate renewal).
  • You can opt to add to cli.ini. Example: post-hook /full/path/to/script/or/command
  • You can opt to do it directly on renew command line: Example: certbot renew --pre-hook do_something --post-hook do_something
  • You can add a script to /etc/letsencrypt/renewal-hooks + /post or /pre areas

For more granularity we are doing it a bit differntly here:

Edit the certficate renewal file(s).
Note: the '(certname)' is what you set for --cert-name (when you created it):

sudo nano /etc/letsencrypt/renewal/(certname).conf

Under "[renewalparams]" add a line similar to one of the examples.

Example #1:

post_hook = systemctl restart apache2

Example #2:

post_hook = systemctl restart nginx postfix dovecot

Example #3:

pre_hook  = systemctl stop nginx
post_hook = systemctl start nginx

If you need to execute something after certbot gets done with a renewal, you would add a post_hook. Once a renewal happens, you will need to reload or restart any daemons/services which depend on this renewed certificate. (Examples would be a webserver, email services, etc.)

If you need to execute something before renew runs, you can use a pre_hook = as well. An example of when this is needed is when you are using standalone as the Certbot verification type and need to stop the system webserver before renewal. You would issue a 'stop' on the pre_hook and a 'start' on the post_hook to Apache, Nginx, etc, so they aren't blocking the port Certbot uses for verfication.

5. Expanding the certificate

If you forgot a domain, or need to add one at a later date, you can update it. Make sure you include all the original domains as well, or they will get removed.
Using the --expand parameter:

sudo certbot certonly --expand --dns-route53 --cert-name example \
-d -d * -d -d * -d -d *

6. Upgrading

To upgrade certbot (and all dependencies) later if you install using this method, run:

sudo -H pip3 install certbot --upgrade


Copy link

duccio commented Apr 14, 2022

🥇 thanks!

Copy link

cary67 commented May 19, 2022

Excellent! This works within an Ubuntu based Docker container. Thank you!

Copy link

Thanks for the input @cary67 - I'll add a note that it works okay in containers on next revision.
I can not think of a reason it wouldn't work, but have never tried it myself. Good to know.

Copy link

Works great (I'm using Debian), thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment