PasarGuard
Migration

Marzban to PasarGuard

This guide is for Marzban versions beta-3 and below.

This guide will help you migrate your data, settings, and user accounts from Marzban to PasarGuard without losing anything.

Prerequisites

⚠️ Important: Always have a complete backup of your data before starting the migration process.

  • Make sure you have root access to your server.
  • Have a backup of your current Marzban installation.
  • Check that Docker and Docker Compose are installed.

Migration Steps

1. Stop Marzban Services

First, stop all running Marzban containers:

Stop Service Commands

cd /opt/marzban
docker compose down

2. Rename Main Directory

Delete the PasarGuard directories, if they already exist:

Directories Delete Command

rm -r /opt/pasarguard /var/lib/pasarguard /var/lib/mysql/pasarguard

Change the main Marzban directory name to PasarGuard:

Directory Rename Command

sudo mv /opt/marzban /opt/pasarguard

3. Rename Data Directory

Change the data directory name as well:

Data Directory Rename Command

sudo mv /var/lib/marzban /var/lib/pasarguard

4. Rename MySQL Directory (if using)

If you're using MySQL and have a dedicated directory for Marzban database:

MySQL Directory Rename Command

sudo mv /var/lib/mysql/marzban /var/lib/mysql/pasarguard

If you encounter a "No such file or directory" error, it may be because the MySQL directory is different. Use this command instead:

mkdir -p /var/lib/mysql/pasarguard
mv /var/lib/pasarguard/mysql/* /var/lib/mysql/pasarguard
rm -r /var/lib/pasarguard/mysql

5. Update Environment Variables

Go to the new PasarGuard directory and update the environment file:

cd /opt/pasarguard

Update all paths referenced in the .env file with a simple command:

sudo sed -i 's|/var/lib/marzban|/var/lib/pasarguard|g' .env

If you're using an older version (0.8.4 or below), you also need to change the SQL driver:

Open the .env file:

nano .env

SQLite Driver Update

❌ Old

SQLALCHEMY_DATABASE_URL = "sqlite:///db.sqlite3"

✅ New

SQLALCHEMY_DATABASE_URL = "sqlite+aiosqlite:///db.sqlite3"

MySQL Driver Update

❌ Old

SQLALCHEMY_DATABASE_URL = "mysql+pymysql://root:MYSQL_ROOT_PASSWORD@127.0.0.1/marzban"

✅ New

SQLALCHEMY_DATABASE_URL = "mysql+asyncmy://root:MYSQL_ROOT_PASSWORD@127.0.0.1/pasarguard"

Other Changes

Rename v2ray to xray Template

If you're using a custom v2ray template, you should also change its directory with this command:

mv /var/lib/pasarguard/templates/v2ray /var/lib/pasarguard/templates/xray

Update xray-config Certificate Directories

If you have a TLS inbound, you need to update your xray_config.json and change the certificate directories from marzban to pasarguard:

nano /var/lib/pasarguard/xray_config.json

After changes, your .env file and xray_config.json should look something like this:

Update Xray template in .env

❌ Old

V2RAY_SUBSCRIPTION_TEMPLATE = "v2ray/default.json"

✅ New

XRAY_SUBSCRIPTION_TEMPLATE = "xray/default.json"

Update certificate directories in xray_config.json

❌ Old

      "certificates": [
        {
          "certificateFile": "/var/lib/marzban/certs/example.com/fullchain.pem",
          "keyFile": "/var/lib/marzban/certs/example.com/key.pem"
        }
      ],

✅ New

      "certificates": [
        {
          "certificateFile": "/var/lib/pasarguard/certs/example.com/fullchain.pem",
          "keyFile": "/var/lib/pasarguard/certs/example.com/key.pem"
        }
      ],

6. Update Docker Compose File

Update the docker-compose.yml file to reflect the new paths. You need to manually edit this file:

sudo nano docker-compose.yml

Docker Compose Changes

Here's a comparison showing the necessary changes:

❌ Before (Marzban)

services:
  marzban:
    image: gozargah/marzban:latest
    restart: always
    env_file: .env
    network_mode: host
    volumes:
      - /var/lib/marzban:/var/lib/marzban
    depends_on:
      - mysql

  mysql:
    image: mysql:lts
    restart: always
    env_file: .env
    network_mode: host
    command: --bind-address=127.0.0.1 --mysqlx-bind-address=127.0.0.1 --disable-log-bin
    environment:
      MYSQL_DATABASE: marzban
    volumes:
      - /var/lib/mysql/marzban:/var/lib/mysql

✅ After (PasarGuard)

services:
  pasarguard:
    image: pasarguard/panel:latest
    restart: always
    env_file: .env
    network_mode: host
    volumes:
      - /var/lib/pasarguard:/var/lib/pasarguard
    depends_on:
      - mysql

  mysql:
    image: mysql:lts
    restart: always
    env_file: .env
    network_mode: host
    command: --bind-address=127.0.0.1 --mysqlx-bind-address=127.0.0.1 --disable-log-bin
    environment:
      MYSQL_DATABASE: pasarguard
    volumes:
      - /var/lib/mysql/pasarguard:/var/lib/mysql

Key Changes Summary:

SectionBeforeAfter
Service Namemarzbanpasarguard
Docker Imagegozargah/marzban:latestpasarguard/panel:latest
App Volume/var/lib/marzban:/var/lib/marzban/var/lib/pasarguard:/var/lib/pasarguard
MySQL Databasemarzbanpasarguard
MySQL Volume/var/lib/mysql/marzban:/var/lib/mysql/var/lib/mysql/pasarguard:/var/lib/mysql

Obviously, if you are using SQLite database, you should not add MySQL lines to your file. Just compare the example with your file and apply the changes.

7. Change Marzban MySQL Database to PasarGuard (if using)

If you're using SQLite database, skip this step. If you're using MySQL database, export the Marzban database so it can later be imported as the PasarGuard database.

Export Marzban Database Commands

Run Mysql

cd /opt/pasarguard && docker compose up -d mysql

Dump Database

You will be asked to enter the database password. Use the value of MYSQL_ROOT_PASSWORD found in your .env file.

docker compose exec mysql mysqldump -u root -p -h 127.0.0.1 --databases marzban > "/opt/pasarguard/marzban.sql"

If you encounter an "Access Denied" error, try using marzban user with MYSQL_PASSWORD value from your .env file:

docker compose exec mysql mysqldump -u marzban -p -h 127.0.0.1 --databases marzban > "/opt/pasarguard/marzban.sql"

Edit Database Information

This step is crucial to ensure that the pasarguard database is created in MySQL. The following command will replace "marzban" with "pasarguard" in two important lines:

sed -i '/^CREATE DATABASE/s/marzban/pasarguard/;/^USE/s/marzban/pasarguard/' /opt/pasarguard/marzban.sql

Import PasarGuard Database

To import the new database, replace the database password in this command with the MYSQL_ROOT_PASSWORD value from your .env file:

docker compose exec -T mysql mysql -u root -p"MYSQL_ROOT_PASSWORD" -h 127.0.0.1 < "/opt/pasarguard/marzban.sql"

Alternative Method: You can import the database using phpmyadmin. Add the phpmyadmin service to your Docker Compose file and restart. Edit your marzban.sql backup file in a text editor, and replace marzban with pasarguard in the beginning lines (CREATE DATABASE and USE lines). Save the file and finally import it using phpmyadmin.

Drop Marzban Database

You will be asked to enter the database password. Use MYSQL_ROOT_PASSWORD value in your .env file.

Make sure you have a backup of your data and be prepared to restore the data if something goes wrong.

rm /opt/pasarguard/marzban.sql
docker compose exec mysql mysql -u root -p -e "DROP DATABASE marzban;"

8. Install PasarGuard Management Script

Install the PasarGuard management script for easier management:

Script Installation Command

sudo bash -c "$(curl -sL https://github.com/PasarGuard/scripts/raw/main/pasarguard.sh)" @ install-script

This script provides useful commands for managing your PasarGuard installation.

9. Start PasarGuard

Now start PasarGuard with the new configuration:

Startup Command

pasarguard restart

10. Verify Migration

Check that all services are running properly:

Verification Commands

pasarguard status

Open your panel URL to make sure everything is working correctly.

Troubleshooting

Common Issues

💡 Tip: Most issues can be resolved by checking file permissions and path configurations.

1. Permission Denied Make sure you're running commands with appropriate permissions (sudo when needed).

2. Database Connection Issues If you're using MySQL, check that database paths and login information are properly updated.

3. Port Conflicts Make sure no other services are using the same ports.

4. Missing Environment Variables Double-check that all environment variables in the .env file are properly updated.

Rollback

⚠️ Emergency Rollback: If you encounter serious issues and need to revert to the previous version

# Stop PasarGuard
cd /opt/pasarguard
docker compose down

# Restore original directories
sudo mv /opt/pasarguard /opt/marzban
sudo mv /var/lib/pasarguard /var/lib/marzban
sudo mv /var/lib/mysql/pasarguard /var/lib/mysql/marzban  # if using

# Restore original docker-compose.yml and .env files from backup
# Then start Marzban
marzban up

Post-Migration

After successful migration:

  • 📡 PasarGuard Nodes: Install and connect PasarGuard Nodes. PasarGuard itself doesn't run Xray-Core.
  • 📊 Update Monitoring: If you have monitoring tools, connect them to the new paths.
  • 💾 Update Backups: Make sure your backup scripts are updated to backup from the new directories.
  • 🧪 Test All Features: Thoroughly test all panel features to ensure everything is working correctly.

Support

🔗 Links

  • Discussion Group: Telegram
  • Issues: If you encounter any problems during migration, create an issue.

📝 Note: This guide assumes a standard Marzban installation. Custom configurations may require additional steps.