Skip to content

Remnawave on a VPS: install the panel and a node

Xray panel with nodes

Category
VPN / Proxy
Hosting
VPN server
Author
Remnawave
License
AGPL-3.0
Version
3.4.4
Updated

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

Install over SSH

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

  • SystemUbuntu 24.04 · x86_64ok
  • Sourcegithub.com/remnawave/panelok
  • Version3.4.4ok
  • Port3000/tcplisten
  • Port3001/tcplisten
  • Port443/tcplisten

✓ Remnawave 3.4.4 installed · about 3 minutes

root@vps:~#

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

What it is

  • Xray
  • VLESS
  • Subscriptions
  • Multi-server
  • API

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.

  • Split into a panel and nodes running Xray-core
  • Subscriptions with a dedicated client page
  • Limits on traffic, time and devices (HWID)
  • REST API and SDK for bots and billing
  • Configuration profiles for node groups
  • User and node statistics and metrics

Who it is for

  • You sell VPN access or run many servers: users and subscriptions live in the panel, Xray on the nodes.
  • You need traffic, expiry and device (HWID) limits, a REST API and SDKs for your own bot and billing.

Recommended plan

For Remnawave: at least 4 vCPU, 4 GB RAM and 100 GB NVMe.

Minimum to run
2 vCPU · 2 GB RAM · 20 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 Remnawave 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 the panel in Docker in /opt/remnawave on Ubuntu 22.04 or 24.04 and generates the secrets and the database password.
  • Puts nginx on port 443 in front of the panel with a Let’s Encrypt certificate for the server domain server-name.expresshost.cloud and its subdomains.
  • Brings up the subscription page at subs.server-name.expresshost.cloud.
  • Registers the SuperAdmin admin with a random password — the bot sends the panel address, username and password to the chat.
  • Installs the node-01 node on the same server (/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.

Installing the Remnawave panel by hand

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.

Remnawave ports
PortProtocolPurpose
3000tcpPanel and API (127.0.0.1 only, exposed via reverse proxy)
3001tcpMetrics (127.0.0.1 only)
443tcpReverse proxy HTTPS in front of the panel
  1. 01

    Install Docker

    Docker with the Compose plugin is required.

    Code
    sudo curl -fsSL https://get.docker.com | sh
  2. 02

    Download docker-compose.yml and .env

    Code
    mkdir /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
  3. 03

    Generate the secrets

    APP_SECRET, METRICS_PASS and WEBHOOK_SECRET_HEADER are used for authentication. The default Postgres password should be changed too — that is the second line.

    Code
    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
  4. 04

    Set the domains

    In .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.

    Code
    nano .env
  5. 05

    Start the containers

    The panel listens only on 127.0.0.1:3000 — a reverse proxy exposes it. Do not publish Remnawave services to the internet directly.

    Code
    docker compose up -d && docker compose logs -f -t

Domain and HTTPS: Caddy in front of the panel

The 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.

  1. 01

    Create the Caddyfile

    Code
    mkdir -p /opt/remnawave/caddy && cd /opt/remnawave/caddy && nano Caddyfile
  2. 02

    Paste the configuration

    Replace YOUR_DOMAIN with the panel domain.

    Code
    https://YOUR_DOMAIN {
            encode
            reverse_proxy * http://remnawave:3000
    }
    :443 {
        tls internal
        respond 204
    }
  3. 03

    Create docker-compose.yml for Caddy

    Paste the configuration below into the file.

    Code
    cd /opt/remnawave/caddy && nano docker-compose.yml
  4. 04

    Caddy configuration

    Code
    services:
      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-data
  5. 05

    Start Caddy and log in

    Open the domain in a browser. The first user to register becomes the super-admin.

    Code
    docker compose up -d && docker compose logs -f -t

Remnawave node and VLESS Reality

The 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.

  1. 01

    Add the node in the panel

    Nodes → Management → “+”. Node Port is the internal API port the panel uses to manage the node. Click Copy docker-compose.yml.

  2. 02

    Prepare the node server

    Paste the copied config into docker-compose.yml.

    Code
    sudo curl -fsSL https://get.docker.com | sh
    mkdir /opt/remnanode && cd /opt/remnanode && nano docker-compose.yml
  3. 03

    Start the node

    Code
    docker compose up -d && docker compose logs -f -t
  4. 04

    Finish in the panel

    In the node card click Next, choose a Config Profile and click Create. Firewall NODE_PORT for everyone except the panel IP.

  5. 05

    Set up the inbounds

    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.

Updating Remnawave

Update the panel first, then the nodes, and read the changelog before you do.

  1. 01

    Panel

    Code
    cd /opt/remnawave && docker compose pull && docker compose down && docker compose up -d && docker compose logs -f
  2. 02

    Node

    Code
    cd /opt/remnanode && docker compose pull && docker compose down && docker compose up -d && docker compose logs -f
  3. 03

    Subscription page

    If it lives in /opt/remnawave/subscription, as with the bot install.

    Code
    cd /opt/remnawave/subscription && docker compose pull && docker compose down && docker compose up -d && docker compose logs -f

Common Remnawave errors

  • The panel does not open by IP or over HTTP

    That is by design: the panel listens only on 127.0.0.1, and an HTTPS reverse proxy on a domain exposes it.

  • The node logs XML-RPC fault: SPAWN_ERROR: xray

    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.

  • Users do not see new inbounds

    The inbounds have to be attached to Hosts and enabled in Internal Squads.

  • Forgot the super-admin password

    The Rescue CLI can recreate the super-admin: docker exec -it remnawave cli.

Sources

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

Remnawave FAQ

Didn’t find an answer? Message @ExpressHost_SupportBot.

What server does the panel need?

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.

Can I run the panel and a node on the same server?

You can, but the developers recommend putting the node on a separate server: the panel itself has no Xray.

How do I update Remnawave?

cd /opt/remnawave && docker compose pull && docker compose down && docker compose up -d. Update the panel first, then the nodes.

Where is the data stored?

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.