22
33For traditional Linux server deployments (Ubuntu/Debian), we recommend running the application with Gunicorn managed by Systemd, and using Nginx as a reverse proxy.
44
5- ## 1. Systemd Service
5+ ## Prerequisites
66
7- Create a service file to keep the application running.
7+ - Python 3.11 (install via ` apt ` or ` pyenv ` )
8+ - PostgreSQL 14+
9+ - Redis 6+
10+ - Nginx
811
9- ** /etc/systemd/system/jasmin-web.service**
12+ ### Install Python 3.11
13+
14+ === "Ubuntu"
15+
16+ ```bash
17+ sudo apt update
18+ sudo apt install -y software-properties-common
19+ sudo add-apt-repository ppa:deadsnakes/ppa -y
20+ sudo apt update
21+ sudo apt install -y python3.11 python3.11-venv python3.11-dev
22+ ```
23+
24+ === "Debian"
25+
26+ The `deadsnakes` PPA is not available on Debian. Use `pyenv` to install Python 3.11:
27+
28+ ```bash
29+ # Install pyenv dependencies
30+ sudo apt update
31+ sudo apt install -y build-essential libssl-dev zlib1g-dev \
32+ libbz2-dev libreadline-dev libsqlite3-dev curl git \
33+ libncursesw5-dev xz-utils tk-dev libxml2-dev libxmlsec1-dev libffi-dev liblzma-dev
34+
35+ # Install pyenv
36+ curl https://pyenv.run | bash
37+
38+ # Add to shell profile (~/.bashrc or ~/.profile)
39+ echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc
40+ echo 'command -v pyenv >/dev/null || export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc
41+ echo 'eval "$(pyenv init -)"' >> ~/.bashrc
42+ source ~/.bashrc
43+
44+ # Install and set Python 3.11
45+ pyenv install 3.11
46+ pyenv global 3.11
47+ ```
48+
49+ ## 1. Application Setup
50+
51+ ``` bash
52+ # Clone the project
53+ sudo mkdir -p /opt/jasmin-web-panel
54+ cd /opt/jasmin-web-panel
55+ git clone https://github.com/101t/jasmin-web-panel.git .
56+
57+ # Create a virtual environment with Python 3.11
58+ python3.11 -m venv env
59+ source env/bin/activate
60+
61+ pip install --upgrade pip wheel uv
62+ uv pip install -r pyproject.toml --extra=prod
63+ ```
64+
65+ ### Configure Environment
66+
67+ ``` bash
68+ cp sample.env .env
69+ # Edit .env and set SECRET_KEY, PRODB_URL, REDIS_HOST, TELNET_HOST, etc.
70+ nano .env
71+ ```
72+
73+ ### PostgreSQL Database Setup
74+
75+ ``` sql
76+ -- Run as the postgres superuser
77+ sudo - u postgres psql
78+
79+ CREATE USER jasmin_user WITH PASSWORD ' strong_password_here' ;
80+ CREATE DATABASE jasmin_db OWNER jasmin_user;
81+ \c jasmin_db
82+ GRANT USAGE, CREATE ON SCHEMA public TO jasmin_user;
83+ \q
84+ ```
85+
86+ Set ` PRODB_URL ` in your ` .env ` :
87+
88+ ``` dotenv
89+ PRODB_URL=postgres://jasmin_user:strong_password_here@localhost:5432/jasmin_db
90+ ```
91+
92+ ### Database Migrations
93+
94+ ``` bash
95+ source env/bin/activate
96+ export DJANGO_SETTINGS_MODULE=config.settings.pro
97+
98+ python manage.py migrate
99+ python manage.py createsuperuser
100+ python manage.py collectstatic --noinput
101+ ```
102+
103+ !!! tip "Migration troubleshooting"
104+ If you see ` permission denied for schema public ` , connect to PostgreSQL and run:
105+ ```sql
106+ GRANT ALL ON SCHEMA public TO jasmin_user;
107+ ALTER SCHEMA public OWNER TO jasmin_user;
108+ ```
109+
110+ ### Set Permissions
111+
112+ ``` bash
113+ sudo chown -R www-data:www-data /opt/jasmin-web-panel
114+ sudo chmod -R 750 /opt/jasmin-web-panel
115+ sudo mkdir -p /opt/jasmin-web-panel/logs
116+ sudo chown www-data:www-data /opt/jasmin-web-panel/logs
117+ ```
118+
119+ ## 2. Systemd Services
120+
121+ ### Web Application Service
122+
123+ Create ** /etc/systemd/system/jasmin-web.service** :
10124
11125``` ini
12126[Unit]
13127Description =Jasmin Web Panel
14128Requires =postgresql.service
15- After =network.target postgresql.service
129+ After =network.target postgresql.service redis-server.service
16130
17131[Service]
18132Type =simple
19133User =www-data
20134Group =www-data
21135WorkingDirectory =/opt/jasmin-web-panel
22136Environment =" DJANGO_SETTINGS_MODULE=config.settings.pro"
23- # Ensure you have your virtualenv path correct
24137ExecStart =/opt/jasmin-web-panel/env/bin/gunicorn \
25138 --bind 127.0.0.1:8000 \
26139 --workers 4 \
@@ -36,21 +149,56 @@ RestartSec=10
36149WantedBy =multi-user.target
37150```
38151
39- Enable and start the service:
152+ ### Celery Worker Service
153+
154+ Create ** /etc/systemd/system/jasmin-celery.service** :
155+
156+ ``` ini
157+ [Unit]
158+ Description =Jasmin Web Panel Celery Worker
159+ Requires =redis-server.service
160+ After =network.target redis-server.service
161+
162+ [Service]
163+ Type =simple
164+ User =www-data
165+ Group =www-data
166+ WorkingDirectory =/opt/jasmin-web-panel
167+ Environment =" DJANGO_SETTINGS_MODULE=config.settings.pro"
168+ ExecStart =/opt/jasmin-web-panel/env/bin/celery \
169+ -A config worker \
170+ --max-tasks-per-child 1 \
171+ -l info \
172+ --logfile /opt/jasmin-web-panel/logs/celery.log
173+ Restart =on-failure
174+ RestartSec =10
175+
176+ [Install]
177+ WantedBy =multi-user.target
178+ ```
179+
180+ Enable and start both services:
40181
41182``` bash
42183sudo systemctl daemon-reload
43- sudo systemctl enable jasmin-web
44- sudo systemctl start jasmin-web
184+ sudo systemctl enable jasmin-web jasmin-celery
185+ sudo systemctl start jasmin-web jasmin-celery
186+ sudo systemctl status jasmin-web jasmin-celery
45187```
46188
47- ## 2 . Nginx Configuration
189+ ## 3 . Nginx Configuration
48190
49191Configure Nginx to proxy requests to Gunicorn and serve static files.
50192
51- ** /etc/nginx/sites-available/jasmin_web**
193+ Create ** /etc/nginx/sites-available/jasmin_web** :
52194
53195``` nginx
196+ # Map $http_upgrade to correctly handle WebSocket and regular HTTP connections
197+ map $http_upgrade $connection_upgrade {
198+ default upgrade;
199+ '' close;
200+ }
201+
54202upstream jasmin_web {
55203 server 127.0.0.1:8000;
56204}
@@ -61,36 +209,80 @@ server {
61209
62210 client_max_body_size 20M;
63211
64- # Static Files
212+ # Security headers
213+ add_header X-Frame-Options "SAMEORIGIN" always;
214+ add_header X-Content-Type-Options "nosniff" always;
215+ add_header X-XSS-Protection "1; mode=block" always;
216+ add_header Referrer-Policy "strict-origin-when-cross-origin" always;
217+
218+ # Static files
65219 location /static/ {
66220 alias /opt/jasmin-web-panel/public/static/;
67221 expires 30d;
222+ add_header Cache-Control "public, immutable";
223+ access_log off;
68224 }
69225
70- # Proxy to Django
226+ # Media files (if applicable)
227+ location /media/ {
228+ alias /opt/jasmin-web-panel/public/media/;
229+ expires 7d;
230+ access_log off;
231+ }
232+
233+ # Proxy to Gunicorn
71234 location / {
72235 proxy_pass http://jasmin_web;
73- proxy_set_header Host $host;
236+ proxy_http_version 1.1;
237+ proxy_set_header Host $http_host;
74238 proxy_set_header X-Real-IP $remote_addr;
75239 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
76240 proxy_set_header X-Forwarded-Proto $scheme;
241+ proxy_redirect off;
242+ proxy_connect_timeout 60s;
243+ proxy_read_timeout 60s;
244+
245+ # WebSocket support (if needed)
246+ proxy_set_header Upgrade $http_upgrade;
247+ proxy_set_header Connection $connection_upgrade;
77248 }
78249}
79250```
80251
81- Enable the site:
252+ Enable the site and reload Nginx :
82253
83254``` bash
84255sudo ln -s /etc/nginx/sites-available/jasmin_web /etc/nginx/sites-enabled/
85256sudo nginx -t
86257sudo systemctl reload nginx
87258```
88259
89- ## 3 . SSL ( Certbot)
260+ ## 4 . SSL with Certbot
90261
91- Secure your panel with HTTPS:
262+ Secure your panel with HTTPS (free certificate from Let's Encrypt) :
92263
93264``` bash
94- sudo apt install certbot python3-certbot-nginx
265+ sudo apt install -y certbot python3-certbot-nginx
95266sudo certbot --nginx -d sms.yourdomain.com
267+ # Auto-renewal is configured automatically by certbot
268+ sudo systemctl status certbot.timer
96269```
270+
271+ After obtaining a certificate, Certbot updates your Nginx config to redirect HTTP → HTTPS automatically.
272+
273+ ## 5. Verify the Deployment
274+
275+ ``` bash
276+ # Check service status
277+ sudo systemctl status jasmin-web
278+ sudo systemctl status jasmin-celery
279+
280+ # Tail application logs
281+ sudo tail -f /opt/jasmin-web-panel/logs/gunicorn.log
282+ sudo tail -f /opt/jasmin-web-panel/logs/gunicorn_error.log
283+
284+ # Test Nginx config
285+ sudo nginx -t
286+ ```
287+
288+ Access the panel at ` http://sms.yourdomain.com ` (or ` https:// ` after SSL setup).
0 commit comments