Skip to content

Marzban on a VPS: install, SSL and VLESS Reality

Xray management panel

Category
VPN / Proxy
Hosting
VPN server
Author
Gozargah
License
AGPL-3.0
Version
0.8.4
Updated

The script is free · VPS from $2.79 per month · installs in about 7 minutes

Install over SSH

root@vps:~# sudo bash -c "$(curl -sL https://github.com/Gozargah/Marzban-scripts/raw/master/marzban.sh)" @ install

  • SystemUbuntu 24.04 · x86_64ok
  • Sourcegithub.com/Gozargah/Marzbanok
  • Version0.8.4ok
  • Port8000/tcplisten
  • Port1080/tcp/udplisten
  • Port443/tcplisten

✓ Marzban 0.8.4 installed · about 2 minutes

root@vps:~#

Install command from the library. Output is shortened and may differ on your server.

What it is

  • Xray
  • VLESS
  • REALITY
  • Subscriptions
  • Telegram bot

Marzban is a web panel for managing an Xray-based proxy server. Use it to create users, hand out subscription links and track traffic without editing Xray configs by hand.

The panel supports VMess, VLESS, Trojan and Shadowsocks, including TLS and REALITY. Each user has a traffic limit and an expiry date, and subscriptions open in V2rayNG, Sing-box, Nekoray, Clash and other clients.

On your own VPS the panel is handy if you sell VPN access or share it with a team: manage everything from the browser, the REST API or the built-in Telegram bot, and spread the load across multiple servers with Marzban Node.

  • VMess, VLESS, Trojan and Shadowsocks protocols with TLS and REALITY support
  • Traffic and time limits, including periodic ones (day, week, month)
  • Subscription links for V2Ray clients, Sing-box and Clash, plus QR codes
  • Multiple servers via Marzban Node
  • REST API, built-in Telegram bot and CLI
  • Traffic statistics and server monitoring

Who it is for

  • You give VPN access to a team or sell it: every user has their own subscription link, traffic limit and expiry.
  • You need subscriptions for V2rayNG, Sing-box, Clash and other clients, a REST API and the built-in Telegram bot.
  • Later the load will have to be spread over several servers with Marzban Node.

Recommended plan

For Marzban: at least 1 vCPU, 2 GB RAM and 10 GB NVMe.

Minimum to run
1 vCPU · 1 GB RAM · 10 GB disk
Systems
Ubuntu 22.04 · Ubuntu 24.04 · Debian 12
Virtualization
KVM on every VPS of ours

One-click install via the Telegram bot

Three steps in the bot, no command line. The bot shows progress; installation usually takes about 7 minutes.

  1. 01

    Open the bot with the button

    The install button on this page opens @ExpressHost_bot, and the bot fills in Marzban by itself.

  2. 02

    Choose a plan and OS

    The script appears at the “Скрипты” (Scripts) step automatically; then pay for the server.

  3. 03

    Get the login details

    When installation finishes, the bot sends the login details to the chat.

What the bot sets up

  • Installs Docker and Marzban (the gozargah/marzban:latest image) on Debian 12, 13 or Ubuntu 22.04, 24.04.
  • Issues a Let’s Encrypt certificate for the server domain server-name.expresshost.cloud; the panel runs over HTTPS on port 443 — https://domain/dashboard/, subscription links too.
  • Creates the “VLESS TCP REALITY” inbound on port 8443 right away, disguised as www.vk.com, and generates its private key and Short ID.
  • Does not create the admin: the ready message contains the panel address and the marzban cli admin create --sudo command — run it over SSH and set a username and password.

Installing Marzban by hand

The official script installs Docker and the marzban command. Application files go to /opt/marzban, settings to /opt/marzban/.env, data to /var/lib/marzban.

Marzban ports
PortProtocolPurpose
8000tcpWeb panel (/dashboard/), API and subscriptions
1080tcp/udpShadowsocks inbound from the default Xray config
443tcpTypically used for VLESS REALITY or TLS (configurable)
  1. 01

    Connect to the server

    The bot sends the IP and root password once the server is created.

    Code
    ssh root@SERVER_IP
  2. 02

    Run the install

    The default database is SQLite. For MySQL or MariaDB add --database mysql or --database mariadb to the command. At the end the installer shows the logs — leave them with Ctrl+C.

    Code
    sudo bash -c "$(curl -sL https://github.com/Gozargah/Marzban-scripts/raw/master/marzban.sh)" @ install
  3. 03

    Create the admin

    The command asks for the username and password to log in to the panel.

    Code
    marzban cli admin create --sudo
  4. 04

    Open the panel

    The panel listens on port 8000 but does not open by IP address: it needs a domain with SSL (https://YOUR_DOMAIN:8000/dashboard/, see the next section). To test without a domain, forward the port over SSH and open http://localhost:8000/dashboard/ — access ends when you close the terminal.

    Code
    ssh -L 8000:localhost:8000 root@SERVER_IP

Domain and SSL for the Marzban panel

Create the domain’s A record pointing to the server IP before issuing the certificate. The certificate files must be in /var/lib/marzban/certs — that is where Marzban reads them.

  1. 01

    Install socat and acme.sh

    Replace YOUR_EMAIL with your email.

    Code
    apt install curl socat -y
    curl https://get.acme.sh | sh -s email=YOUR_EMAIL
  2. 02

    Issue the certificate

    Replace YOUR_DOMAIN with your domain or subdomain. During validation acme.sh listens on port 80 itself, so the port must be free.

    Code
    export DOMAIN=YOUR_DOMAIN
    mkdir -p /var/lib/marzban/certs
    ~/.acme.sh/acme.sh \
      --issue --force --standalone -d "$DOMAIN" \
      --fullchain-file "/var/lib/marzban/certs/$DOMAIN.cer" \
      --key-file "/var/lib/marzban/certs/$DOMAIN.cer.key"
  3. 03

    Add the certificate to .env

    Add the lines to /opt/marzban/.env. Keep the panel on port 8000 or move it to 443 with UVICORN_PORT = 443 if no inbound uses that port.

    Code
    UVICORN_SSL_CERTFILE = "/var/lib/marzban/certs/YOUR_DOMAIN.cer"
    UVICORN_SSL_KEYFILE = "/var/lib/marzban/certs/YOUR_DOMAIN.cer.key"
    XRAY_SUBSCRIPTION_URL_PREFIX = https://YOUR_DOMAIN
  4. 04

    Restart Marzban

    After the restart the panel and subscriptions open over HTTPS on your domain.

    Code
    marzban restart

How to add VLESS Reality to Marzban

Marzban inbounds are the Xray config: edit it in the panel (Core Settings) or in /var/lib/marzban/xray_config.json. After a manual install it only has Shadowsocks on port 1080. REALITY needs no domain of your own.

  1. 01

    Generate the private key

    The private key stays in the server config.

    Code
    docker exec marzban-marzban-1 xray x25519
  2. 02

    Generate a Short ID

    Short ID and SpiderX are optional, but a Short ID is better set.

    Code
    openssl rand -hex 8
  3. 03

    Add the inbound in Core Settings

    Replace SITE with someone else’s busy website with TLS 1.3 and HTTP/2 whose domain is not a redirect; put names from its certificate into serverNames.

    Code
    {
      "tag": "VLESS TCP REALITY",
      "listen": "0.0.0.0",
      "port": 443,
      "protocol": "vless",
      "settings": { "clients": [], "decryption": "none" },
      "streamSettings": {
        "network": "tcp",
        "tcpSettings": {},
        "security": "reality",
        "realitySettings": {
          "show": false,
          "dest": "SITE:443",
          "xver": 0,
          "serverNames": ["SITE"],
          "privateKey": "PRIVATE_KEY",
          "shortIds": ["SHORT_ID"]
        }
      },
      "sniffing": {
        "enabled": true,
        "destOverride": ["http", "tls", "quic"]
      }
    }
  4. 04

    Check Host Settings

    This is where the inbound gets the address, port, SNI and fingerprint that go into users’ links. By default the address is the server IP.

  5. 05

    Create a user

    Add a user with the VLESS protocol, set a traffic limit and expiry, and send them the subscription link.

Updating and backing up Marzban

The important files are /var/lib/marzban (database, Xray config, certificates) and /opt/marzban (.env and docker-compose.yml). The latest release on GitHub is v0.8.4.

  1. 01

    Update Marzban

    The command updates Marzban to the latest version.

    Code
    marzban update
  2. 02

    Take a backup

    marzban backup runs a manual backup, and marzban backup-service sets up regular archives sent to Telegram.

    Code
    marzban backup

Common Marzban errors

  • The panel does not open by IP

    That is by design: without SSL the panel is reachable only through localhost. Issue a certificate for a domain or forward the port over SSH.

  • Cannot log in after installing from the bot

    The bot does not create the admin. Connect over SSH and run marzban cli admin create --sudo.

  • The certificate is not issued

    The domain’s A record must already point to the server, and port 80 must be free during validation.

  • A Reality client cannot connect

    Check dest and serverNames: a site with TLS 1.3 and H2, no redirect, serverNames from its certificate. The inbound port must be open in the firewall.

  • You need to see what is going on

    marzban status shows the containers, marzban logs the logs.

Sources

Commands and steps were checked against the official documentation on October 25, 2026. What the bot install does comes from its install script.

Marzban FAQ

Didn’t find an answer? Message @ExpressHost_SupportBot.

How many users can the plan handle?

The panel itself is lightweight; the bottleneck is bandwidth and CPU for encryption. 1 vCPU and 2 GB RAM is enough to start and for a few dozen active users. As you grow, add another server via Marzban Node.

How do I update Marzban?

Run marzban update. It pulls the new images and restarts the containers; user data is preserved.

Where is the data stored?

Application files are in /opt/marzban, settings in /opt/marzban/.env, and the database and Xray config in /var/lib/marzban. For backups there is marzban backup.

Can I use MySQL instead of SQLite?

Yes: add --database mysql or --database mariadb to the install command.

Marzban installs at checkout — in the bot.