A modern, feature-rich web interface for managing Jasmin SMS Gateway
Features β’ Quick Start β’ Installation β’ Docker β’ Support
- Overview
- Features
- Prerequisites
- Quick Start
- Installation
- Configuration
- Production Deployment
- Submit Log Integration
- Default Credentials
- Troubleshooting
- Support
Jasmin Web Panel is a comprehensive web-based management interface for Jasmin SMS Gateway. Built with Django and modern web technologies, it provides an intuitive dashboard to configure, monitor, and manage your SMS operations efficiently.
flowchart LR
user(["You<br/>browser or API client"])
panel["<b>Jasmin Web Panel</b><br/>pages + REST API"]
jcli["<b>Jasmin gateway</b><br/>jcli console :8990"]
smsc(["SMSC providers<br/>and your apps"])
mq{{"RabbitMQ"}}
db[("Panel database")]
user -- "(1) use the panel" --> panel
panel -- "(2) jcli commands over telnet<br/>(add user, create route, ...)" --> jcli
jcli -- "(3) answer: OK or error message" --> panel
jcli -. "SMS traffic never passes<br/>through the panel" .- smsc
jcli -- "delivery results" --> mq
mq -- "sms_logger" --> db
panel -- "Submit Log page reads" --> db
How the panel and the gateway talk:
- You use the panel in the browser (or call its REST API).
- For every action (add a user, create a route, start a connector) the panel opens a telnet session to Jasmin's
jcli console on port
8990and types the same commands an administrator would, then runspersistso the change survives a restart. - Jasmin answers; the panel shows the result, or Jasmin's own error message if the command was refused.
The panel only manages the gateway. Your SMS traffic flows through Jasmin's SMPP server and HTTP API and never
passes through the panel. For the Submit Log, Jasmin publishes delivery results to RabbitMQ and the sms_logger
service stores them in the panel's database, which the Submit Log page reads.
- π Dashboard: Real-time statistics and system health monitoring
- π₯ User Management: Create and manage users with role-based access control
- π‘ SMPP Connectors: Configure and monitor SMPP client/server connections
- π HTTP API: Manage HTTP connectors for sending SMS via REST API
- π Message Routing: Define routing rules and filters for message delivery
- π¨ MO/MT Routers: Configure Mobile Originated and Mobile Terminated message routing
- π Submit Logs: Comprehensive message tracking with advanced search and filtering
- Search by Message ID, Source/Destination address, UID, and content
- Filter by status: Success (
ESME_ROK,ESME_RINVNUMDESTS), Failed (ESME_RDELIVERYFAILURE), Unknown - Real-time statistics with color-coded status badges
- π Service Monitoring: Monitor Jasmin gateway service health
- π Real-time Status: Live SMPP connector status monitoring
- π§ RESTful API: Programmatic access to all management functions
- β‘ Rate Limiting: Configure throughput limits per user/connector
- π Multi-tenancy: Manage multiple clients/users
- π Audit Logging: Track all administrative actions
- π Internationalization: Multi-language support ready
- π± Responsive Design: Mobile-friendly interface
- Jasmin SMS Gateway: v0.9+ installed and running
- Python: 3.11 or 3.12 (both tested in CI; the Docker image uses 3.12)
- telnet client: the panel drives Jasmin's jcli through the
telnetcommand (apt install telnet; already in the Docker image) - Database: PostgreSQL 12+ (recommended) or MySQL 8.0+
- Redis: 6.0+ (for caching and Celery)
- RabbitMQ: 3.10+ (used by Jasmin and the submit-log consumer)
- OS: Linux (Ubuntu 20.04+, Debian 11+, CentOS 8+)
- RAM: Minimum 2GB (4GB+ recommended for production)
- Disk: 10GB+ free space
- Network: Connectivity to Jasmin telnet interface (default: port 8990)
# Clone the repository
git clone https://github.com/101t/jasmin-web-panel.git
cd jasmin-web-panel
# Copy and configure environment file
cp sample.env .env
# Edit .env: at least set SECRET_KEY, and change the default passwords for production
# Start all services
docker compose up -d
# Access the web interface
open http://localhost:8999Default credentials: admin / secret
# Clone repository
git clone https://github.com/101t/jasmin-web-panel.git
cd jasmin-web-panel
# Create virtual environment (recommended)
python3 -m venv env
source env/bin/activate # On Windows: env\Scripts\activate
# Upgrade pip and install build tools
pip install --upgrade pip wheel uv
# Install dependencies
uv pip install -r pyproject.toml --extra=prod# Copy sample environment file
cp sample.env .env
# Edit .env with your configuration
nano .env # or use your preferred editorEssential configuration:
# Django Settings
DEBUG=False # Always False in production; set True for local development
SECRET_KEY=your-very-long-random-secret-key-here
ALLOWED_HOSTS=yourdomain.com,www.yourdomain.com
# Database
PRODB_URL=postgres://username:password@localhost:5432/jasmin_web_db
# Jasmin Gateway Connection
TELNET_HOST=127.0.0.1
TELNET_PORT=8990
TELNET_USERNAME=jcliadmin
TELNET_PW=jclipwd
TELNET_TIMEOUT=10
# Redis for Cache & Celery
REDIS_HOST=redis
REDIS_PORT=6379
REDIS_DB=0
REDIS_PASSWORD=<Optional>
# Submit Log Feature
SUBMIT_LOG=TrueNote: If you are using PostgreSQL 15 or newer, the
CREATEprivilege on thepublicschema is no longer granted to all users by default. Run the following commands as a PostgreSQL superuser to create the application database and grant the required permissions.
-- Connect as a PostgreSQL superuser (e.g. psql -U postgres)
-- Replace the values below with those you set in PRODB_URL in your .env file
CREATE USER your_db_user WITH PASSWORD 'your_db_password';
CREATE DATABASE your_db_name OWNER your_db_user;
\c your_db_name
GRANT USAGE, CREATE ON SCHEMA public TO your_db_user;# Run migrations
python manage.py migrate
# Load sample data (optional)
python manage.py samples
# Collect static files
python manage.py collectstatic --no-input
# Create your own admin account (optional, "samples" already creates admin / secret)
python manage.py createsuperuserpython manage.py runserver 0.0.0.0:8000Access the application at http://localhost:8000
# Pull the latest image
docker pull tarekaec/jasmin_web_panel:3.1.0
# Configure environment
cp sample.env .env
# Edit .env with your settings
# Run container
docker run -d \
--name jasmin-web \
-p 8999:8000 \
--env-file .env \
-v ./public:/app/public \
tarekaec/jasmin_web_panel:3.1.0# Build from Dockerfile
docker build -f config/docker/slim/Dockerfile -t jasmin_web_panel:custom .
# Run your custom image
docker run -d \
--name jasmin-web \
-p 8999:8000 \
--env-file .env \
jasmin_web_panel:customFull stack deployment with all dependencies:
# Ensure .env is configured
cp sample.env .env
# Start all services
docker compose up -d
# View logs
docker compose logs -f jasmin-web
# Check service status
docker compose ps
# Stop all services
docker compose downServices included:
jasmin-web: Web application (port 8999)jasmin-celery: Background task processordb: PostgreSQL databaseredis: Redis cacherabbitmq: RabbitMQ message brokerjasmin: Jasmin SMS Gateway (ports 2775, 8990, 1401)sms_logger: SMS submit log collector
The Dockerfile builds on both amd64 and arm64 without changes:
docker build -f config/docker/slim/Dockerfile -t jasmin_web_panel:custom .| Variable | Description | Default | Required |
|---|---|---|---|
DEBUG |
Enable debug mode | False |
β |
SECRET_KEY |
Django secret key | - | β |
ALLOWED_HOSTS |
Allowed hosts | * |
β |
PRODB_URL |
PostgreSQL URL | - | β |
REDIS_HOST |
Redis host | redis |
β |
REDIS_PORT |
Redis port | 6379 |
β |
REDIS_DB |
Redis database | 0 |
β |
TELNET_HOST |
Jasmin telnet host | 127.0.0.1 |
β |
TELNET_PORT |
Jasmin telnet port | 8990 |
β |
TELNET_USERNAME |
Jasmin admin username | jcliadmin |
β |
TELNET_PW |
Jasmin admin password | jclipwd |
β |
TELNET_TIMEOUT |
Seconds to wait for a jcli answer | 10 |
β |
HTTPS_ONLY |
Secure cookies and HTTPS redirect (set when served over HTTPS) | False |
β |
CSRF_TRUSTED_ORIGINS |
Origins allowed to post forms, e.g. https://sms.example.com |
- | β |
SUBMIT_LOG |
Enable submit log tracking | False |
β |
API_THROTTLE_ANON |
API rate limit for anonymous requests | 20/minute |
β |
API_THROTTLE_USER |
API rate limit for authenticated requests | 120/minute |
β |
The configuration guide lists every variable, including the Send SMS (HTTP_*, SMPP_*) settings.
Ensure Jasmin is configured properly:
-
Enable
submit_sm_resppublishing injasmin.cfg:[sm-listener] publish_submit_sm_resp = True
-
Restart Jasmin:
systemctl restart jasmin
Create /etc/systemd/system/jasmin-web.service:
[Unit]
Description=Jasmin Web Panel
Requires=postgresql.service
After=network.target postgresql.service
[Service]
Type=simple
SyslogIdentifier=jasminwebpanel
User=www-data
Group=www-data
WorkingDirectory=/opt/jasmin-web-panel
Environment="DJANGO_SETTINGS_MODULE=config.settings.pro"
ExecStart=/opt/jasmin-web-panel/env/bin/gunicorn \
--bind 127.0.0.1:8000 \
--workers 4 \
--timeout 120 \
--log-level info \
--access-logfile /opt/jasmin-web-panel/logs/gunicorn.log \
--error-logfile /opt/jasmin-web-panel/logs/gunicorn_error.log \
config.wsgi:application
Restart=on-failure
RestartSec=10
[Install]
WantedBy=multi-user.targetThe web panel requires a Celery worker to process background tasks like report exports from Submit Logs Page.
Create /etc/systemd/system/jasmin-web-panel-celery.service:
[Unit]
Description=Jasmin Web Panel Celery Worker
After=network.target redis.service
Requires=redis.service
[Service]
Type=simple
SyslogIdentifier=jasmin-web-panel-celery
User=www-data
Group=www-data
WorkingDirectory=/opt/jasmin-web-panel
Environment="DJANGO_SETTINGS_MODULE=config.settings.pro"
Environment="CELERY_LOG_LEVEL=info"
ExecStart=/opt/jasmin-web-panel/env/bin/celery --app config worker --max-tasks-per-child 1 -l info
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.targetsudo systemctl daemon-reload
sudo systemctl enable jasmin-web.service
sudo systemctl start jasmin-web.service
sudo systemctl status jasmin-web.servicesudo systemctl daemon-reload
sudo systemctl enable jasmin-web-panel-celery.service
sudo systemctl start jasmin-web-panel-celery.service
sudo systemctl status jasmin-web-panel-celery.serviceCreate /etc/nginx/sites-available/jasmin_web:
upstream jasmin_web {
server 127.0.0.1:8000;
}
server {
listen 80;
server_name sms.yourdomain.com; # Replace with your domain
charset utf-8;
# Security headers
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
# Logging
access_log /var/log/nginx/jasmin_web_access.log combined;
error_log /var/log/nginx/jasmin_web_error.log;
# Static files
location /static/ {
alias /opt/jasmin-web-panel/public/static/;
expires 30d;
add_header Cache-Control "public, immutable";
}
# Media files
location /media/ {
alias /opt/jasmin-web-panel/public/media/;
}
# Proxy to Django
location / {
proxy_pass http://jasmin_web;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffering off;
client_max_body_size 20M;
}
}sudo ln -s /etc/nginx/sites-available/jasmin_web /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginxsudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d sms.yourdomain.comTrack all SMS messages submitted through Jasmin Gateway with detailed status information.
-
Enable in configuration:
SUBMIT_LOG=True -
Configure SMS Logger:
DB_HOST=db DB_DATABASE=jasmin DB_USER=jasmin DB_PASS=jasmin DB_TABLE=submit_log
- β Real-time Tracking: Monitor message submission and delivery status
- π Advanced Search: Search by Message ID, addresses, UID, or content
- π― Status Filtering:
- Success:
ESME_ROK,ESME_RINVNUMDESTS - Failed:
ESME_RDELIVERYFAILURE - Unknown: All other status codes
- Success:
- π Statistics Dashboard: View total, success, failed, and unknown counts
- π¨ Color-coded Badges: Visual status identification
- π Pagination: Handle large volumes efficiently
Username: admin
Password: secret
Via Web Interface:
- Log in with default credentials
- Navigate to Profile β Change Password
- Enter new secure password
Via Command Line:
python manage.py changepassword adminThis error occurs on PostgreSQL 15+ where the CREATE privilege on the public schema is no longer granted to all users by default.
Solution β connect to PostgreSQL as a superuser and run:
\c your_db_name -- connect to your application database (matches DB name in PRODB_URL)
GRANT USAGE, CREATE ON SCHEMA public TO your_db_user; -- matches DB user in PRODB_URLIf you created the database without setting the owner correctly, you can also fix it with:
ALTER DATABASE your_db_name OWNER TO your_db_user;For new Docker deployments this is handled automatically by config/docker/postgres/init.sql when the Postgres data volume is first initialized. If you already have an existing postgres_data volume, you must either run the GRANT statements above manually or recreate the Postgres volume so the init script can run.
The pages show the reason in the table, for example "Could not connect to Jasmin jcli at 127.0.0.1:8990" or "Jasmin jcli login failed, check TELNET_USERNAME and TELNET_PW".
Solutions:
- Verify Jasmin is running:
systemctl status jasmin - Check telnet connectivity:
telnet localhost 8990 - Confirm
TELNET_*settings match Jasmin configuration - Ensure firewall allows port 8990
- For manual installs, make sure the
telnetclient is installed (apt install telnet)
Solutions:
- Verify
SUBMIT_LOG=Truein.env - Check SMS Logger service:
docker compose ps sms_logger - Confirm
publish_submit_sm_resp = Trueinjasmin.cfg - Check logs:
docker compose logs sms_logger
The panel serves its static files itself (WhiteNoise) once they are collected; the Docker image does this on start.
Solutions:
python manage.py collectstatic --no-input --clear
sudo chown -R www-data:www-data /opt/jasmin-web-panel/public/
sudo nginx -t && sudo systemctl reload nginxAccounts created before this fix were saved with an unverified email, which the sign-in page refuses. Mark them verified:
python manage.py shell -c "from main.users.models import User; User.objects.filter(is_superuser=True).update(is_email=True, is_verified=True)"# Docker Compose
docker compose logs -f jasmin-web
# Systemd
sudo journalctl -u jasmin-web.service -f- Telegram: Join our community β https://t.me/jasminwebpanel
- GitHub Issues: Report bugs or request features
- Email: tarek.it.eng@gmail.com
We welcome contributions! Please read our Contributing Guide before submitting a pull request.
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature - Follow the coding standards
- Write tests for your changes
- Open a Pull Request using our PR template
Please also review our Code of Conduct and Security Policy.
This project is licensed under the MIT License. See LICENSE file for details.
Made with β€οΈ for the Jasmin SMS Gateway community