Quick Answer: Install:
sudo bash -c "$(curl -sL https://github.com/Gozargah/Marzban/raw/main/script.sh)" @ install. Access panel athttps://your-ip:8443/dashboard. Create admin, add inbounds (VLESS+Reality, VMess+WS, etc.), create users, share subscription links. Marzban handles everything through a clean web UI.
Need a VPS? Vultr (free credit), DigitalOcean ($200 free credit), or RackNerd (cheap annual deals).
What Is Marzban?
Marzban is a modern, open-source proxy management panel built on top of Xray-core. It provides a clean web UI for managing proxy servers, users, and subscriptions — similar to 3X-UI but with a different architecture and feature set.
What It Does
- Web dashboard — manage everything from a browser
- Multi-protocol — VLESS, VMess, Trojan, Shadowsocks in one panel
- Reality support — VLESS+Reality for maximum DPI resistance
- User management — create users with data limits, expiry dates, connection limits
- Subscription links — each user gets a URL that auto-updates their client configs
- Multi-server (Nodes) — one panel controls multiple VPS servers
- Telegram bot — create users, check stats, get notifications from your phone
- REST API — automate everything programmatically
- Docker-based — clean install, easy updates, no dependency conflicts
Marzban vs 3X-UI
| Feature | Marzban | 3X-UI |
|---|---|---|
| Architecture | Docker + API-first | Single binary |
| UI | Modern React dashboard | Classic web UI |
| User management | Centralized (one user = all protocols) | Per-inbound users |
| Subscription links | Built-in, auto-format for all clients | Built-in |
| Multi-server | Native "Node" system | Manual setup |
| Telegram bot | Built-in | Built-in |
| Hysteria2 | Supported (bundled binary) | Supported (bundled binary) |
| API | Full REST API | Limited API |
| Install method | Docker Compose | Shell script |
| Resource usage | Higher (Docker overhead) | Lower |
| Best for | Multi-server operators, API users | Single server, simpler setups |
Choose Marzban when: You manage multiple servers, need API access, want centralized user management across protocols, or prefer a modern UI.
Choose 3X-UI when: You run a single server, want lower resource usage, or prefer simpler setup.
Note: This guide covers Marzban v0.5+. Check your version with
marzban --version.
How Marzban Works
Users (phone/laptop)
|
| Connect via proxy link or subscription
|
v
Marzban Panel (your VPS)
├── Xray-core (handles all proxy protocols)
├── Web Dashboard (manage users, view stats)
├── REST API (automation)
├── Subscription endpoint (auto-update client configs)
└── Telegram bot (remote management)
Key concept: In Marzban, you create inbounds (protocol configurations like VLESS+Reality on port 443) and then create users who can connect to ANY inbound. This is different from 3X-UI where users are tied to specific inbounds.
Marzban approach:
Inbound 1: VLESS+Reality :443
Inbound 2: VMess+WS :2083 → User "alice" can use ALL of these
Inbound 3: Trojan+WS :2087 → User "bob" can use ALL of these
3X-UI approach:
Inbound 1: VLESS+Reality :443 → alice1 (separate user)
Inbound 2: VMess+WS :2083 → alice2 (separate user for same person)
This makes user management much simpler when you run multiple protocols.
Part 1: Install Marzban
Prerequisites
# Update system
sudo apt update && sudo apt upgrade -y
# Install Docker (if not installed)
curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker $USER
Install
sudo bash -c "$(curl -sL https://github.com/Gozargah/Marzban/raw/main/script.sh)" @ install
The installer:
- Downloads Marzban Docker images
- Sets up Docker Compose
- Creates config files at
/opt/marzban/ - Starts the panel
Create Admin Account
marzban cli admin create --sudo
Enter a username and password. This is your panel login.
Access the Dashboard
Open your browser: https://YOUR_SERVER_IP:8443/dashboard
Accept the self-signed certificate warning (we'll set up proper SSL later).
Log in with the admin credentials you just created.
Part 2: Get a TLS Certificate
For production use, you need a real SSL certificate:
# Install certbot
sudo apt install certbot -y
# Get certificate (stop Marzban first to free port 80)
marzban down
sudo certbot certonly --standalone -d panel.yourdomain.com
marzban up
Configure Marzban to Use the Certificate
Edit /opt/marzban/.env:
UVICORN_SSL_CERTFILE=/etc/letsencrypt/live/panel.yourdomain.com/fullchain.pem
UVICORN_SSL_KEYFILE=/etc/letsencrypt/live/panel.yourdomain.com/privkey.pem
Important: You also need to add the certificate path as a volume mount in Marzban's docker-compose.yml:
volumes:
- /etc/letsencrypt:/etc/letsencrypt:ro
Then restart:
marzban restart
Auto-renew certificates (they expire in 90 days):
(crontab -l 2>/dev/null; echo '0 3 * * * certbot renew --quiet --deploy-hook "cd /opt/marzban && docker compose restart"') | crontab -
Now access at https://panel.yourdomain.com:8443/dashboard with a valid certificate.
Part 3: Configure Inbounds (Protocols)
Inbounds define which proxy protocols your server offers. Go to Dashboard → Settings → Inbound Settings (or edit the Xray config directly).
VLESS + Reality (Recommended — Best DPI Resistance)
This is the most censorship-resistant TCP protocol. Traffic looks like a legitimate HTTPS connection to a real website.
In Dashboard → Xray Configuration, add this inbound:
{
"tag": "VLESS-Reality",
"listen": "0.0.0.0",
"port": 443,
"protocol": "vless",
"settings": {
"clients": [],
"decryption": "none"
},
"streamSettings": {
"network": "tcp",
"tcpSettings": {},
"security": "reality",
"realitySettings": {
"show": false,
"dest": "www.yahoo.com:443",
"xver": 0,
"serverNames": ["www.yahoo.com"],
"privateKey": "YOUR_PRIVATE_KEY",
"shortIds": ["abcd1234"]
}
},
"sniffing": {
"enabled": true,
"destOverride": ["http", "tls", "quic"]
}
}
Generate Reality keys:
docker exec marzban-marzban-1 xray x25519
# Output: Private key and Public key
# Use Private key in server config
# Users need Public key in their client
VLESS + WebSocket (For Cloudflare CDN)
Use this when you want to hide your server IP behind Cloudflare:
{
"tag": "VLESS-WS",
"listen": "0.0.0.0",
"port": 2083,
"protocol": "vless",
"settings": {
"clients": [],
"decryption": "none"
},
"streamSettings": {
"network": "ws",
"wsSettings": {
"path": "/vless-ws"
},
"security": "none"
},
"sniffing": {
"enabled": true,
"destOverride": ["http", "tls"]
}
}
Then put Cloudflare in front with orange cloud enabled. Cloudflare handles TLS.
For finding clean Cloudflare IPs: cfray Guide
VMess + WebSocket (Legacy — Wide Client Support)
{
"tag": "VMess-WS",
"listen": "0.0.0.0",
"port": 2087,
"protocol": "vmess",
"settings": {
"clients": []
},
"streamSettings": {
"network": "ws",
"wsSettings": {
"path": "/vmess-ws"
},
"security": "none"
}
}
Trojan + WebSocket
{
"tag": "Trojan-WS",
"listen": "0.0.0.0",
"port": 2096,
"protocol": "trojan",
"settings": {
"clients": []
},
"streamSettings": {
"network": "ws",
"wsSettings": {
"path": "/trojan-ws"
},
"security": "none"
}
}
Shadowsocks 2022
{
"tag": "Shadowsocks",
"listen": "0.0.0.0",
"port": 8388,
"protocol": "shadowsocks",
"settings": {
"clients": [],
"network": "tcp,udp",
"method": "2022-blake3-aes-128-gcm"
}
}
Open Firewall
sudo ufw allow 443/tcp # VLESS+Reality
sudo ufw allow 2083/tcp # VLESS+WS (CDN)
sudo ufw allow 2087/tcp # VMess+WS
sudo ufw allow 2096/tcp # Trojan+WS
sudo ufw allow 8388/tcp # Shadowsocks
sudo ufw allow 8443/tcp # Marzban dashboard
Part 4: User Management
Create a User
Dashboard → Users → Add User:
| Field | Description |
|---|---|
| Username | Unique identifier (e.g., "alice") |
| Data Limit | Total bandwidth quota (e.g., 10 GB, 50 GB, unlimited) |
| Expiry Date | When access expires |
| Protocols | Which inbounds the user can access (all by default) |
Click Create — the user gets a unique UUID that works across all configured inbounds.
Subscription Link
Every user automatically gets a subscription URL:
https://panel.yourdomain.com:8443/sub/USER_TOKEN
Share this with the user. They paste it into their client app (v2rayNG, Hiddify, etc.) and all proxy configs auto-download and auto-update.
Subscription formats supported:
- V2Ray Base64 (v2rayNG, v2rayN)
- Clash YAML (Clash Meta, Clash Verge)
- sing-box JSON (Hiddify, sing-box)
- Outline (Shadowsocks)
The client auto-detects the correct format.
Bulk User Creation
# Via CLI
marzban cli user create --username alice --data-limit 10GB --expire 30d
marzban cli user create --username bob --data-limit 50GB --expire 90d
# Via API (for automation)
curl -X POST https://panel.yourdomain.com:8443/api/user \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"username": "charlie", "data_limit": 10737418240, "expire": 1798761600}'
User Monitoring
The dashboard shows for each user:
- Current data usage vs limit
- Days remaining until expiry
- Active connections (online/offline)
- Last connection time
- Per-protocol usage breakdown
Part 5: Telegram Bot
Marzban has a built-in Telegram bot for remote management.
Setup
- Create a bot with @BotFather on Telegram — get the bot token
- Edit
/opt/marzban/.env:
TELEGRAM_API_TOKEN=your-bot-token-here
TELEGRAM_ADMIN_ID=your-telegram-user-id
Get your Telegram user ID from @userinfobot.
- Restart:
marzban restart
Bot Commands
| Command | What It Does |
|---|---|
| Create user | Interactive wizard with limits |
| User info | Data usage, expiry, status |
| Delete user | Remove access |
| System status | Server load, connections, bandwidth |
| User list | All users with stats |
The bot also sends automatic notifications:
- User expired
- User hit data limit
- Server down/up
- High resource usage
Part 6: Multi-Server (Nodes)
Marzban's killer feature: run one panel that controls multiple VPS servers.
Marzban Panel (main VPS)
|
├── Node 1 (VPS in Germany)
├── Node 2 (VPS in Netherlands)
└── Node 3 (VPS in US)
Users connect to ANY node using the same subscription link.
If one node gets blocked, they automatically switch to another.
Add a Node
On the Node VPS:
# Install Marzban-node
sudo bash -c "$(curl -sL https://github.com/Gozargah/Marzban-node/raw/main/script.sh)" @ install
On the Panel:
- Dashboard → Nodes → Add Node
- Enter the Node server IP and port
- Copy the certificate from the panel to the node
- The node connects and starts accepting traffic
Why Nodes Matter
- Redundancy — if one server gets blocked, others still work
- Geographic diversity — servers in different countries
- Load distribution — spread traffic across servers
- One subscription — users get all nodes in one link, clients auto-select the best
Part 7: Cloudflare CDN Integration
Hide your server IP behind Cloudflare:
Setup
- Add your domain to Cloudflare (free plan)
- Create A record pointing to your VPS IP — orange cloud ON
- Use VLESS+WS or VMess+WS inbound (NOT Reality — Reality doesn't work with CDN)
- Set Cloudflare SSL to Full
Ports
Cloudflare only proxies these HTTPS ports:
- 443, 2053, 2083, 2087, 2096, 8443
Your WS inbounds should use one of these ports.
Clean IPs
If Cloudflare IPs are throttled in your region, use cfray to find working ones. Users set the clean IP in their client instead of the domain.
Part 8: Configuration Files
Main Config: /opt/marzban/.env
# Dashboard
UVICORN_HOST=0.0.0.0
UVICORN_PORT=8443
# SSL
UVICORN_SSL_CERTFILE=/etc/letsencrypt/live/panel.yourdomain.com/fullchain.pem
UVICORN_SSL_KEYFILE=/etc/letsencrypt/live/panel.yourdomain.com/privkey.pem
# Subscription
XRAY_SUBSCRIPTION_URL_PREFIX=https://panel.yourdomain.com:8443
# Telegram
TELEGRAM_API_TOKEN=your-bot-token
TELEGRAM_ADMIN_ID=your-telegram-id
# Database (default: SQLite, can use MySQL)
# SQLALCHEMY_DATABASE_URL = mysql+pymysql://user:pass@localhost/marzban
Xray Config: /opt/marzban/xray_config.json
This is the full Xray configuration with inbounds, outbounds, and routing. Edit through the dashboard or directly.
Part 9: Marzban CLI
marzban up # Start
marzban down # Stop
marzban restart # Restart
marzban logs # View logs
marzban update # Update to latest version
# Admin management
marzban cli admin create --sudo
marzban cli admin list
marzban cli admin delete USERNAME
# User management
marzban cli user create --username NAME
marzban cli user list
marzban cli user delete USERNAME
marzban cli user info USERNAME
Part 10: Security Hardening
Change Dashboard Port
The default 8443 is widely known. Change it in .env:
UVICORN_PORT=9443
Restrict Dashboard Access
Add firewall rules to only allow your IP:
# Only allow your IP to access the dashboard
sudo ufw allow from YOUR_IP to any port 9443
Use Fortify
Fortify auto-detects Marzban and Xray:
bash <(curl -sL https://github.com/SamNet-dev/fortify/raw/main/install.sh)
fortify
Block Abuse
Add to Xray routing in the dashboard to block spam and torrents:
{
"type": "field",
"outboundTag": "block",
"port": "25,465,587"
}
Part 11: Backup and Restore
Backup
# Backup everything
tar czf marzban-backup-$(date +%Y%m%d).tar.gz /opt/marzban/
# Or just the database (most important)
cp /opt/marzban/db.sqlite3 /backups/marzban-db-$(date +%Y%m%d).sqlite3
Restore
marzban down
tar xzf marzban-backup-20260408.tar.gz -C /
marzban up
Automate
# Daily backup at 3 AM
(crontab -l 2>/dev/null; echo "0 3 * * * cp /opt/marzban/db.sqlite3 /backups/marzban-db-\$(date +\%Y\%m\%d).sqlite3") | crontab -
Troubleshooting
# Check status
marzban logs
# Check Xray specifically
docker logs marzban-marzban-1 2>&1 | tail -30
# Check if ports are open
ss -tlnp | grep -E "443|2083|2087|8443"
# Test Xray config
docker exec marzban-marzban-1 xray run -test -c /etc/xray/config.json
| Problem | Fix | |
|---|---|---|
| Can't access dashboard | Check firewall: ufw status. Check port: `ss -tlnp \ |
grep 8443` |
| Users can't connect | Check inbound config. Check firewall opens the right ports | |
| Certificate error | Cert expired. Renew: certbot renew. Restart: marzban restart |
|
| Subscription not updating | Check XRAY_SUBSCRIPTION_URL_PREFIX in .env matches your domain |
|
| High memory usage | Normal for Docker. Minimum 1GB RAM recommended | |
| Node disconnected | Check node logs: marzban-node logs. Check network between panel and node |
|
| Telegram bot not working | Verify bot token and admin ID in .env. Restart after changes |
|
| "Xray failed to start" | Config syntax error. Check logs for the exact JSON error |
Related Guides
- 3X-UI Panel Setup — alternative panel (simpler)
- Xray Config Examples — copy-paste configs
- Xray Routing Guide — routing rules
- Proxy Client Setup — client apps for all platforms
- Hysteria2 Setup — fastest protocol (standalone)
- sing-box Setup — alternative to Xray
- Clean Cloudflare IPs — CDN bypass
- Cloudflare Setup — CDN configuration
- Bypass Internet Censorship — all methods compared
- Fortify Server Hardening — secure your server
- Complete Self-Hosting Guide — VPS basics
Related Tools
- VPN Leak Test — verify proxy works
- Port Scanner — check ports are open
- What's My IP — verify IP changed
- Speed Test — test proxy speed
- SSL Certificate Checker — verify TLS