docs: rewrite README with hdg quick start, architecture diagram, repair guide, and updated author link
This commit is contained in:
219
README.md
219
README.md
@@ -1,78 +1,177 @@
|
|||||||
# HestiaCP + Django + Gunicorn Deployment Guide
|
# HestiaCP + Django + Gunicorn — Deployment Engine
|
||||||
|
|
||||||
**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.
|
[](LICENSE)
|
||||||
|
|
||||||
Prepared by: **MohammadAmin Baranzehi**
|
A **production-grade, modular deployment engine** for running Django applications on [HestiaCP](https://hestiacp.com/) using Gunicorn (unix socket) and NGINX reverse proxy.
|
||||||
Website/Contact: [hacktube.ir](https://hacktube.ir)
|
|
||||||
Last updated: February 2026
|
> **Prepared by [MohammadAmin Baranzehi](https://amin.baranzehi.com)** — Cybersecurity & DevOps Engineer
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Features
|
## 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+
|
|
||||||
|
|
||||||
## Requirements
|
- **Smart Auto-Detection** — Automatically identifies your Django project structure:
|
||||||
- HestiaCP with NGINX proxy mode
|
- `config/wsgi.py` (modular / clean architecture)
|
||||||
- Django project in `/home/user/web/yourdomain.com/public_html/`
|
- `<project>/wsgi.py` (traditional `django-admin startproject`)
|
||||||
- Python 3.10+ and virtualenv
|
- `wsgi.py` at root (flat layout)
|
||||||
- Gunicorn installed in venv
|
- **One-Command Deployment** — Single command to deploy, configure, and start
|
||||||
|
- **Repair & Migration** — Fix previously deployed projects with `repair` command
|
||||||
|
- **Health Diagnostics** — Built-in `doctor` command with colour-coded reports
|
||||||
|
- **Security Hardened** — `--umask 007`, `ProtectSystem`, `PrivateTmp`, `NoNewPrivileges`
|
||||||
|
- **Dynamic Workers** — Auto-calculated: `(2 × CPU cores) + 1`
|
||||||
|
- **`.env` Support** — Auto-loads environment files via systemd `EnvironmentFile`
|
||||||
|
- **Static Files** — NGINX serves both `staticfiles/` and `static/` with priority matching
|
||||||
|
- **Backward Compatible** — Works with or without Python 3 on the server
|
||||||
|
|
||||||
## Step-by-Step Deployment Checklist
|
---
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
```
|
||||||
|
hestia-django-gunicorn/
|
||||||
|
├── hdg # Global CLI executable (self-installing & updating)
|
||||||
|
├── cli.py # Python CLI engine (setup, repair, doctor, update)
|
||||||
|
├── add-gunicorn-service.sh # Legacy wrapper (redirects to hdg)
|
||||||
|
├── core/ # OOP Engine (SOLID principles)
|
||||||
|
│ ├── models.py # Data models & value objects (DRY)
|
||||||
|
│ ├── interfaces.py # Abstract contracts (ISP & DIP)
|
||||||
|
│ ├── detector.py # Project structure analyser (SRP)
|
||||||
|
│ ├── service_generator.py # Systemd unit file generator (SRP)
|
||||||
|
│ ├── nginx_manager.py # NGINX template manager (SRP)
|
||||||
|
│ ├── migrator.py # Repair & upgrade engine (SRP)
|
||||||
|
│ ├── executor.py # OS command executor (LSP)
|
||||||
|
│ └── doctor.py # Health check diagnostics (SRP)
|
||||||
|
├── templates/
|
||||||
|
│ ├── django-gunicorn.tpl # NGINX HTTP template
|
||||||
|
│ └── django-gunicorn.stpl # NGINX HTTPS template
|
||||||
|
└── tests/ # Unit test suite
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Quick Start
|
||||||
|
|
||||||
|
### Prerequisites
|
||||||
|
- Ubuntu 22.04+ with HestiaCP (NGINX proxy mode)
|
||||||
|
- Domain created in HestiaCP panel
|
||||||
|
- Django project in `/home/<user>/web/<domain>/public_html/`
|
||||||
|
- Python 3.10+ with virtualenv and Gunicorn installed
|
||||||
|
|
||||||
|
### 1. One-Time Global Setup
|
||||||
|
|
||||||
|
Clone the repository anywhere (e.g. `/opt` or your home directory) and run `hdg` once:
|
||||||
|
|
||||||
### 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
|
```bash
|
||||||
sudo chown root:root /usr/local/hestia/data/templates/web/nginx/django-gunicorn.*
|
git clone https://github.com/amin-baranzehi/hestia-django-gunicorn.git
|
||||||
sudo chmod 644 /usr/local/hestia/data/templates/web/nginx/django-gunicorn.*
|
cd hestia-django-gunicorn
|
||||||
2. Apply Template in HestiaCP Panel
|
|
||||||
|
|
||||||
Go to: Web → Edit domain (e.g. example.com)
|
# Installs templates to HestiaCP and links 'hdg' globally
|
||||||
Select django-gunicorn in NGINX Template (or Proxy Template)
|
sudo ./hdg install-templates
|
||||||
Click Save
|
```
|
||||||
Force rebuild (recommended):Bashsudo v-rebuild-web-domain amin example.com yes
|
|
||||||
sudo systemctl restart nginx
|
|
||||||
|
|
||||||
3. Create & Start Gunicorn Service
|
> **Note:** `hdg` automatically installs itself to `/usr/local/bin/hdg` (and `/usr/local/bin/v-django`). From now on, you can run `hdg` from **ANY** directory on your server!
|
||||||
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
|
|
||||||
|
|
||||||
Service status:Bashsudo systemctl status gunicorn-example.com
|
### 2. Apply Template in HestiaCP Panel
|
||||||
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
|
|
||||||
|
|
||||||
5. Test & Monitor
|
1. Go to **Web → Edit Domain** (e.g. `example.com`)
|
||||||
|
2. Select **`django-gunicorn`** in NGINX / Proxy Template dropdown
|
||||||
|
3. Click **Save**
|
||||||
|
|
||||||
Open: https://example.com
|
### 3. Deploy from ANY Directory
|
||||||
Real-time Gunicorn logs:Bashjournalctl -u gunicorn-example.com -f
|
|
||||||
NGINX logs:Bashtail -f /var/log/nginx/error.log
|
|
||||||
|
|
||||||
Quick Fixes
|
```bash
|
||||||
|
# Super fast — auto-detects WSGI, venv, and .env:
|
||||||
|
sudo hdg example.com amin
|
||||||
|
|
||||||
502 Bad Gateway → Check socket permissions + rebuild domain
|
# Or with explicit setup keyword:
|
||||||
Readonly database → chown/chmod db.sqlite3
|
sudo hdg setup example.com amin
|
||||||
Default page shows → mv index.html index.html.bak
|
```
|
||||||
Template not in list → Force rebuild + logout/login panel
|
|
||||||
|
|
||||||
Important Notes
|
### 4. Verify & Diagnostics
|
||||||
|
|
||||||
Set DEBUG = False in production
|
```bash
|
||||||
After code changes: git pull → collectstatic → migrate → restart gunicorn
|
sudo hdg doctor example.com amin
|
||||||
For new domains: Repeat steps 2–5 only (templates stay forever)
|
```
|
||||||
|
|
||||||
Enjoy your stable Django setup! 🚀
|
---
|
||||||
Prepared with ❤️ by MohammadAmin Baranzehi
|
|
||||||
https://hacktube.ir
|
## Self-Updating
|
||||||
|
|
||||||
|
Whenever a new version is released, update your installation with a single command from anywhere:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo hdg update
|
||||||
|
```
|
||||||
|
|
||||||
|
This will:
|
||||||
|
1. Pull the latest code from git
|
||||||
|
2. Update NGINX templates in HestiaCP
|
||||||
|
3. Refresh global symlinks
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Repairing Previously Deployed Projects
|
||||||
|
|
||||||
|
If you deployed projects before and they have issues (502 errors, socket permissions, wrong WSGI module), `repair` fixes everything:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo hdg repair example.com amin
|
||||||
|
```
|
||||||
|
|
||||||
|
**What `repair` does:**
|
||||||
|
1. Reads the existing systemd service file and creates a timestamped backup
|
||||||
|
2. Re-detects your project structure (modular `config/` vs traditional vs flat)
|
||||||
|
3. Regenerates a hardened service file with `--umask 007`
|
||||||
|
4. Fixes `db.sqlite3` and static file permissions
|
||||||
|
5. Restarts Gunicorn and rebuilds NGINX configuration
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Commands Reference
|
||||||
|
|
||||||
|
| Command | Description |
|
||||||
|
| :--- | :--- |
|
||||||
|
| `hdg <domain> <user>` | Fast deploy (auto-detects project structure) |
|
||||||
|
| `hdg setup <domain> <user>` | Standard deploy |
|
||||||
|
| `hdg repair <domain> <user>` | Repair/upgrade an existing deployment |
|
||||||
|
| `hdg doctor <domain> <user>` | Run health diagnostics |
|
||||||
|
| `hdg update` | Self-update to latest version from git |
|
||||||
|
| `hdg install-templates` | Install NGINX templates to HestiaCP |
|
||||||
|
| `hdg status <domain>` | Show Gunicorn service status |
|
||||||
|
| `hdg install` | Re-link global commands in `/usr/local/bin` |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Django Settings Required for Production (HTTPS)
|
||||||
|
|
||||||
|
Add these to your `settings.py` when deploying behind NGINX with SSL:
|
||||||
|
|
||||||
|
```python
|
||||||
|
# Trust the X-Forwarded-Proto header from NGINX (prevents CSRF 403 errors)
|
||||||
|
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
|
||||||
|
USE_X_FORWARDED_HOST = True
|
||||||
|
|
||||||
|
# CSRF trusted origins
|
||||||
|
CSRF_TRUSTED_ORIGINS = ['https://yourdomain.com']
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
| Issue | Solution |
|
||||||
|
| :--- | :--- |
|
||||||
|
| **502 Bad Gateway** | Run `sudo python3 cli.py repair domain user` |
|
||||||
|
| **CSRF 403 Forbidden** | Add `SECURE_PROXY_SSL_HEADER` to settings.py |
|
||||||
|
| **Readonly database** | `sudo chown user:www-data db.sqlite3 && sudo chmod 664 db.sqlite3` |
|
||||||
|
| **Default page showing** | `mv public_html/index.html public_html/index.html.bak` |
|
||||||
|
| **Static files 404** | Run `python manage.py collectstatic --noinput` |
|
||||||
|
| **Template not in panel** | Run `sudo v-rebuild-web-domain user domain yes` |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
MIT License — see [LICENSE](LICENSE) for details.
|
||||||
|
|
||||||
|
**Prepared with ❤️ by [MohammadAmin Baranzehi](https://amin.baranzehi.com)**
|
||||||
|
|||||||
Reference in New Issue
Block a user