How to install a Let's Encrypt SSL certificate with ServerPilot and DigitalOcean
Back in 2016, Cormac Bracken wrote a fantastic article on how to install a free Let’s Encrypt SSL certificate with ServerPilot and DigitalOcean when you have multiple domains on a single droplet.
Since then, several things have changed. I’ve created my own reference here that I keep relatively up-to-date.
(The stuff in all caps should get replaced with your own details.)
Log in to your droplet from the command line
Unfortunately, this whole process requires the CLI. If you’d rather use a GUI, ServerPilot offers one with their paid plans.
First, SSH into your droplet as your serverpilot
user.
ssh serverpilot@YOUR-DROPLET-IP-OR-HOSTNAME
Then, login as the root user. You’ll probably need to enter your root user password.
su
Install Let’s Encrypt
In order for this to work, you first have to install Let’s Encrypt on your DigitalOcean droplet. Once it’s installed, you can jump straight to the next section for additional domains and skip this step.
While Let’s Encrypt recommends using Snap, it’s not available on DigitalOcean’s VPS environment. You can install the Let’s Encrypt package using APT.
apt update
apt install certbot
Finally, check that everything worked OK.
certbot --help
Install a certificate
Replace the stuff in caps with your info. Replace YOURAPP
with the name of your application in ServerPilot.
certbot certonly --agree-tos --email YOU@YOUREMAIL.com --webroot -w /srv/users/serverpilot/apps/YOURAPP/public -d YOURSITE.com -d www.YOURSITE.com
Note: If your droplet has some weird security settings, you may need to add the flag --preferred-challenge dns
. Try it without the flag first.
If it worked, you’ll get the following message.
Congratulations! Your certificate and chain have been saved at
/etc/letsencrypt/live/YOURAPP/fullchain.pem
.
Now we need to tell the server where to find the certificate. Jump into the vhosts.d
directory.
cd /etc/nginx-sp/vhosts.d
Next, create a new .conf
file for the SSL certificate.
nano YOURAPP.ssl.conf
Replace the stuff in all caps below, and paste this into the file. Press control+X to exit and save.
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name YOURDOMAIN.com www.YOURDOMAIN.com;
ssl on;
# letsencrypt certificates
ssl_certificate /etc/letsencrypt/live/YOURDOMAIN.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/YOURDOMAIN.com/privkey.pem;
#SSL Optimization
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:20m;
ssl_session_tickets off;
# modern configuration
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK';
# OCSP stapling
ssl_stapling on;
ssl_stapling_verify on;
# verify chain of trust of OCSP response
ssl_trusted_certificate /etc/letsencrypt/live/YOURDOMAIN.com/chain.pem; #root directory and logfiles root /srv/users/serverpilot/apps/YOURAPP/public;
access_log /srv/users/serverpilot/log/YOURAPP/YOURAPP_nginx.access.log main;
error_log /srv/users/serverpilot/log/YOURAPP/YOURAPP_nginx.error.log;
#proxyset
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-SSL on;
proxy_set_header X-Forwarded-Proto $scheme;
#includes
include /etc/nginx-sp/vhosts.d/YOURAPP.d/*.nonssl_conf;
include /etc/nginx-sp/vhosts.d/YOURAPP.d/*.conf;
}
Finally, we need to restart the nginx server for the changes to take effect.
service nginx-sp restart
As Cormac notes in their original article, if there are any errors in your conf file, this process will fail and break all the things.
If there’s any problem with the config file, Nginx will fail to restart, and all websites on your server will be unavailable. Quickly rename the
.conf
file to.con
, then restart Nginx again while you figure out the problem.
Automatically renewing your certificate
By default, Let’s Encrypt certificates are good for 90 days.
We don’t want to have log into our server and renew them manually. We want them to automatically renew. Cormac shares an approach in their original article, but I found it stopped working for me after a while. Here’s what I do instead.
(Once you set this up, you’ll never have to touch it again, even if you add more certificates.)
First, jump into the /opt
directory.
cd /opt
Check if there’s a /scripts
directory in it already.
ls
If there’s not, create one.
mkdir scripts
Either way, jump into the /scripts
directory.
cd /scripts
Next, create a bash script named renewcerts.sh
.
nano renewcerts.sh
Copy/paste the following script into your file, replacing the stuff in all caps with your info. The press control+X to exist and save.
#!/bin/sh
certbot renew --agree-tos --email YOU@YOUREMAIL.com --post-hook "service nginx-sp restart" >> /opt/logs/renew-ssl.log
Next, open your crontab
file. Copy/paste this into the file, then exit and save.
# Renew SSL certificates
0 0 * * * /opt/scripts/renewcerts.sh
Once a day, your server will run the bash script and renew any certificates that are close to expiring.