Skip to main content
The bench setup lets-encrypt command automatically obtains and configures free SSL certificates from Let’s Encrypt for your Frappe sites.
This command requires sudo privileges and temporarily stops NGINX during certificate generation, causing brief downtime.

Usage

sudo bench setup lets-encrypt [SITE] [OPTIONS]

Arguments

SITE
string
required
The site name to set up SSL for.Must be an existing site in your bench.

Options

--custom-domain
string
Set up SSL for a specific custom domain instead of the site name.The domain must already be added to the site.
--custom-server
string
Custom ACME server URL for certificate authority.Useful for testing with Let’s Encrypt staging server.
-n, --non-interactive
flag
Run command non-interactively without prompts.Automatically restarts NGINX and runs certbot without interaction.Warning: Only use after first successful setup, as certbot may need manual DNS verification initially.

Prerequisites

DNS Configuration

Your domain must be properly configured in DNS and pointing to your server before running this command.
  1. Domain DNS A record must point to your server’s IP
  2. DNS propagation must be complete (check with nslookup your-domain.com)
  3. Port 80 must be open and accessible from the internet

Multi-Tenant Mode

SSL setup requires DNS multi-tenancy:
// sites/common_site_config.json
{
  "dns_multitenant": true
}

Certbot Installation

Certbot must be installed: Ubuntu/Debian:
sudo apt-get install certbot
CentOS/RHEL:
sudo yum install certbot

Examples

Basic SSL Setup

Set up SSL for your main site:
sudo bench setup lets-encrypt site1.local
You’ll be prompted to:
  1. Confirm NGINX will be stopped temporarily
  2. Accept Let’s Encrypt Terms of Service
  3. Provide an email address for renewal notifications

SSL for Custom Domain

If your site has a custom domain:
# First add the domain
bench setup add-domain example.com --site site1.local

# Then set up SSL for it
sudo bench setup lets-encrypt site1.local --custom-domain example.com

Non-Interactive Mode

For automated scripts or renewals:
sudo bench setup lets-encrypt site1.local --non-interactive

Staging Environment

Test with Let’s Encrypt staging server (doesn’t count against rate limits):
sudo bench setup lets-encrypt site1.local \
  --custom-server https://acme-staging-v02.api.letsencrypt.org/directory

What It Does

1

Verify DNS Multitenant

Checks that dns_multitenant is enabled in bench configuration.
2

Create Certbot Config

Generates Let’s Encrypt configuration file:
/etc/letsencrypt/configs/[domain].cfg
3

Stop NGINX

Temporarily stops NGINX to free port 80 for certbot’s standalone authenticator.
4

Obtain Certificate

Runs certbot to obtain SSL certificate from Let’s Encrypt.Certbot uses HTTP challenge to verify domain ownership.
5

Update Site Config

Adds SSL certificate paths to site configuration:
{
  "ssl_certificate": "/etc/letsencrypt/live/domain/fullchain.pem",
  "ssl_certificate_key": "/etc/letsencrypt/live/domain/privkey.pem"
}
6

Regenerate NGINX Config

Updates NGINX configuration to include SSL settings.
7

Start NGINX

Restarts NGINX with new SSL configuration.
8

Setup Auto-Renewal

Creates a cron job to automatically renew certificates monthly:
0 0 */1 * * certbot renew -a nginx --post-hook "systemctl reload nginx"

Certificate Files

Location

Certificates are stored in:
/etc/letsencrypt/live/[domain]/
├── fullchain.pem       # Certificate + intermediate chain
├── privkey.pem         # Private key
├── cert.pem           # Certificate only
└── chain.pem          # Intermediate chain only

Permissions

Certificate files are owned by root with restricted permissions:
ls -l /etc/letsencrypt/live/example.com/
# -rw-r--r-- root root fullchain.pem
# -rw-r--r-- root root privkey.pem

Automatic Renewal

Renewal Cron Job

The command sets up automatic renewal at midnight daily:
# View cron job
sudo crontab -l

# Output:
0 0 */1 * * certbot renew -a nginx --post-hook "systemctl reload nginx"

Manual Renewal

Test renewal before expiration:
sudo certbot renew --dry-run
Force renewal (certificates must be within 30 days of expiration):
sudo certbot renew --force-renewal
sudo systemctl reload nginx

Renewal Logs

Check renewal logs:
sudo tail -f /var/log/letsencrypt/letsencrypt.log

Multiple Sites

Set up SSL for multiple sites:
sudo bench setup lets-encrypt site1.local
sudo bench setup lets-encrypt site2.local
sudo bench setup lets-encrypt site3.local
Each site gets its own certificate.

Wildcard SSL

For wildcard certificates (*.example.com):
sudo bench setup wildcard-ssl example.com --email [email protected]
Note: Wildcard certificates require DNS challenge (not HTTP), so you’ll need to manually add TXT records.

Troubleshooting

DNS Not Configured

Error: “You cannot setup SSL without DNS Multitenancy” Solution:
# Enable DNS multitenant
bench config dns_multitenant true

# Regenerate NGINX config
bench setup nginx --yes

# Try again
sudo bench setup lets-encrypt site1.local

Domain Not Reachable

Error: “Failed authorization procedure” Diagnosis:
# Check DNS
nslookup site1.local

# Test port 80 accessibility
curl -I http://site1.local

# Check firewall
sudo ufw status
Solutions:
  1. Verify DNS A record points to server IP
  2. Ensure port 80 is open in firewall
  3. Check that domain is accessible from internet

Rate Limit Exceeded

Let’s Encrypt has rate limits:
  • 50 certificates per registered domain per week
  • 5 duplicate certificates per week
Solution: Use staging server for testing:
sudo bench setup lets-encrypt site1.local \
  --custom-server https://acme-staging-v02.api.letsencrypt.org/directory

Certificate Already Exists

Error: “SSL for Domain already exists” Solution: Certificate is already configured. To renew:
sudo certbot renew --force-renewal
sudo bench setup nginx --yes
sudo systemctl reload nginx

NGINX Won’t Start

After SSL setup, if NGINX fails:
# Test NGINX config
sudo nginx -t

# Check certificate paths
cat sites/site1.local/site_config.json

# Verify certificates exist
sudo ls -l /etc/letsencrypt/live/site1.local/

# Regenerate NGINX config
bench setup nginx --yes
sudo nginx -t
sudo systemctl restart nginx

Security Best Practices

HTTPS Redirect

NGINX automatically redirects HTTP to HTTPS when SSL is configured.

HSTS Header

Add HSTS header for enhanced security:
# Add to NGINX config
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

Certificate Monitoring

Monitor certificate expiration:
# Check expiration date
sudo certbot certificates

# Output shows:
# Expiry Date: 2024-06-01 12:00:00+00:00 (VALID: 89 days)

Renewal Notifications

Let’s Encrypt sends email reminders before expiration to the email provided during setup.

Source Code

Implementation: bench/config/lets_encrypt.py:18 Command definition: bench/commands/setup.py:158

Build docs developers (and LLMs) love