Развертывание
Документ описывает продакшен-запуск после разделения проекта на backend, frontend и worker.
Перед стартом заполните минимальный .env по configuration.md. Полный справочник переменных лежит в configuration/env-vars.md; после первого входа большинство продуктовых настроек удобнее менять через Web App админку.
Быстрый старт
Заголовок раздела «Быстрый старт»Интерактивный install wizard
Заголовок раздела «Интерактивный install wizard»Для нового сервера скачайте install-скрипт и запустите его:
Та же ссылка на install-скрипт в GitLab:
Wizard работает через меню с цифрами и подтверждениями y/n. Он умеет:
- работать полностью на русском языке и по умолчанию предлагать папку
/opt/remnawave-minishop; - скачать выбранный compose-профиль (
Caddy,Angie,Nginx,Pangolin/Newt,no-proxyили профиль существующего eGames reverse proxy); - встроиться в уже запущенный reverse proxy на сервере: помимо схемы eGames
wizard находит любые запущенные Nginx/Angie/Caddy контейнеры, подключает их к
Docker-сети Minishop (или проксирует на локальные порты для host-network),
дописывает managed-блоки конфига с маркерами
BEGIN/END remnawave-minishop, проверяет конфиг (nginx -t/angie -t/caddy validate) и откатывает изменения при ошибке; - подключить публикацию Web App через Pangolin (Newt) отдельным обратимым
шагом: пункты меню «Подключить Web App к Pangolin (Newt)» и «Отключить
Web App от Pangolin (Newt)» добавляют/убирают
docker-compose.pangolin.ymlчерезCOMPOSE_FILEв.env, не трогая основной профиль деплоя; - сгенерировать минимальный
.env, включая пароли и стабильные secrets; - проверить A-записи
WEBHOOK_HOSTиMINIAPP_HOSTперед выпуском TLS; - для Nginx выпустить сертификаты через Certbot Cloudflare DNS-01 или standalone
HTTP-01, либо принять уже разложенные файлы
ssl/<hostname>/; - сохранить backup существующих файлов перед перезаписью;
- подготовить writable
data/для файлов приложения и при необходимости обновить владельца каталога на пользователя контейнеров10001:10001; - запустить
docker compose pull && docker compose up -d; - проверить текущий стек через
docker compose psи логиmigrate; - запустить миграцию из поддерживаемых ботов: Remnashop и старый
remnawave-tg-shop; - выбрать связь frontend -> backend WebApp API: same-origin, protected upstream или Rathole tunnel;
Wizard не спрашивает repository/ref в обычном сценарии. По умолчанию он берет
3252a8/remnawave-minishop и ref main; для тестирования другой ветки, тега
или форка задайте источник перед запуском:
Миграция Remnashop в wizard сначала запускает проверку без записи (dry-run),
показывает короткую сводку и сохраняет полный JSON/raw-вывод в .installer/.
Если выбрана текущая compose-БД, wizard предлагает сделать бэкап целевой БД и
основных файлов деплоя в backups/pre-remnashop-migration-* с restore.sh.
После успешной проверки подтверждение применения имеет дефолт Y: Enter
применит миграцию, n остановит ее без записи. Если
указать старый Remnashop .env, wizard передаст importer-у APP_CRYPT_KEY,
Remnawave API settings и поддерживаемые payment provider settings из таблицы
payment_gateways. После применения wizard обновляет совместимые настройки,
перезапускает backend, worker и frontend, для профиля eGames делает
nginx -t и reload/restart eGames Nginx, отправляет Telegram-уведомление
админам/лог-чату и в самом конце печатает новые webhook URL для Remnawave Panel,
Telegram и платежных провайдеров.
Миграция со старого remnawave-tg-shop работает как upgrade совместимой БД:
wizard автоматически пытается собрать source DSN из старого DB-контейнера,
сохраняет pg_dump старой БД в backups/pre-remnawave-tg-shop-source-*,
пересоздает целевой DB volume с новыми POSTGRES_* из .env,
восстанавливает сохраненный дамп в целевую compose-БД и запускает сервис
migrate. Старый DB volume remnawave-tg-shop-db-data не удаляется.
Что спрашивает install wizard
Заголовок раздела «Что спрашивает install wizard»Wizard старается предлагать безопасные значения по умолчанию. Если вы запускаете его на обычном VPS с публичными доменами, чаще всего можно нажимать Enter там, где уже показано подходящее значение.
| Вопрос | Что это значит | Что обычно выбрать |
|---|---|---|
Папка установки |
Каталог, куда будут скачаны docker-compose.yml, .env, прокси-конфиги и где появятся data/ и backups/. |
Оставьте /opt/remnawave-minishop, если на сервере нет особой схемы каталогов. |
Профиль деплоя |
Как приложение будет опубликовано наружу. | Caddy HTTPS для нового публичного сервера; Angie HTTPS - те же автоматические сертификаты, но конфигурация в Nginx-синтаксисе; Nginx HTTPS, если уже управляете сертификатами; Pangolin/Newt, если входящие порты закрыты; Без прокси, если TLS завершается внешней платформой; профиль существующего reverse proxy, если на этом же хосте уже работает Remnawave через eGames или любой другой Nginx/Angie/Caddy контейнер. |
Подключение к существующему reverse proxy |
Для профиля существующего прокси: схема eGames (unix socket), универсальное подключение к любому запущенному Nginx/Angie/Caddy контейнеру или пропуск. | Схему eGames — для установки Remnawave скриптом eGames; универсальное подключение — для остальных случаев. Wizard сам определит host/bridge-сеть контейнера, переиспользует найденный ssl_certificate и откатит конфиг, если nginx -t/angie -t/caddy validate не пройдет. |
Имя Docker Compose проекта |
Префикс Docker-сети, volumes и контейнеров. | Оставьте remnawave-minishop. Меняйте только если на одном сервере нужно несколько независимых стеков. |
Тег Docker-образа |
Версия backend/worker/frontend образов. | Для обычной установки оставьте latest или укажите конкретный опубликованный релизный тег. |
Токен Telegram бота |
BOT_TOKEN из BotFather. |
Вставьте токен бота, через которого пользователи будут открывать Mini App. |
Telegram ID администраторов |
Список Telegram ID, которым доступна админка и сервисные уведомления. | Укажите свой ID; несколько ID разделяйте запятыми. |
Пользователь/пароль/база PostgreSQL |
Учетные данные внутренней базы Minishop. | Пользователя и имя базы можно оставить по умолчанию; пароль wizard генерирует сам, его можно принять Enter. |
Название Web App |
Название приложения в интерфейсе. | Можно оставить remnawave-minishop и позже поменять в настройках. |
URL API Remnawave Panel |
Адрес API панели, обычно https://panel.example.com/api. |
Укажите публичный URL панели с /api в конце. |
API-ключ Remnawave Panel |
Token из Remnawave Panel для чтения/изменения пользователей. | Вставьте API token с нужными правами. Если панель закрыта cookie-proxy, заполните и вопрос про Cookie. |
Webhook-секрет Remnawave Panel |
Секрет, которым панель подписывает webhook в Minishop. | Можно принять сгенерированный секрет, но тот же секрет нужно указать в Remnawave Panel. |
Telegram OAuth client secret |
Секрет BotFather Web Login для входа через браузер вне Telegram. | Можно оставить пустым, если нужен только Telegram Mini App. |
WEBHOOK_HOST / MINIAPP_HOST |
Публичные домены без https://, пути и порта. |
Например webhooks.example.com и app.example.com. Для Caddy/Angie/Nginx/eGames DNS должен указывать на сервер или на прокси перед ним. |
HTTP_BIND / HTTPS_BIND |
На каком IP и портах Caddy/Angie/Nginx слушает входящий HTTP/HTTPS. | Обычно 0.0.0.0:80 и 0.0.0.0:443. IP без порта указывать нельзя. |
WEB_SERVER_BIND / FRONTEND_BIND |
Порты прямой публикации backend и frontend в no-proxy/eGames профилях. | Для no-proxy обычно 0.0.0.0:8080 и 0.0.0.0:8082; для eGames лучше 127.0.0.1:8080 и 127.0.0.1:8082, чтобы сервисы были доступны только локальному Nginx. |
WEBHOOK_PUBLIC_URL / MINIAPP_PUBLIC_URL |
Публичные URL, по которым Telegram, платежные провайдеры и пользователи увидят приложение в no-proxy/eGames сценариях. | Для production это должны быть HTTPS URL. В no-proxy с локальной проверкой можно временно оставить http://127.0.0.1:.... |
FRONTEND_BACKEND_MODE |
Как frontend nginx достигает WebApp API plane 8081. |
same-origin для обычного compose, protected-upstream для отдельного frontend-сервера, rathole для приватного туннеля. Browser API base остается /api во всех режимах. |
WEBAPP_BACKEND_UPSTREAM |
Server-side upstream frontend nginx для /api, /auth, /open-app и Web App assets. |
http://backend:8081 в обычном compose, https://bot.example.com для protected backend-domain mode, http://rathole-server:18081 для Rathole. |
MINISHOP_EDGE_TOKEN |
Server-side secret между frontend nginx/API edge и backend WebApp API. | Используйте для protected public backend upstream. Не добавляйте этот token в frontend JS и не требуйте его на webhook plane 8080. |
Интеграция с Remnawave Panel настраивается отдельным шагом. На новой установке без найденных
параметров обычный Enter пропускает этот шаг и записывает пустые значения вместо change_me.
Minishop запустится, но синхронизация, выдача подписок и другие Panel-зависимые действия останутся
недоступны до настройки.
Если параметры введены, wizard делает безопасный запрос к /system/stats и проверяет HTTP-статус,
Content-Type: application/json и структуру ответа. PANEL_API_COOKIE должен быть пустым либо
иметь вид name=value; JWT без имени cookie обычно относится к PANEL_API_KEY. После неуспешной
проверки по умолчанию предлагается пропустить интеграцию. Сохранить непроверенные значения можно
только отдельным явным выбором — это полезно, когда Panel временно недоступна во время установки.
Формат bind-полей (HTTP_BIND, HTTPS_BIND, WEB_SERVER_BIND,
FRONTEND_BIND) особенно важен: используйте PORT или IP:PORT, например
80, 0.0.0.0:80, <IP_СЕРВЕРА>:80, 127.0.0.1:8080. Значение
с одним IP без порта некорректно: Docker Compose воспринимает его как
порт хоста и падает с ошибкой invalid hostPort.
Если Docker Compose не найден, wizard предложит установить его автоматически.
Он сначала пробует системный пакетный менеджер (apt, dnf/yum, apk,
pacman), затем, если Docker CLI уже установлен, пробует поставить Compose как
Docker CLI plugin. Если автоматическая установка не подходит вашему серверу,
установите Docker Engine и Docker Compose plugin вручную и запустите wizard
повторно.
При ошибке docker compose pull или docker compose up -d wizard печатает не
только сырой вывод Docker, но и русское объяснение для частых случаев:
некорректный bind-адрес, занятый порт, IP не назначен серверу, не запущен
Docker daemon, нет прав на Docker socket, недоступен registry или указан
несуществующий IMAGE_TAG. Полный вывод последней Compose-ошибки сохраняется в
.installer/compose-last-error.log внутри папки установки.
Обычный docker compose up -d --build поднимает:
postgresиredisс проверками здоровья; PostgreSQL healthcheck проверяет именно логин/пароль из.env, а не только открытый порт;migrateкак одноразовый сервис на backend-образе;backendтолько после успешных миграций;workerтолько после успешных миграций;frontendкак отдельный nginx-образ без Python runtime.
Основной путь миграций — отдельный сервис migrate. backend и worker также выполняют
безопасную проверку схемы на старте под PostgreSQL advisory lock, поэтому прямой запуск сервиса
без compose тоже применит недостающие миграции и не создаст гонку на схеме БД.
При повторном запуске wizard проверяет существующий Docker volume PostgreSQL. Если volume уже
инициализирован старым паролем, wizard останавливает старт до запуска приложения и предлагает либо
вернуть старый POSTGRES_PASSWORD, либо явно удалить volume для настоящей чистой установки.
Готовые папки запуска
Заголовок раздела «Готовые папки запуска»Для продакшена удобнее использовать не корневой compose, а отдельные Docker Compose-примеры из папки deploy/examples. В каждой папке лежат свой docker-compose.yml, .env.example и нужный конфиг прокси.
Предпочтительный вариант для обычного публичного сервера - Caddy: он сам выпускает и продлевает HTTPS-сертификаты, а конфигурация получается короче, чем с ручным Nginx. Если ближе Nginx-синтаксис, тот же автоматический HTTPS дает Angie - форк Nginx с нативной поддержкой ACME.
| Папка | Когда использовать |
|---|---|
deploy/examples/caddy |
Нужен простой публичный HTTPS с автоматическими сертификатами Let’s Encrypt. |
deploy/examples/angie |
Нужен автоматический HTTPS как у Caddy, но с конфигурацией в Nginx-синтаксисе (Angie - форк Nginx с нативным ACME). |
deploy/examples/nginx |
Уже используете Nginx и готовы положить TLS-сертификаты рядом с примером. |
deploy/examples/newt |
Публикуете сервисы через Pangolin/Newt без входящих портов на сервере приложения. |
deploy/examples/no-proxy |
Нужно напрямую открыть HTTP-порты backend/frontend или проверить стек за внешним TLS-терминатором. |
deploy/examples/split-protected-upstream |
Frontend и backend на разных серверах; frontend nginx проксирует /api к protected/private backend upstream. |
deploy/examples/rathole |
Frontend и backend на разных серверах, WebApp API plane идет через приватный Rathole tunnel. |
Уже установленная Remnawave через eGames - использовать ее Nginx/TLS в wizard |
Remnawave Panel уже стоит на этом же хосте через eGamesAPI/remnawave-reverse-proxy; wizard использует no-proxy compose, добавляет backend/Mini App маршруты в найденный nginx.conf eGames и после миграции перечитывает Nginx. |
Caddy (рекомендуемый вариант)
Заголовок раздела «Caddy (рекомендуемый вариант)»Caddy подходит, если DNS-записи WEBHOOK_HOST и MINIAPP_HOST смотрят на сервер приложения, а входящие 80/tcp и 443/tcp открыты.
Минимально поменяйте в .env:
WEBHOOK_HOSTиMINIAPP_HOST;BOT_TOKEN,ADMIN_IDS;POSTGRES_PASSWORD;WEBAPP_SESSION_SECRET,WEBHOOK_SECRET_TOKEN;PANEL_API_URL,PANEL_API_KEY,PANEL_WEBHOOK_SECRET.
Если нужна нестандартная логика Caddy, правьте Caddyfile рядом с compose и перезапускайте:
В стандартном Caddyfile есть global log filter для X-Telegram-Bot-Api-Secret-Token;
если заменяете файл целиком, сохраните этот фильтр, чтобы webhook secret не попадал в логи Caddy.
Angie - форк Nginx от бывших разработчиков ядра Nginx с нативной поддержкой ACME:
сертификаты Let’s Encrypt выпускаются и продлеваются автоматически, как в Caddy, но
конфигурация остается в привычном Nginx-синтаксисе. Вариант подходит, если DNS-записи
WEBHOOK_HOST и MINIAPP_HOST смотрят на сервер приложения, а входящие 80/tcp и
443/tcp открыты.
Минимально поменяйте в .env:
WEBHOOK_HOSTиMINIAPP_HOST;BOT_TOKEN,ADMIN_IDS;POSTGRES_PASSWORD;WEBAPP_SESSION_SECRET,WEBHOOK_SECRET_TOKEN;PANEL_API_URL,PANEL_API_KEY,PANEL_WEBHOOK_SECRET.
Hostnames из .env подставляются в конфиг при старте контейнера: образ
docker.angie.software/angie:templated рендерит angie.conf.template через gomplate
(плейсхолдеры {{.Env.WEBHOOK_HOST}} и {{.Env.MINIAPP_HOST}}). ACME-аккаунт и
сертификаты живут в volume remnawave-minishop-angie-acme (/var/lib/angie/acme),
поэтому пересоздание контейнера не приводит к повторному выпуску сертификатов. После
самого первого старта Angie начинает отвечать на 443 только после выпуска первого
сертификата - обычно это занимает меньше минуты.
Если нужна нестандартная логика Angie, правьте angie.conf.template рядом с compose и перезапускайте:
Nginx-вариант поднимает Nginx в той же Docker-сети, что и приложение:
WEBHOOK_HOSTпроксируется вbackend:8080;MINIAPP_HOSTпроксируется вfrontend:80;frontendсам проксирует внутренние/api,/authи ассеты тем вbackend:8081.
Положите TLS-сертификаты в ssl/:
Имена папок должны совпадать с WEBHOOK_HOST и MINIAPP_HOST в .env.
Если нужно поменять заголовки, лимиты или TLS-настройки, правьте nginx.conf.template и перезапускайте Nginx:
Pangolin / Newt
Заголовок раздела «Pangolin / Newt»Этот вариант не открывает входящие порты на сервере приложения. Newt подключается к Pangolin, а публичные домены настраиваются ресурсами в панели Pangolin.
В .env заполните:
WEBHOOK_HOSTиMINIAPP_HOST- публичные домены ресурсов в Pangolin;PANGOLIN_ENDPOINT,NEWT_ID,NEWT_SECRET- значения из настроек site/client в Pangolin;- обычные переменные приложения:
BOT_TOKEN,ADMIN_IDS,POSTGRES_PASSWORD, секреты и доступ к Remnawave.
В Pangolin создайте два HTTP-ресурса для этого Newt site:
| Публичный домен | Upstream |
|---|---|
https://webhooks.example.com |
http://backend:8080 |
https://app.example.com |
http://frontend:80 |
Проверка:
Подключение Pangolin к уже установленному Minishop
Заголовок раздела «Подключение Pangolin к уже установленному Minishop»Профиль Pangolin/Newt выше делает Newt единственным входом в приложение. Если
Minishop уже установлен с другим профилем (Caddy, Angie, Nginx, no-proxy, eGames),
публикацию через Pangolin можно добавить позже обратимым шагом: в install wizard
есть пункты меню «Подключить Web App к Pangolin (Newt)» и «Отключить Web App от
Pangolin (Newt)».
Подключение записывает PANGOLIN_ENDPOINT, NEWT_ID и NEWT_SECRET в .env,
создает дополнительный docker-compose.pangolin.yml с контейнером newt в той
же Docker-сети и включает его через COMPOSE_FILE в .env. Ресурсы в Pangolin
указываются на http://frontend:80 (Mini App) и http://backend:8080
(API/webhook). Отключение останавливает и удаляет контейнер newt, убирает
файл из COMPOSE_FILE и сохраняет значения NEWT_* в .env для быстрого
повторного подключения.
Без обратного прокси
Заголовок раздела «Без обратного прокси»Этот вариант напрямую публикует два HTTP-порта:
- backend/вебхуки:
WEB_SERVER_BIND, по умолчанию0.0.0.0:8080; - frontend/Mini App:
FRONTEND_BIND, по умолчанию0.0.0.0:8082.
Важно: контейнеры приложения сами не выпускают TLS-сертификаты. Для реального вебхука Telegram и Mini App публичные URL должны быть HTTPS. Используйте этот вариант для локальной проверки, внутренней сети или ситуации, когда HTTPS завершается внешней платформой и дальше трафик приходит на эти порты.
Проверка локально:
Корневой docker-compose.yml оставлен для локальной сборки из исходников. Примеры в deploy/examples используют готовые Docker Hub-образы и не требуют указывать -f.
Split frontend/backend
Заголовок раздела «Split frontend/backend»В split-схеме браузер не обращается к backend напрямую. WEBAPP_API_BASE_URL остается /api, а frontend nginx проксирует server-side upstream:
Backend при этом имеет две разные HTTP-плоскости:
backend:8080- публичная webhook plane для Telegram, платежных провайдеров и Remnawave Panel.backend:8081- WebApp API/auth/assets plane для frontend nginx, private network, protected upstream или Rathole.
Protected upstream без дополнительного backend API домена обычно выглядит так:
Backend-side proxy должен требовать X-Minishop-Edge-Token только на /api/*, /auth/*, /open-app, logo/theme/favicon paths к 8081. Webhook routes на 8080 не должны требовать этот token.
Проверки:
Для Rathole frontend-сервер запускает rathole-server, backend-сервер запускает rathole-client, а frontend nginx использует WEBAPP_BACKEND_UPSTREAM=http://rathole-server:18081. Откройте между серверами только Rathole control port, например 2333; service port 18081 наружу не публикуется.
Rathole checklist:
- одинаковый service token в
rathole.server.tomlиrathole.client.toml; - backend client видит
backend:8081; - frontend nginx upstream указывает на
rathole-server:18081; - payment/provider/Panel webhook по-прежнему указывают на backend
WEBHOOK_BASE_URL, а не frontend-домен.
Миграции
Заголовок раздела «Миграции»При обычном старте миграции применяются автоматически:
Для ручного повторного запуска:
Проверить логи миграций:
backend и worker зависят от migrate через service_completed_successfully; если миграции
падают, приложение не стартует поверх неподготовленной БД. При прямом запуске backend или
worker без compose тот же init_db применяет недостающие миграции перед стартом логики сервиса.
Сервисы
Заголовок раздела «Сервисы»backend: aiohttp API, вебхук Telegram, платежные вебхуки, вебхуки панели, проверка здоровья/healthz.worker: TariffTrafficWorker, задачи синхронизации с панелью, обработка рассылок, потребители очереди вебхуков.frontend: статические Svelte-ассеты через nginx.postgres: PostgreSQL 17.redis: Redis 7 для FSM, кеша, rate-limit, очередей и locks.
В продакшен-примерах внешний доступ добавляют caddy, angie, nginx, newt или прямые ports в соответствующем варианте из deploy/examples.
Логи и проверка
Заголовок раздела «Логи и проверка»Эндпоинты проверки здоровья:
В обычном compose backend публикуется на 127.0.0.1:${WEB_SERVER_PORT:-8080}, frontend на
127.0.0.1:${FRONTEND_PORT:-8082}. В новых продакшен-примерах проверяйте bind-переменные
конкретной папки: HTTP_BIND, HTTPS_BIND, WEB_SERVER_BIND или FRONTEND_BIND.
Обновление
Заголовок раздела «Обновление»Локальная сборка из репозитория:
Если нужно пересобрать только образы приложения:
Образы GHCR и Docker Hub
Заголовок раздела «Образы GHCR и Docker Hub»Образы приложения называются единообразно:
Чтобы собрать и сразу опубликовать все три образа в GHCR и Docker Hub, сначала выполните логин в оба registry:
PowerShell-вариант:
По умолчанию скрипты используют:
IMAGE_REGISTRIES=ghcr.io docker.ioIMAGE_NAMESPACE=3252a8IMAGE_PREFIX=remnawave-minishopTARGETS=backend worker frontendDOCKERFILE=deploy/docker/Dockerfile
Если нужен только один registry или другой namespace, переопределите переменные:
Старые раздельные команды тоже остаются:
Для PowerShell есть варианты scripts/docker-build-images.ps1 и
scripts/docker-push-images.ps1. Если публикуете образы в другой registry, namespace или с другим
префиксом имени, переопределите IMAGE_NAMESPACE, IMAGE_REGISTRY или IMAGE_PREFIX.
Для совместимости оставлены Docker Hub-only скрипты:
PowerShell-вариант:
Если PowerShell блокирует локальные скрипты ошибкой PSSecurityException / Execution Policy,
запустите те же скрипты с обходом политики только для текущего процесса:
Этот bypass действует только для запущенного процесса powershell и не меняет системную политику.
Масштабирование
Заголовок раздела «Масштабирование»В текущих Compose-файлах заданы явные container_name, поэтому docker compose --scale для
backend, frontend и worker не используется: Docker не может создать несколько контейнеров с
одним именем. Если понадобится горизонтальное масштабирование, уберите container_name у
масштабируемых сервисов или перенесите конфигурацию в orchestrator.
Состояние FSM, rate-limit и краткоживущие кеши вынесены в Redis, а tariff tick защищен Redis distributed lock; код подготовлен к нескольким репликам, но текущие Compose-файлы ориентированы на фиксированные имена контейнеров.
Данные и volumes
Заголовок раздела «Данные и volumes»Продакшен compose использует именованные volumes:
postgres-data;redis-data; В Caddy-варианте также используютсяcaddy-dataиcaddy-config, в Angie-варианте -angie-acme(ACME-аккаунт и сертификаты Let’s Encrypt).
Файлы приложения монтируются из локальной папки ./data рядом с выбранным docker-compose.yml в
/app/data; внутри нее лежат тарифы, темы, логотипы и прочие файловые данные приложения.
Тот же /app/data должен быть смонтирован в migrate, backend и worker. Это важно для data/tariffs.json: docker compose run --rm migrate читает тот же каталог тарифов, что и приложение. В текущих compose-файлах этот mount уже есть у всех трех сервисов.
Перед первым запуском на сервере заранее дайте права пользователю контейнера 10001:
Проверка прав:
Резервная копия PostgreSQL
Заголовок раздела «Резервная копия PostgreSQL»Для штатных автоматических ZIP-бэкапов, отправки в Telegram и восстановления через админку используйте раздел бэкапы и восстановление. Команды ниже - минимальный ручной fallback для PostgreSQL.
Восстановление в чистую БД:
Обратный прокси
Заголовок раздела «Обратный прокси»Готовые reverse-proxy примеры описаны выше:
- Caddy - автоматический HTTPS;
- Angie - автоматический HTTPS в Nginx-синтаксисе;
- Nginx - сертификаты кладутся рядом в
ssl/; - Newt/Pangolin - без входящих портов на сервере приложения.
Во всех вариантах схема одинаковая:
- webhook/backend-домен целиком идет в
backend:8080; - Mini App/frontend-домен целиком идет в
frontend:80; - API/auth/theme routes Mini App дальше проксируются frontend nginx в
backend:8081.
Для платежных провайдеров с IP allowlist важно, чтобы reverse proxy передавал реальный IP
отправителя в X-Forwarded-For, а backend доверял IP последнего proxy-hop через
TRUSTED_PROXIES. Готовые профили caddy, angie, nginx и newt уже доверяют loopback и
private ranges (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, fc00::/7), чтобы
Docker/LAN/Kubernetes proxy не ломал проверки YOOKASSA, FREEKASSA_TRUSTED_IPS,
WATA_TRUSTED_IPS, HELEKET_TRUSTED_IPS и PAYKILLA_TRUSTED_IPS. Если в вашей
Docker-сети есть недоверенные контейнеры, сузьте TRUSTED_PROXIES до конкретного IP
Caddy/Angie/Nginx/Newt. Для домена за Cloudflare backend безопасно принимает реальный адрес из
CF-Connecting-IP, когда ближайший внешний hop входит в официальные сети Cloudflare;
добавлять эти сети в TRUSTED_PROXIES не требуется. Trust-all режим возможен через
0.0.0.0/0,::/0, но используйте его
только когда backend недоступен напрямую, а внешний proxy очищает входящий X-Forwarded-For.
Минимальная логика Caddy:
Минимальная логика Nginx такая же: webhooks.example.com проксируется в backend:8080,
app.example.com - в frontend:80. В deploy/examples/nginx/nginx.conf.template уже есть
заголовки X-Forwarded-*, редирект HTTP -> HTTPS и пути сертификатов.
Переменный env-файл
Заголовок раздела «Переменный env-файл»По умолчанию compose читает .env. Для smoke-тестов или отдельного окружения можно подставить
другой файл:
Dev dry-run рядом с production
Заголовок раздела «Dev dry-run рядом с production»Для проверки фичей на той же Remnawave Panel поднимайте dev-стек с отдельным
env-файлом, отдельным Telegram-ботом и локальной БД.
В dev-режиме приложение продолжает читать пользователей, squads, devices и
статистику из живой панели, но записи в пользователей Remnawave не отправляет:
payload валидируется, а в логах появляется строка вида
[PANEL DRY-RUN OK] would PATCH /users ....
Минимальный фрагмент .env.dev:
Запуск:
PANEL_WRITE_MODE=live можно поставить только для отдельной тестовой Remnawave
Panel, потому что этот режим реально меняет пользователей панели.
Если второй стек запускается на том же хосте, дополнительно разведите порты:
для корневого compose используйте WEB_SERVER_PORT и FRONTEND_PORT, а для
production examples без встроенного TLS - WEB_SERVER_BIND и FRONTEND_BIND.
Если production на другом сервере, локальные порты можно оставить стандартными.