The default certbot certonly –standalone is quite useful for a quick start to run a standalone server and get the SSL certificate. But nowadays everyone is running their own server. Which would cause the issue of binding port 80 fail. In order to fix this would be using –webroot instead.

Firstly, create a new folder for nginx to serve static file

mkdir -p /var/www/letsencrypt/.well-known/acme-challenge

Secondly, in each server config that you want to have SSL add the followings, E.g. inside into the server listen 80 block.

location ^~ /.well-known/acme-challenge/ {
root /var/www/letsencrypt;

It tells nginx when matching path /.well-known/acme-challenge/, go to /var/www/letsencrypt/.well-known/acme-challenge/ to find the file.

Thirdly, run nginx reload and

certbot certonly --webroot --webroot-path /var/www/letsencrypt/ --agree-tos -m [email protected] -d yourdomain

Letsencrypt will put a text file inside /var/www/letsencrypt/.well-known/acme-challenge and fire a get request to achieve it in order to finish the justification. You can tail the nginx log to see the requests to debug.

Fourthly, you add the listen 443 block into your domain’s nginx config file

listen 443;
ssl on;
ssl_certificate /etc/letsencrypt/live/;
ssl_certificate_key /etc/letsencrypt/live/;
ssl_prefer_server_ciphers On;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

Lastly, create a cron job task file in /etc/cron.d/

@monthly root /bin/bash -c "/usr/bin/letsencrypt certonly --webroot -w /var/www/letsencrypt -d"

Hope that helps!

Auto-renewing Let’s Encrypt SSL certificate

Let’s Encrypt’s certificates are valid for 90 days. To automatically renew the certificates before they expire, the certbot package creates a cronjob and a systemd timer. The timer will automatically renew the certificates 30 days before its expiration.

When the certificate is renewed, the nginx service needs to be reloaded. Open the /etc/letsencrypt/cli.ini and add the following line:

sudo nano /etc/letsencrypt/cli.ini
deploy-hook = systemctl reload nginx

To test the renewal process, run the certbot --dry-run command:

sudo certbot renew --dry-run

If there are no errors, it means that the renewal process was successful.

Now, Let’s Encrypt’s certificates are valid for 90 days… You’ll want to setup a crob job to automate the renewal process… To do that, open crontab and add the entry below:

sudo crontab -e

Then add the line below and save…

0 1 * * * /usr/bin/certbot renew >> /var/log/letsencrypt/renew.log

Save and you’re done!

How to update certbot to latest version on Ubuntu

Lets Encrypt has announced that, “Beginning June 1, 2020, we will stop allowing new domains to validate using the ACMEv1 protocol. You should upgrade to an ACMEv2 compatible client before then, or certificate issuance will fail. For most people, simply upgrading to the latest version of your existing client will suffice. You can view the client list at: “

This article explains how to update certbot to latest version (0.31 at the time of writing this) on Ubuntu 16.04LTS.

If you are on non LTS version such as 17.10 these steps will not work. You have to either update your OS or find another client that complies.

My test machine is Ubuntu 16.04 LTS and runs Apache with certbot 0.21. You can check OS and certbot by following commands.

$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 16.04.3 LTS
Release:        16.04
Codename:       xenial

$ certbot --version
certbot 0.21.0

Now we need a higher version certbot that supports ACMEv2. Certbot can be updated as follows:

  • Step 1) Run apt-get update


    $ sudo apt-get update
    Hit:1 xenial InRelease
    Fetched 349 kB in 0s (593 kB/s)
    Reading package lists... Done
  • Step 2) Upgrade latest version of certbot

    $ sudo apt-get install --only-upgrade certbot
    This will upgrade only certbot package, and only if it is installed
    $ sudo apt-get install --only-upgrade certbot
    Reading package lists... Done
    Building dependency tree
    Reading state information... Done
    Setting up python-certbot-apache (0.31.0-1+ubuntu16.04.1+certbot+1) ...
    Setting up python3-icu (1.9.2-2build1) ...
  • Step 3) Verify new Certbot Version

    $ certbot --version
    certbot 0.31.0
    As you can see we are now at 0.31 whicch supports ACMEv2. However we need to do a trail run to verify that it is able to use ACMEv2
  • Step 4) Do a Dry Run

    $ sudo certbot renew --dry-run
    Saving debug log to /var/log/letsencrypt/letsencrypt.log
    Cleaning up challenges
  • Step 5) Double check debug log to verify ACME server. You need to be logged in as root user to view letsencrypt logs.

    $ sudo su -
    # cd /var/log/letsencrypt/
    #sudo vi letsencrypt.log

If you search for “v02”, you will be able to see entries for

DEBUG:acme.client:Sending GET request to

Note that if you see only acme-staging-v01 then this means that the update has not worked as expected. If the update is successful, you will see requests to

Sometimes certbot upgrade may fail as below:

$ sudo apt-get install --only-upgrade certbot
Reading package lists... Done
Building dependency tree
Reading state information... Done
You might want to run 'apt-get -f install' to correct these:

If this happens you just need to run the following command.

$ sudo apt-get -f install

automatic renew

go to crontab: 

crontab -e

then add the next: 

#auto renew ssl
0 1 * * * /usr/bin/certbot renew >> /var/log/letsencrypt/renew.log 

0 1 * * * /usr/bin/certbot renew --renew-hook "nginx -s reload" -q >> /var/log/letsencrypt/renew.log

or add setting into letsencrypt file:  /etc/letsencrypt/cli.ini

deploy-hook = systemctl reload nginx


Remove ssl from letsencrypt

sudo rm -rf /etc/letsencrypt/{live,renewal,archive}/{,}

issue: new certbot require python 3

First of all, you have to upgrade python to version 3: 
apt update && apt install --only-upgrade python3-acme

If you have multiple version of python in your system. You just need to update the symbolic link of python inside /usr/bin/ 

root@irshad:/usr/bin# ls -lrth python*
lrwxrwxrwx 1 root root    9 Apr 16  2018 python -> python2.7
-rwxr-xr-x 1 root root 3.6M Nov 12  2018 python2.7
-rwxr-xr-x 2 root root 4.4M May  7 14:58 python3.6

In above example if you see the output of python --version you will get python2.7

Now update the python symlink using below command-

root@irshad:/usr/bin# unlink python
root@irshad:/usr/bin# ln -s /usr/bin/python3.6 python
root@irshad:/usr/bin# python --version
Python 3.6.8

finally, for renewal, just run: 

certbot certonly --webroot --webroot-path /var/www/letsencrypt/ --agree-tos -m [email protected] -d