“Your app isn’t production until the padlock turns green.”
This guide merges the one-liner speed of the quick-start and the step-by-step clarity of the original long-form post.
Follow along and you’ll mint fresh Let’s Encrypt certificates, wire them into Dify’s Nginx, and set-and-forget auto-renewal—all in ~15 minutes.
0 Why bother?
| ✅ Win | 🚀 Why it matters | 
|---|---|
| End-to-end encryption | Keep chat sessions & API calls private. | 
| Browser trust | No more red “Not secure” labels. | 
| Free & automated | Let’s Encrypt renews every 60–90 days without a credit-card or cron anxiety. | 
1 Prerequisites
- 
Domain – A/AAAArecord → your server
- Ports – 80 & 443 open on firewall/cloud SG
- 
Docker – v24 + Compose v2 (docker compose version)
- 
Dify repo – git clone https://github.com/langgenius/dify.git && cd dify/docker
  
  
  2 Patch .env (tell Dify who it is)
# --- SSL filenames Nginx expects
NGINX_SSL_CERT_FILENAME=fullchain.pem
NGINX_SSL_CERT_KEY_FILENAME=privkey.pem
# --- Let Certbot answer ACME challenges
NGINX_ENABLE_CERTBOT_CHALLENGE=true
# --- Your domain + a real e-mail
CERTBOT_DOMAIN=dify.example.com
CERTBOT_EMAIL=ops@example.com
# --- Leave this OFF until the cert exists
NGINX_HTTPS_ENABLED=false
Got multiple sub-domains?
AddAPP_WEB_URL,APP_API_URL,CONSOLE_WEB_URL, andCONSOLE_API_URL, each withhttps://…so Dify’s front-end matches its back-end once HTTPS is live.
3 (Tidy-up) Prune stray Docker networks
Old bridges sometimes clash with the Certbot profile.
docker network prune        # hit y when asked
4 Launch the stack with the Certbot profile
docker compose --profile certbot up --force-recreate -d
| Flag | Why we need it | 
|---|---|
| --profile certbot | Starts nginx + certbot side-cars. | 
| --force-recreate | Rebuild nginx so it mounts the Let’s Encrypt volume. | 
| -d | Runs in the background (detached). | 
5 Run Certbot inside its container
docker compose exec -it certbot /bin/sh /update-cert.sh
What just happened?
- Certbot spins a micro webroot on :80.
- Let’s Encrypt validates dify.example.com.
- Keys drop into volumes/certbot/conf/live/dify.example.com/.
Expect the triumphant:
Congratulations! Your certificate and chain have been saved at:
  /etc/letsencrypt/live/dify.example.com/fullchain.pem
6 Flip the HTTPS switch
# in docker/.env
NGINX_HTTPS_ENABLED=true
7 Recreate only nginx (fast restart)
docker compose --profile certbot up -d --no-deps --force-recreate nginx
Nginx boots, finds fullchain.pem & privkey.pem, and starts serving 443.
8 Verify the green padlock
https://dify.example.com
You should see:
- 🔒 Green padlock
- Auto-redirect from http://→https://
9 Renewal in two commands (bookmark this)
Let’s Encrypt certs last 90 days. Certbot’s built-in cron renews them, but here’s the manual drill:
# 1. Force renew (safe to run anytime)
docker compose exec -it certbot /bin/sh /update-cert.sh
# 2. Hot-reload nginx to pick up the new files
docker compose exec nginx nginx -s reload
10 Troubleshooting cheat-sheet
| 🛠️ Symptom | 💡 Fix | 
|---|---|
| timeout during connect (likely firewall) | Port 80 closed or DNS not propagated. | 
| Permission deniedon/update-cert.sh | Script lost its +x bit— chmod +x /update-cert.shinside the image or rebuild. | 
| Infinite “Loading…” UI | All five *_WEB_URL/*_API_URLenv vars must match the newhttps://…URL. | 
| bind: address already in use: 0.0.0.0:80 | Another web server running—stop Apache/old Nginx or change Compose ports. | 
11 Recap (copy-paste edition)
# 0  clone repo & cd dify/docker
# 1  edit .env  → domain, e-mail, filenames
# 2  docker network prune
# 3  docker compose --profile certbot up --force-recreate -d
# 4  docker compose exec -it certbot /bin/sh /update-cert.sh
# 5  set NGINX_HTTPS_ENABLED=true in .env
# 6  docker compose --profile certbot up -d --no-deps --force-recreate nginx
Fifteen minutes, one free cert, zero recurring fees—your Dify instance is officially production-grade.
Happy shipping!
 
 
              
 
    
Top comments (0)