From 125ab8aee1d4bb3ec48e8742068eeb070a1acb12 Mon Sep 17 00:00:00 2001 From: MohammadAmin Baranzehi Date: Mon, 9 Feb 2026 14:38:09 +0330 Subject: [PATCH] Revise HestiaCP + Django + Gunicorn deployment guide Updated the README.md to enhance the deployment guide for HestiaCP and Django with Gunicorn, including formatting improvements and additional sections. --- README.md | 163 +++++++++++++++++++++--------------------------------- 1 file changed, 62 insertions(+), 101 deletions(-) diff --git a/README.md b/README.md index 64b452d..526fe16 100644 --- a/README.md +++ b/README.md @@ -1,117 +1,78 @@ -================================================================================ -HestiaCP + Django + Gunicorn Setup - Complete Checklist -Prepared by: MohammadAmin Baranzehi -Website / Contact: hacktube.ir -Last updated: February 09, 2026 -================================================================================ +# HestiaCP + Django + Gunicorn Deployment Guide -Prerequisites (Must be done before starting) -──────────────────────────────────────────── -□ Domain already created in HestiaCP (e.g. example.com) -□ Django project copied to: /home/amin/web/example.com/public_html/ -□ Virtualenv created and packages installed: - python3 -m venv venv - source venv/bin/activate - pip install -r requirements.txt # gunicorn must be included -□ Run collectstatic and migrate: - python manage.py collectstatic --noinput - python manage.py migrate -□ In settings.py: - - DEBUG = False (or True for initial debugging) - - ALLOWED_HOSTS includes domain (e.g. ['pexample.com', '*']) - - STATIC_URL = '/static/' - - STATIC_ROOT = BASE_DIR / 'staticfiles' +**Simple, fast and reliable way** to run Django applications on HestiaCP using Gunicorn (unix socket) and NGINX reverse proxy — without manual nginx.conf editing every time. -Stage 1 – Place Custom NGINX Templates -──────────────────────────────────────────── -□ Copy template files directly (no subfolder!) to: - /usr/local/hestia/data/templates/web/nginx/django.tpl - /usr/local/hestia/data/templates/web/nginx/django.stpl +Prepared by: **MohammadAmin Baranzehi** +Website/Contact: [hacktube.ir](https://hacktube.ir) +Last updated: February 2026 -□ Set correct permissions: - sudo chown root:root /usr/local/hestia/data/templates/web/nginx/django.* - sudo chmod 644 /usr/local/hestia/data/templates/web/nginx/django.* +## Features +- Unix socket for secure & fast communication +- Custom NGINX templates (no subfolder needed) +- One-command systemd service creation +- Static/media files served directly by NGINX +- Tested on Ubuntu 22.04 + HestiaCP 1.6.x+ -Stage 2 – Apply Template in HestiaCP Panel -──────────────────────────────────────────── -□ Log in to HestiaCP panel -□ Go to: Web → Edit domain (example.com) -□ In NGINX Template or Proxy Template section → select django -□ Click Save -□ (Strongly recommended) Force rebuild domain: - sudo v-rebuild-web-domain amin example.com yes - sudo systemctl restart nginx +## Requirements +- HestiaCP with NGINX proxy mode +- Django project in `/home/user/web/yourdomain.com/public_html/` +- Python 3.10+ and virtualenv +- Gunicorn installed in venv -Stage 3 – Create and Start Gunicorn Service -──────────────────────────────────────────── -□ Run the helper script: - add-gunicorn-service example.com user yourprojectname - (or sudo /path/to/add-gunicorn-service.sh ... if not in PATH) +## Step-by-Step Deployment Checklist -□ Restart service to apply: - sudo systemctl restart gunicorn-example.com +### 1. Place Custom NGINX Templates +Copy files **directly** (no subfolder) to: +/usr/local/hestia/data/templates/web/nginx/django-gunicorn.tpl +/usr/local/hestia/data/templates/web/nginx/django-gunicorn.stpl +textSet permissions: +```bash +sudo chown root:root /usr/local/hestia/data/templates/web/nginx/django-gunicorn.* +sudo chmod 644 /usr/local/hestia/data/templates/web/nginx/django-gunicorn.* +2. Apply Template in HestiaCP Panel -Stage 4 – Verify Service, Socket and Permissions -──────────────────────────────────────────── -□ Check service status (must be active (running)): - sudo systemctl status gunicorn.example.com +Go to: Web → Edit domain (e.g. example.com) +Select django-gunicorn in NGINX Template (or Proxy Template) +Click Save +Force rebuild (recommended):Bashsudo v-rebuild-web-domain amin example.com yes +sudo systemctl restart nginx -□ Check socket existence and permissions: - ls -l /home/amin/web/example.com/public_html/gunicorn.sock - # Expected output: srw-rw---- 1 amin www-data ... +3. Create & Start Gunicorn Service +Run: +Bashadd-gunicorn-service example.com amin yourprojectname +# Example: add-gunicorn-service panel.example.com amin zamzam +Restart: +Bashsudo systemctl restart gunicorn-example.com +4. Verify Everything -□ Fix socket permissions if wrong: - sudo chown user:www-data gunicorn.sock - sudo chmod 660 gunicorn.sock - sudo systemctl restart gunicorn.example.com +Service status:Bashsudo systemctl status gunicorn-example.com +Socket check:Bashls -l /home/amin/web/example.com/public_html/gunicorn.sock +# Expected: srw-rw---- 1 amin www-data ... +Fix socket permissions if needed:Bashsudo chown amin:www-data gunicorn.sock +sudo chmod 660 gunicorn.sock +sudo systemctl restart gunicorn-example.com +Fix db.sqlite3 permissions:Bashsudo chown amin:www-data db.sqlite3 +sudo chmod 664 db.sqlite3 -□ Fix db.sqlite3 permissions (prevents readonly database error): - ls -l db.sqlite3 - # Should be: -rw-rw-r-- 1 user www-data ... - sudo chown user:www-data db.sqlite3 - sudo chmod 664 db.sqlite3 +5. Test & Monitor -Stage 5 – Final Testing & Monitoring -──────────────────────────────────────────── -□ Open site in browser: https://example.com -□ Try login and basic functionality +Open: https://example.com +Real-time Gunicorn logs:Bashjournalctl -u gunicorn-example.com -f +NGINX logs:Bashtail -f /var/log/nginx/error.log -□ Monitor Gunicorn logs in real-time: - journalctl -u gunicorn.example.com -f +Quick Fixes -□ Monitor NGINX logs if issue occurs: - tail -f /var/log/nginx/error.log - tail -f /home/amin/web/example.com/logs/nginx.error.log # if exists +502 Bad Gateway → Check socket permissions + rebuild domain +Readonly database → chown/chmod db.sqlite3 +Default page shows → mv index.html index.html.bak +Template not in list → Force rebuild + logout/login panel -□ Optional direct socket test: - curl --unix-socket gunicorn.sock http://localhost/ +Important Notes -Quick Fixes for Common Issues -──────────────────────────────────────────── -□ 502 Bad Gateway - → Check NGINX log: tail -f /var/log/nginx/error.log - → Fix socket permissions (chmod 660 + chown) - → Rebuild domain and restart NGINX +Set DEBUG = False in production +After code changes: git pull → collectstatic → migrate → restart gunicorn +For new domains: Repeat steps 2–5 only (templates stay forever) -□ Readonly database (db.sqlite3) - → chown user:www-data db.sqlite3 && chmod 664 db.sqlite3 - -□ Default Hestia page still showing - → mv index.html index.html.bak - → sudo systemctl restart nginx - -□ Template not showing in panel - → Force rebuild: sudo v-rebuild-web-domain user yourdomain.com yes - → Logout/login panel or clear browser cache - -Important Post-Setup Notes -──────────────────────────────────────────── -□ Set DEBUG = False in production -□ Rename or remove index.html if default page appears -□ After code update: git pull → collectstatic → migrate → restart gunicorn -□ For new domains: repeat stages 2–5 only (templates are already there) - -Enjoy your stable Django setup on HestiaCP! -Prepared by: MohammadAmin Baranzehi -Website / Contact: hacktube.ir -================================================================================ +Enjoy your stable Django setup! 🚀 +Prepared with ❤️ by MohammadAmin Baranzehi +https://hacktube.ir