Что нужно до старта: VPS, домены, DNS, Docker
80% проблем новичков — не в самой панели, а в подготовке. Разберитесь с базой до того, как настроить Remnawave.
Минимальный набор:
- VPS под панель — 1–2 vCPU, 2 ГБ RAM, Debian 12 / Ubuntu 22.04+. Панель почти не грузит железо; ресурсы ест нода.
- VPS под ноду — отдельная машина там, где нужен выход трафика. Панель и нода умеют жить на одном сервере, но в проде разносите: заблокируют ноду или соберётесь переезжать — панель с базой останется цела.
- Домен + доступ к DNS. Нужны минимум 2 поддомена: под панель (
panel.example.com) и под страницу подписки (sub.example.com). Reality-инбаунду свой домен не нужен — он маскируется под чужой SNI. - Docker + compose plugin — ставится официальным скриптом:
curl -fsSL https://get.docker.com | sh
DNS: A-записи поддоменов на IP панели. Для sub.* проксирование Cloudflare (оранжевое облако) допустимо; для panel.* на первичную выдачу сертификата проще оставить DNS-only (серое облако), иначе ACME-челлендж может не пройти. Дайте записям прогрузиться (dig panel.example.com должен отдавать ваш IP) до установки.
Установка панели Remnawave через Docker
Панель ставится контейнерами. Стек: backend (сама панель), PostgreSQL, Valkey (Redis-совместимый кеш). Нода — отдельный контейнер, к ней ниже.
Порядок:
- Рабочая директория, например
/opt/remnawave, тудаdocker-compose.ymlи.envиз документации проекта под вашу версию. - В
.envзаполните ключевое: - домены панели и подписки (
FRONT_END_DOMAIN,SUB_PUBLIC_DOMAIN); - логин/пароль Postgres;
JWT-секреты — сгенерируйте случайные, не оставляйте дефолт:openssl rand -hex 32;- параметры Telegram-бота/вебхуков — опционально.
- Поднимите стек и смотрите логи:
docker compose up -d
docker compose logs -f remnawave
Миграции БД прогоняются автоматически при первом старте — в логах видно, как накатываются схемы.
- Создайте администратора. В версиях 2.x первый вход — регистрация первого пользователя на веб-морде (после этого регистрация закрывается). Сверяйтесь с документацией ровно вашей версии.
Честно про версии. Проект активно развивается: между 1.x и 2.x менялись и структура .env, и логика инбаундов (в 2.x они переехали в config profile). Всегда берите compose и переменные под ту версию, что ставите, — это главная причина «у меня не так, как в статье».
Домены и reverse proxy: панель + страница подписки
Панель и подписку не оставляют голыми на порту — их закрывают reverse proxy с TLS. Проще всего Caddy (автоматический Let's Encrypt), для тонкой настройки — nginx.
Минимальный Caddyfile:
panel.example.com {
reverse_proxy 127.0.0.1:3000
}
sub.example.com {
reverse_proxy 127.0.0.1:3010
}
Порты сверьте с вашим compose.
Типовые грабли:
SUB_PUBLIC_DOMAINв.envдолжен совпадать с доменом в reverse proxy и в DNS — иначе в ссылке на подписку окажется неверный хост и клиент не скачает конфиг.- Не выставляйте порт панели напрямую в интернет мимо прокси. Админка — самое чувствительное; прячьте её дополнительно: нестандартный путь, basic-auth, ограничение по IP.
- Для iOS-клиентов (Happ и др.) на странице подписки важны заголовки кеширования: после смены конфига телефон нередко держит старую версию. Отдавайте подписку с
Cache-Control: no-cacheлибо переподключайте подписку в приложении — это лечит «не вижу новый сервер».
Config profile и инбаунды: VLESS Reality
В Remnawave 2.x инбаунды задаются не по одному в UI, а через config profile — это фактически Xray-конфиг (JSON) с секцией inbounds, который панель раздаёт нодам. Гибко, но требует знать синтаксис Xray.
Практичный дефолт для обхода блокировок — VLESS + Reality:
- свой валидный TLS-сертификат на домен ноды не нужен — Reality маскирует соединение под легитимный чужой сайт;
- ключевые поля:
privateKey/publicKey(генерируютсяxray x25519),shortIds,dest(например:443реального сайта с TLS 1.3 и HTTP/2) иserverNamesпод него.
Сгенерировать пару ключей одной командой в контейнере:
docker run --rm ghcr.io/xtls/xray-core x25519
Что учесть:
serverNames(SNI) выбирайте под реально живой сторонний сайт, географически близкий и стабильный; «мёртвый» dest ломает соединение.- Один config profile может содержать несколько инбаундов (разные протоколы/порты) — потом раздаются разным squad.
- Помимо Reality есть XHTTP и другие транспорты — они нужны, когда трафик заворачивают за CDN. Это отдельная тема (см. наши разборы по XHTTP и выносу Remnawave за CDN); для чистой ноды в ДЦ Reality проще и надёжнее — здесь не дублирую.
Подключение ноды по взаимному TLS (mTLS)
Нода (remnawave-node) — контейнер с Xray: получает конфиг от панели и гоняет трафик. Панель и нода общаются по взаимному TLS: панель выдаёт креды, нода ими авторизуется. Без этого нода не подключится.
Порядок:
- В панели создайте ноду: имя, публичный адрес/IP и порт (по умолчанию нода слушает служебный порт связи с панелью).
- Панель выдаст сертификат/креды — обычно строкой в переменную окружения (
SSL_CERTили аналог) для compose ноды. Скопируйте целиком, без обрезки. - На сервере ноды поднимите её
docker-compose.yml, вставив креды и адрес панели в.env, затемdocker compose up -d. - В панели статус ноды должен стать online/connected.
Диагностика, если нода не поднимается:
- служебный порт ноды доступен с панели? Проверьте firewall/security group с обеих сторон:
nc -vz <panel_ip> <port>; - креды скопированы без обрезки и лишних переносов строк;
- логи ноды
docker compose logs -f— там видно, отвергает панель авторизацию или не сходится TLS; - время на серверах синхронизировано (NTP): рассинхрон часов ломает TLS-рукопожатие.
Пользователи, squad и hosts
Нода онлайн, инбаунды описаны — связываем пользователей с конфигом. В 2.x цепочка: пользователь → internal squad → инбаунды, а на выходе клиент получает host (готовую строку подключения).
Шаги:
- Internal squad — группа, привязывающая набор инбаундов из config profile к пользователям. Создайте хотя бы один squad и включите нужные инбаунды.
- Пользователь — имя, лимит трафика (опц.), срок действия, привязка к squad. Каждому генерируется UUID и подписочный токен.
- Host — витрина подключения: под каждый инбаунд описывается host с адресом ноды, портом, SNI, Reality-параметрами и remark (название, которое клиент увидит в приложении). Именно hosts собираются в подписку.
Практика:
- Начните с одного squad и одного-двух hosts, добейтесь подключения, потом усложняйте.
- Remark делайте информативным (страна/номер) — это видно пользователю в списке серверов.
- Массовую выдачу и лимиты удобно автоматизировать через API/Telegram-бота, но на этапе настройки пройдите путь руками — так понятнее, что на что влияет.
Подписки, проверка и устойчивость ноды
Финальный артефакт — ссылка на подписку вида https://sub.example.com/<token>. Клиент (v2rayNG, Hiddify, Happ, Streisand) добавляет её и получает актуальный список hosts; при изменениях в панели подписка обновляется без переотправки конфигов.
Проверка перед раздачей:
- откройте ссылку в браузере или
curl -I https://sub.example.com/<token>— должен вернуться base64/конфиг и 200, а не 404; - импортируйте в тестовый клиент, подключитесь, проверьте реальный выход (IP-чек, доступ к нужным ресурсам);
- на iOS помните про кеширование подписки (см. раздел про reverse proxy).
Про устойчивость — честно. Нода в ДЦ отлично работает, пока её IP/подсеть не попали под блок. В режиме «белых списков» (ТСПУ режет всё, кроме разрешённых сетей) сервер в обычном дата-центре выключается первым — не спасают ни Reality, ни смена порта. Устойчивость даёт вынос фронта на whitelisted-CDN: клиент стучится в разрешённую CDN-сеть, а та проксирует трафик до вашей ноды. Это отдельный слой поверх той же панели — как заворачивать инбаунды за CDN и почему нужен XHTTP, разобрано в наших материалах про Remnawave за CDN и про XHTTP. Здесь важен принцип: панель и нода настраиваются одинаково, а живучесть определяется тем, через какой фронт до ноды доходит клиент.