Separate server
Separate server installation means that you will install subscription page on a different server from Remnawave Panel.
Step 1 - Prepare .env fileβ
Make this changes on the server where Remnawave Panel is installed.
Edit the /opt/remnawave/.env file and change SUB_PUBLIC_DOMAIN to your subscription page domain name.
cd /opt/remnawave && nano .env
Change SUB_PUBLIC_DOMAIN to your subscription page domain name. Domain name must be without http or https.
SUB_PUBLIC_DOMAIN=subscription.domain.com
Don't forget to restart Remnawave Panel container:
cd /opt/remnawave && docker compose down remnawave && docker compose up -d && docker compose logs -f
Step 2 - Create docker-compose.yml fileβ
This step and next steps should be made on another server!
Make sure you have Docker installed on the server where you will install the subscription page.
mkdir -p /opt/remnawave/subscription && cd /opt/remnawave/subscription && nano docker-compose.yml
services:
    remnawave-subscription-page:
        image: remnawave/subscription-page:latest
        container_name: remnawave-subscription-page
        hostname: remnawave-subscription-page
        restart: always
        env_file:
            - .env
        ports:
            - '127.0.0.1:3010:3010'
        networks:
            - remnawave-network
networks:
    remnawave-network:
        name: remnawave-network
        driver: bridge
        external: false
Now create .env file:
mkdir -p /opt/remnawave/subscription && cd /opt/remnawave/subscription && nano .env
Paste the following content into the .env file:
APP_PORT=3010
REMNAWAVE_PANEL_URL=https://remnawave.panel.com
META_TITLE="Subscription page"
META_DESCRIPTION="Subscription page description"
Replace remnawave.panel.com with your panel domain name.
Full .env file reference
APP_PORT=3010
### Remnawave Panel URL, can be http://remnawave:3000 or https://panel.example.com
REMNAWAVE_PANEL_URL=https://panel.example.com
META_TITLE="Subscription page"
META_DESCRIPTION="Subscription page description"
# Serve at custom root path, for example, this value can be: CUSTOM_SUB_PREFIX=sub
# Do not place / at the start/end
CUSTOM_SUB_PREFIX=
# Support Marzban links
MARZBAN_LEGACY_LINK_ENABLED=false
MARZBAN_LEGACY_SECRET_KEY=
REMNAWAVE_API_TOKEN=
# If you use "Caddy with security" addon, you can place here X-Api-Key, which will be applied to requests to Remnawave Panel.
CADDY_AUTH_API_TOKEN=
# If you use Cloudflare Zero Trust to protect your panel, please use this variables to bypass the security.
CLOUDFLARE_ZERO_TRUST_CLIENT_ID=
CLOUDFLARE_ZERO_TRUST_CLIENT_SECRET=
Step 3 - Start the containerβ
docker compose up -d && docker compose logs -f
Step 4 - Configure reverse proxyβ
Remnawave and its components does not support being server on a sub-path. (e.g. location /subscription {)
It has to be served on the root path of a domain or subdomain.
For custom path, you can use the CUSTOM_SUB_PREFIX parameter.
Caddyβ
Caddy configuration
Create a file called Caddyfile in the /opt/remnawave/caddy directory.
mkdir -p /opt/remnawave/caddy && cd /opt/remnawave/caddy && nano Caddyfile
Paste the following configuration.
Please, replace REPLACE_WITH_YOUR_DOMAIN with your subscription page domain name.
Review the configuration below, look for red highlighted lines.
https://SUBSCRIPTION_PAGE_DOMAIN {
        reverse_proxy * http://remnawave-subscription-page:3010
}
:443 {
    tls internal
    respond 204
}
Please replace SUBSCRIPTION_PAGE_DOMAIN with your domain name.
Review the configuration below, look for green highlighted lines.
Create docker-compose.ymlβ
Create a docker-compose.yml file in the /opt/remnawave/caddy directory.
cd /opt/remnawave/caddy && nano docker-compose.yml
Paste the following configuration.
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
Start the containerβ
docker compose up -d && docker compose logs -f -t
Step 5 - Usageβ
The subscription page will be available at https://subdomain.panel.com/<shortUuid>.
Configuring subscription page (optional)β
You can customize the subscription page by creating an app-config.json file. This allows you to:
- Add support for different VPN apps
 - Customize text and instructions in multiple languages
 - Add your own branding (logo, company name, support links)
 - Configure which apps appear as "featured"
 
ποΈ Customization
Customization guide