Skip to main content
This guide covers setting up SSL certificates for secure HTTPS connections to your Frappe sites using Let’s Encrypt, wildcard certificates, or custom SSL certificates.

Prerequisites

Before setting up SSL:
  • Production bench configured (see Production Deployment)
  • Domain name(s) pointing to your server
  • DNS-based multitenancy enabled for Let’s Encrypt
  • Certbot installed (automatic during setup)
  • Port 80 and 443 accessible
SSL setup requires DNS-based multitenancy. Port-based sites cannot use Let’s Encrypt certificates.

Enable DNS Multitenancy

SSL setup requires DNS multitenancy to be enabled:
bench config dns_multitenant on
Regenerate NGINX configuration:
bench setup nginx
sudo bench setup reload-nginx
With DNS multitenancy enabled, sites are accessed by their domain name (e.g., mysite.com) rather than by port number.

Let’s Encrypt SSL Setup

Let’s Encrypt provides free, automated SSL certificates with 90-day validity and automatic renewal.
1
Configure DNS
2
Ensure your domain points to your server:
3
dig mysite.com +short
# Should return your server's IP address
4
Run Let’s Encrypt setup
5
sudo bench setup lets-encrypt [sitename]
6
Example:
7
sudo bench setup lets-encrypt mysite.com
8
Confirm the process
9
You’ll be prompted:
10
Running this will stop the nginx service temporarily causing your sites to go offline
Do you want to continue?
11
Type ‘y’ to continue.
12
Setup completes automatically
13
The command will:
14
  • Stop NGINX temporarily
  • Run Certbot to obtain certificates
  • Configure NGINX for HTTPS
  • Set up automatic renewal cron job
  • Restart NGINX
  • Non-interactive mode

    For automation or scripting:
    sudo bench setup lets-encrypt mysite.com --non-interactive
    
    Non-interactive mode should only be used after you’ve successfully run the command once manually.

    Custom Domain SSL

    For sites with custom domains configured via bench setup add-domain:
    1
    Add custom domain to site
    2
    bench setup add-domain custom.example.com --site mysite.com
    
    3
    Setup SSL for custom domain
    4
    sudo bench setup lets-encrypt mysite.com --custom-domain custom.example.com
    

    Wildcard SSL Certificates

    Wildcard certificates cover all subdomains under a domain (e.g., *.example.com).
    Wildcard certificates require DNS validation via manual TXT record creation.
    1
    Run wildcard SSL setup
    2
    sudo bench setup wildcard-ssl example.com --email [email protected]
    
    3
    For wildcard without base domain:
    4
    sudo bench setup wildcard-ssl *.example.com --email [email protected] --exclude-base-domain
    
    5
    Complete DNS challenge
    6
    Certbot will display TXT records to add to your DNS:
    7
    Please deploy a DNS TXT record under the name
    _acme-challenge.example.com with the following value:
    
    ABC123XYZ789...
    
    Before continuing, verify the record is deployed.
    
    8
    Add TXT record to DNS
    9
    In your DNS provider:
    10
  • Name: _acme-challenge.example.com
  • Type: TXT
  • Value: The value provided by Certbot
  • 11
    Verify DNS propagation
    12
    dig _acme-challenge.example.com TXT +short
    
    13
    Complete the process
    14
    Press Enter in the terminal to continue after DNS is updated.

    Wildcard certificate configuration

    Wildcard configuration is stored in sites/common_site_config.json:
    {
      "wildcard": {
        "domain": "*.example.com",
        "ssl_certificate": "/etc/letsencrypt/live/example.com/fullchain.pem",
        "ssl_certificate_key": "/etc/letsencrypt/live/example.com/privkey.pem"
      }
    }
    
    All sites matching the wildcard pattern automatically use this certificate.

    Custom SSL Certificates

    For commercial or self-signed certificates:
    1
    Obtain certificate files
    2
    You’ll need:
    3
  • Certificate file (.crt or .pem)
  • Private key file (.key)
  • Certificate chain/intermediate certificates (optional)
  • 4
    Combine certificate and chain
    5
    If you have separate certificate and chain files:
    6
    cat certificate.crt intermediate.crt > fullchain.pem
    
    7
    Set certificate paths for site
    8
    bench set-ssl-certificate mysite.com /path/to/fullchain.pem
    bench set-ssl-key mysite.com /path/to/privkey.key
    
    9
    Or edit sites/mysite.com/site_config.json directly:
    10
    {
      "ssl_certificate": "/path/to/fullchain.pem",
      "ssl_certificate_key": "/path/to/privkey.key"
    }
    
    11
    Regenerate NGINX config
    12
    bench setup nginx
    sudo bench setup reload-nginx
    

    Custom domain certificates

    For custom domains:
    bench setup add-domain custom.example.com --site mysite.com \
      --ssl-certificate /path/to/fullchain.pem \
      --ssl-certificate-key /path/to/privkey.key
    

    Certificate Renewal

    Automatic renewal

    Let’s Encrypt setup automatically configures a cron job for renewal:
    # Runs daily at midnight
    0 0 */1 * * /usr/bin/certbot renew -a nginx --post-hook "systemctl reload nginx"
    
    View the cron job:
    sudo crontab -l
    

    Manual renewal

    To manually renew all certificates:
    sudo bench renew-lets-encrypt
    
    Or use Certbot directly:
    sudo certbot renew
    sudo systemctl reload nginx
    

    Check certificate expiry

    sudo certbot certificates
    
    Example output:
    Certificate Name: mysite.com
      Domains: mysite.com
      Expiry Date: 2026-06-01 12:34:56+00:00 (VALID: 89 days)
      Certificate Path: /etc/letsencrypt/live/mysite.com/fullchain.pem
      Private Key Path: /etc/letsencrypt/live/mysite.com/privkey.pem
    
    Or using OpenSSL:
    echo | openssl s_client -servername mysite.com -connect mysite.com:443 2>/dev/null | openssl x509 -noout -dates
    

    Testing SSL Configuration

    Verify HTTPS access

    curl -I https://mysite.com
    
    Expected response:
    HTTP/2 200
    server: nginx
    ...
    

    Check SSL certificate

    openssl s_client -connect mysite.com:443 -servername mysite.com < /dev/null
    

    Test SSL strength

    Use SSL Labs for comprehensive testing: https://www.ssllabs.com/ssltest/

    Verify automatic redirect

    HTTP should redirect to HTTPS:
    curl -I http://mysite.com
    
    Expected:
    HTTP/1.1 301 Moved Permanently
    Location: https://mysite.com/
    

    Troubleshooting SSL Issues

    Certificate verification failed

    Issue: Let’s Encrypt cannot verify domain ownership Solutions:
    1. Verify DNS points to server:
      dig mysite.com +short
      
    2. Ensure port 80 is accessible:
      sudo netstat -tlnp | grep :80
      
    3. Check firewall:
      sudo ufw status
      sudo ufw allow 80/tcp
      sudo ufw allow 443/tcp
      
    4. Verify NGINX is configured correctly:
      sudo nginx -t
      

    DNS multitenancy not enabled

    Error: “You cannot setup SSL without DNS Multitenancy” Solution:
    bench config dns_multitenant on
    bench setup nginx
    sudo bench setup reload-nginx
    

    Certificate not found

    Issue: NGINX reports certificate file not found Solution:
    1. Check certificate paths:
      ls -la /etc/letsencrypt/live/mysite.com/
      
    2. Verify site_config.json paths:
      cat sites/mysite.com/site_config.json
      
    3. Ensure proper permissions:
      sudo chmod 755 /etc/letsencrypt/live/
      sudo chmod 755 /etc/letsencrypt/archive/
      

    Mixed content warnings

    Issue: Browser shows “Not Secure” despite SSL certificate Solution: Update site URL in site config:
    bench --site mysite.com set-config host_name "https://mysite.com"
    
    Clear cache:
    bench --site mysite.com clear-cache
    

    Certificate renewal fails

    Issue: Automatic renewal fails Solutions:
    1. Check Certbot logs:
      sudo cat /var/log/letsencrypt/letsencrypt.log
      
    2. Test renewal in dry-run mode:
      sudo certbot renew --dry-run
      
    3. Manually renew:
      sudo certbot renew --force-renewal
      sudo systemctl reload nginx
      

    NGINX fails to reload

    Issue: NGINX configuration test fails Solution:
    1. Test configuration:
      sudo nginx -t
      
    2. Check for syntax errors in nginx.conf:
      cat config/nginx.conf
      
    3. Regenerate configuration:
      bench setup nginx
      
    4. Check NGINX error log:
      sudo tail -f /var/log/nginx/error.log
      

    Custom ACME Server

    For staging or alternative ACME servers:
    sudo bench setup lets-encrypt mysite.com --custom-server https://acme-staging-v02.api.letsencrypt.org/directory
    

    SSL Best Practices

    1
    Always use HTTPS
    2
    Force HTTPS redirect in site config:
    3
    {
      "host_name": "https://mysite.com"
    }
    
    4
    Keep certificates renewed
    5
    Monitor certificate expiry and renewal logs:
    6
    sudo tail -f /var/log/letsencrypt/letsencrypt.log
    
    7
    Use strong cipher suites
    8
    Customize NGINX SSL configuration in config/nginx.conf (advanced):
    9
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;
    
    10
    Test regularly
    11
    Periodically test SSL configuration:
    13
    Monitor certificate expiry
    14
    Set up monitoring alerts for certificates expiring soon.

    Next Steps

    Build docs developers (and LLMs) love