Marzban
Xray management panel
VPN / ProxyFree
Xray panel with nodes
The script is free · VPS from $10.20 per month · installs in about 7 minutes
root@vps:~# command -v docker >/dev/null || curl -fsSL https://get.docker.com | sh; mkdir -p /opt/remnawave && cd /opt/remnawave && curl -o docker-compose.yml https://raw.githubusercontent.com/remnawave/backend/refs/heads/main/docker-compose-prod.yml && curl -o .env https://raw.githubusercontent.com/remnawave/backend/refs/heads/main/.env.sample && sed -i "s/^APP_SECRET=.*/APP_SECRET=$(openssl rand -hex 64)/" .env && sed -i "s/^METRICS_PASS=.*/METRICS_PASS=$(openssl rand -hex 64)/" .env && sed -i "s/^WEBHOOK_SECRET_HEADER=.*/WEBHOOK_SECRET_HEADER=$(openssl rand -hex 64)/" .env && pw=$(openssl rand -hex 24) && sed -i "s/^POSTGRES_PASSWORD=.*/POSTGRES_PASSWORD=$pw/" .env && sed -i "s|^\(DATABASE_URL=\"postgresql://postgres:\)[^\@]*\(@.*\)|\1$pw\2|" .env && docker compose up -d
✓ Remnawave 3.4.4 installed · about 3 minutes
root@vps:~#
Remnawave is an Xray-core proxy management panel for those who sell access or run many servers. The panel and nodes are separate: users, subscriptions and statistics live in the panel, Xray runs on the nodes.
The panel runs in Docker alongside PostgreSQL and Valkey and listens only on 127.0.0.1, so it is exposed through a reverse proxy with HTTPS. Remnawave Node instances are installed on separate servers and connected from the UI.
The project is actively developed and offers an API and SDK for integrating with Telegram bots and billing.
For Remnawave: at least 4 vCPU, 4 GB RAM and 100 GB NVMe.
Three steps in the bot, no command line. The bot shows progress; installation usually takes about 7 minutes.
The install button on this page opens @ExpressHost_bot, and the bot fills in Remnawave by itself.
The script appears at the “Скрипты” (Scripts) step automatically; then pay for the server.
When installation finishes, the bot sends the login details to the chat.
/opt/remnawave on Ubuntu 22.04 or 24.04 and generates the secrets and the database password.server-name.expresshost.cloud and its subdomains.subs.server-name.expresshost.cloud./opt/remnanode, port 2222) and attaches it to a panel config profile. Port 443 here is taken by the panel’s nginx, so this node’s inbounds must listen on other ports.The panel runs in Docker together with PostgreSQL and Valkey. The documented minimum is 2 cores and 2 GB RAM; 4 cores and 4 GB are recommended, with a 20 GB disk.
| Port | Protocol | Purpose |
|---|---|---|
| 3000 | tcp | Panel and API (127.0.0.1 only, exposed via reverse proxy) |
| 3001 | tcp | Metrics (127.0.0.1 only) |
| 443 | tcp | Reverse proxy HTTPS in front of the panel |
Docker with the Compose plugin is required.
sudo curl -fsSL https://get.docker.com | shmkdir /opt/remnawave && cd /opt/remnawave
curl -o docker-compose.yml https://raw.githubusercontent.com/remnawave/backend/refs/heads/main/docker-compose-prod.yml && curl -o .env https://raw.githubusercontent.com/remnawave/backend/refs/heads/main/.env.sampleAPP_SECRET, METRICS_PASS and WEBHOOK_SECRET_HEADER are used for authentication. The default Postgres password should be changed too — that is the second line.
sed -i "s/^APP_SECRET=.*/APP_SECRET=$(openssl rand -hex 64)/" .env && sed -i "s/^METRICS_PASS=.*/METRICS_PASS=$(openssl rand -hex 64)/" .env && sed -i "s/^WEBHOOK_SECRET_HEADER=.*/WEBHOOK_SECRET_HEADER=$(openssl rand -hex 64)/" .env
pw=$(openssl rand -hex 24) && sed -i "s/^POSTGRES_PASSWORD=.*/POSTGRES_PASSWORD=$pw/" .env && sed -i "s|^\(DATABASE_URL=\"postgresql://postgres:\)[^\@]*\(@.*\)|\1$pw\2|" .envIn .env set FRONT_END_DOMAIN — the panel domain, for example panel.yourdomain.com — and SUB_PUBLIC_DOMAIN — the same domain with /api/sub at the end.
nano .envThe panel listens only on 127.0.0.1:3000 — a reverse proxy exposes it. Do not publish Remnawave services to the internet directly.
docker compose up -d && docker compose logs -f -tThe documentation requires an HTTPS reverse proxy in front of the panel. You need your own domain with an A record pointing to the server IP; Caddy issues the certificate itself.
mkdir -p /opt/remnawave/caddy && cd /opt/remnawave/caddy && nano CaddyfileReplace YOUR_DOMAIN with the panel domain.
https://YOUR_DOMAIN {
encode
reverse_proxy * http://remnawave:3000
}
:443 {
tls internal
respond 204
}Paste the configuration below into the file.
cd /opt/remnawave/caddy && nano docker-compose.ymlservices:
caddy:
image: caddy:2.9
container_name: 'caddy'
hostname: caddy
restart: always
ports:
- '0.0.0.0:443:443'
- '0.0.0.0:80:80'
networks:
- remnawave-network
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile
- caddy-ssl-data:/data
networks:
remnawave-network:
name: remnawave-network
driver: bridge
external: true
volumes:
caddy-ssl-data:
driver: local
external: false
name: caddy-ssl-dataOpen the domain in a browser. The first user to register becomes the super-admin.
docker compose up -d && docker compose logs -f -tThe panel has no Xray of its own: connections are served by Remnawave Node, a lightweight container with Xray-core. The node is recommended on a separate server and needs at least 1 core and 1 GB RAM.
Nodes → Management → “+”. Node Port is the internal API port the panel uses to manage the node. Click Copy docker-compose.yml.
Paste the copied config into docker-compose.yml.
sudo curl -fsSL https://get.docker.com | sh
mkdir /opt/remnanode && cd /opt/remnanode && nano docker-compose.ymldocker compose up -d && docker compose logs -f -tIn the node card click Next, choose a Config Profile and click Create. Firewall NODE_PORT for everyone except the panel IP.
VLESS Reality and other inbounds are defined in Config Profiles. For users to get them, attach the inbounds to Hosts and enable them in Internal Squads (Default-Squad). REALITY needs no certificate on the node.
Update the panel first, then the nodes, and read the changelog before you do.
cd /opt/remnawave && docker compose pull && docker compose down && docker compose up -d && docker compose logs -fcd /opt/remnanode && docker compose pull && docker compose down && docker compose up -d && docker compose logs -fIf it lives in /opt/remnawave/subscription, as with the bot install.
cd /opt/remnawave/subscription && docker compose pull && docker compose down && docker compose up -d && docker compose logs -fThat is by design: the panel listens only on 127.0.0.1, and an HTTPS reverse proxy on a domain exposes it.
Xray failed to start because of a config error. docker exec remnanode xlogs shows the reason; fix the profile in the panel and save it.
The inbounds have to be attached to Hosts and enabled in Internal Squads.
The Rescue CLI can recreate the super-admin: docker exec -it remnawave cli.
Commands and steps were checked against the official documentation on October 25, 2026. What the bot install does comes from its install script.
Didn’t find an answer? Message @ExpressHost_SupportBot.
The documentation requires at least 2 cores and 2 GB RAM and recommends 4 cores and 4 GB. A node needs 1 core and 1 GB, but Xray uses more under load.
You can, but the developers recommend putting the node on a separate server: the panel itself has no Xray.
cd /opt/remnawave && docker compose pull && docker compose down && docker compose up -d. Update the panel first, then the nodes.
Settings are in /opt/remnawave/.env, the PostgreSQL database is in a Docker volume next to the project. Dump the database before updating.
Remnawave installs at checkout — in the bot.
Netherlands, Amsterdam
$11.22/mo
$0.40 for 24 hours · $2.81 for 7 days
Pick Remnawave at the “Scripts” step when you order the server.
Germany, Frankfurt
$15.30/mo
$0.55 for 24 hours · $3.83 for 7 days
Pick Remnawave at the “Scripts” step when you order the server.
Poland, Warsaw
$10.20/mo
$0.36 for 24 hours · $2.55 for 7 days
Pick Remnawave at the “Scripts” step when you order the server.
Estonia, Tallinn
$15.26/mo
$0.55 for 24 hours · $3.82 for 7 days
Pick Remnawave at the “Scripts” step when you order the server.