How to Install Marzban on Ubuntu 22.04 VPS

(Complete Setup Guide)

A clean, step-by-step guide to install Marzban on Ubuntu 22.04 with Docker, Nginx, SSL, VLESS, and VMess — without the common mistakes that break most setups.

Table of Contents

Most Marzban installs don’t fail because of complexity. They fail because of wrong setup order.

I’ve worked on multiple VPS fixes where:

The problem is not Marzban. It’s the way it’s installed.

This guide shows you how to install Marzban properly from the start so you don’t have to debug it later. It’s based on real fixes, not theory.

Tested only on Ubuntu 22.04.

What You’ll Get After This Setup

By the end, you’ll have:

Requirements

Before starting:

Prepare the Server

Run:

				
					apt update && apt upgrade -y
apt install -y curl git nginx certbot python3-certbot-nginx docker.io docker-compose
systemctl enable docker
systemctl start docker
				
			

This sets up everything Marzban depends on.

Install Marzban

				
					mkdir -p /opt/marzban
cd /opt/marzban
git clone https://github.com/Gozargah/Marzban.git .
cp .env.example .env
				
			

Edit config:

				
					nano .env
				
			

Add these lines immediately after the line that says UVICORN_PORT = 8000 near top of the file.

				
					XRAY_SUBSCRIPTION_URL_PREFIX = "https://yourdomain.com"
XRAY_VLESS_WS=true
XRAY_VLESS_WS_PATH=/vless
XRAY_VLESS_WS_HOST=yourdomain.com
				
			

Avoid over-configuring here. Most issues start in this file.

Start the service:

				
					docker-compose up -d
				
			

Create Admin User

				
					docker exec -it marzban_marzban_1 python3 /code/marzban-cli.py admin create
				
			

Follow onscreen instructions to create the admin user. You’ll need admin user to login to Marzban dashboard later.

Create Marzban Admin User

Configure Nginx (Where Most People Mess Up)

				
					nano /etc/nginx/sites-available/marzban
				
			

Paste:

				
					server {
    listen 80;
    server_name yourdomain.com;

    location / {
        proxy_pass http://127.0.0.1:8000;

        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;
    }

    location /vless {
        proxy_pass http://127.0.0.1:10000;

        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
    }

    location /vmess {
        proxy_pass http://127.0.0.1:10001;

        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
    }
}
				
			

Enable it:

				
					ln -s /etc/nginx/sites-available/marzban /etc/nginx/sites-enabled/
nginx -t
systemctl restart nginx
				
			

Enable SSL

				
					certbot --nginx -d yourdomain.com
				
			

Choose redirect → YES

Configure Core (Critical Step)

Login:

				
					https://yourdomain.com/dashboard/
				
			

Go to Core Settings, delete everything and add:

				
					{
  "log": {
    "loglevel": "warning"
  },
  "routing": {
    "rules": [
      {
        "ip": [
          "geoip:private"
        ],
        "outboundTag": "BLOCK",
        "type": "field"
      }
    ]
  },
  "inbounds": [
    {
      "tag": "Shadowsocks TCP",
      "listen": "0.0.0.0",
      "port": 1080,
      "protocol": "shadowsocks",
      "settings": {
        "clients": [],
        "network": "tcp,udp"
      }
    },
    {
      "tag": "VLESS WS",
      "listen": "127.0.0.1",
      "port": 10000,
      "protocol": "vless",
      "settings": {
        "clients": [],
        "decryption": "none"
      },
      "streamSettings": {
        "network": "ws",
        "security": "none",
        "wsSettings": {
          "path": "/vless"
        }
      }
    },
    {
      "tag": "VMess WS",
      "listen": "127.0.0.1",
      "port": 10001,
      "protocol": "vmess",
      "settings": {
        "clients": []
      },
      "streamSettings": {
        "network": "ws",
        "security": "none",
        "wsSettings": {
          "path": "/vmess"
        }
      }
    }
  ],
  "outbounds": [
    {
      "protocol": "freedom",
      "tag": "DIRECT"
    },
    {
      "protocol": "blackhole",
      "tag": "BLOCK"
    }
  ]
}
				
			

Refresh the dashboard.

Host Settings (This Fixes Client Configs)

Common settings for VLESS and VMESS:

Since the data is routed through nginx, we should use port 443. The Nginx configuration we added earlier will handle both VLESS and VMESS correctly based on the path you set here. So everything except Path setting should be identical here.

And for the path setting, type /vless for VLESS and /vmess for VMESS.

Create a User

Refresh the Marzban dashboard one more time and it should be ready to accept new users. 

Why Most Installations Fail

From real VPS fixes, the common mistakes are:

Avoid these, and Marzban works smoothly.

🔧 Don’t Want to Deal With This?

If you’d rather skip the setup and just have it working:

I fix real VPS issues daily, including:

Conclusion

Marzban isn’t hard to install. What matters is doing it in the right order.

Set up Docker → configure Nginx → enable SSL → then configure WebSocket properly.

Do that, and everything just works.

Tharindu

Hey!! I'm Tharindu. I'm from Sri Lanka. I'm a part time freelancer and this is my blog where I write about everything I think might be useful to readers. If you read a tutorial here and want to hire me, contact me here.

Leave a Reply

Your email address will not be published. Required fields are marked *

Back to top button