Files
remnawave-minishop/docs/deployment.md
T
2026-05-12 16:34:23 +03:00

11 KiB
Raw Blame History

Развертывание

Документ описывает запуск через Docker Compose, маршруты вебхуков и варианты reverse proxy. Перед запуском заполните .env по configuration.md.

Docker Compose

Локальная сборка:

docker compose up -d --build
docker compose logs -f remnawave-minishop

Запуск из готового образа:

IMAGE_TAG=3.1.0 docker compose -f docker-compose-remote-server.yml up -d

docker-compose-remote-server.yml можно использовать как шаблон и заменить image: на нужный образ. По умолчанию используется ghcr.io/3252a8/remnawave-minishop:latest.

Обновление версии

Образ приложения: ghcr.io/3252a8/remnawave-minishop. Тег задаётся переменной окружения IMAGE_TAG (в Compose подставляется как ${IMAGE_TAG:-latest}). Для продакшена разумно закрепить конкретный тег релиза вместо latest, чтобы обновляться осознанно и иметь откат.

Запуск из готового образа (docker-compose-remote-server.yml или свой файл с тем же шаблоном):

  1. Сделайте резервную копию базы (особенно перед крупными обновлениями) — см. раздел «Резервная копия и восстановление PostgreSQL» ниже на этой странице.
  2. Укажите нужный тег, например в .env: IMAGE_TAG=3.2.0 (или экспортируйте переменную перед командой).
  3. Подтяните образ и пересоздайте контейнер приложения (БД при этом не удаляется, том данных сохраняется):
docker compose -f docker-compose-remote-server.yml pull remnawave-minishop
docker compose -f docker-compose-remote-server.yml up -d --no-deps remnawave-minishop

При необходимости перезапустите оба сервиса: docker compose -f docker-compose-remote-server.yml up -d. Флаг --force-recreate добавляют, если нужно гарантированно пересоздать контейнер при неизменённом образе.

Локальная сборка из репозитория (ваш Dockerfile):

git pull
docker compose up -d --build

После обновления проверьте логи (docker compose logs -f remnawave-minishop), работу бота, вебхуков и Web App. Совместимость с панелью Remnawave — см. раздел «Совместимость» в README.md.

Резервная копия и восстановление PostgreSQL

Имя контейнера БД в типичном Compose — remnawave-minishop-db. Подставьте значения POSTGRES_USER и POSTGRES_DB из .env (на хосте можно выполнить set -a && source .env && set +a перед командами или подставить вручную).

Резервная копия (текстовый SQL)

Логическое дампирование в один файл:

docker exec remnawave-minishop-db pg_dump -U "$POSTGRES_USER" "$POSTGRES_DB" > backup.sql

Такой файл удобно хранить вне сервера. При необходимости добавьте к pg_dump параметры сжатия или расписание через cron.

Восстановление из backup.sql

Дамп выше — обычный текст SQL без удаления существующих объектов. Чтобы накатить его на чистую базу с тем же именем:

  1. Остановите приложение, чтобы не было записей в БД:
docker compose -f docker-compose-remote-server.yml stop remnawave-minishop

(или ваш файл Compose без -f, если работаете из каталога проекта.)

  1. Удалите базу и создайте пустую с тем же именем — пользователь из .env в официальном образе PostgreSQL обычно суперпользователь и может это сделать:
docker exec remnawave-minishop-db dropdb -U "$POSTGRES_USER" "$POSTGRES_DB" --if-exists
docker exec remnawave-minishop-db createdb -U "$POSTGRES_USER" "$POSTGRES_DB"

Если dropdb сообщает, что база занята, убедитесь, что остановлен сервис remnawave-minishop и к базе нет других подключений.

  1. Восстановите данные из файла на хосте:
docker exec -i remnawave-minishop-db psql -U "$POSTGRES_USER" -d "$POSTGRES_DB" < backup.sql
  1. Запустите приложение снова:
docker compose -f docker-compose-remote-server.yml start remnawave-minishop

Проверьте логи и работу бота. При ошибках импорта убедитесь, что версия приложения совместима со схемой в дампе (после обновлений бота иногда нужны шаги из changelog релиза).

Замечание про «накат поверх» без пересоздания БД

Если нужно применить дамп к уже заполненной базе без dropdb, создавайте резервные копии с pg_dump --clean --if-exists — в файл попадут команды DROP перед CREATE, и psql сможет перезаписать объекты. Это разрушительно для текущих данных; перед таким сценарием сделайте отдельный свежий бэкап.

Порты

Порт Назначение
WEB_SERVER_PORT (8080) Telegram webhook, платежные вебхуки, Remnawave webhook.
WEBAPP_SERVER_PORT (8081) Web App / Mini App.

Web App не должен проксироваться на WEB_SERVER_PORT.

Маршруты вебхуков

Проксируйте платежные и системные вебхуки на WEB_SERVER_PORT:

  • https://<webhook-domain>/webhook/yookassa -> http://remnawave-minishop:<WEB_SERVER_PORT>/webhook/yookassa;
  • https://<webhook-domain>/webhook/freekassa -> http://remnawave-minishop:<WEB_SERVER_PORT>/webhook/freekassa;
  • https://<webhook-domain>/webhook/platega -> http://remnawave-minishop:<WEB_SERVER_PORT>/webhook/platega;
  • https://<webhook-domain>/webhook/severpay -> http://remnawave-minishop:<WEB_SERVER_PORT>/webhook/severpay;
  • https://<webhook-domain>/webhook/cryptopay -> http://remnawave-minishop:<WEB_SERVER_PORT>/webhook/cryptopay;
  • https://<webhook-domain>/webhook/panel -> http://remnawave-minishop:<WEB_SERVER_PORT>/webhook/panel.

Telegram webhook устанавливается приложением, если задан WEBHOOK_BASE_URL. Путь формируется как https://<webhook-domain>/<BOT_TOKEN>.

Nginx рядом с Remnawave

Пример upstream и server-блока для домена вебхуков:

upstream remnawave-minishop {
    server remnawave-minishop:8080;
}

map $http_upgrade $connection_upgrade {
    default upgrade;
    "" close;
}

server {
    server_name webhook.domain.com;
    listen 443 ssl;
    http2 on;

    ssl_certificate "/etc/nginx/ssl/webhook_fullchain.pem";
    ssl_certificate_key "/etc/nginx/ssl/webhook_privkey.key";
    ssl_trusted_certificate "/etc/nginx/ssl/webhook_fullchain.pem";

    proxy_http_version 1.1;
    proxy_set_header Host $host;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection $connection_upgrade;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Forwarded-Host $host;
    proxy_set_header X-Forwarded-Port $server_port;
    proxy_send_timeout 60s;
    proxy_read_timeout 60s;
    proxy_intercept_errors on;
    error_page 400 404 500 502 @redirect;

    location / {
        proxy_pass http://remnawave-minishop$request_uri;
    }

    location @redirect {
        return 404;
    }
}

Для Web App используйте отдельный upstream на WEBAPP_SERVER_PORT; пример есть в webapp.md.

SSL для домена вебхуков

Пример выпуска сертификата через acme.sh:

sudo apt-get install cron socat
curl https://get.acme.sh | sh -s email=EMAIL
source ~/.bashrc
ufw allow 80/tcp
ufw reload

acme.sh --set-default-ca --server letsencrypt
acme.sh --issue --standalone -d 'webhook.domain.com' \
  --key-file /opt/remnawave/nginx/webhook_privkey.key \
  --fullchain-file /opt/remnawave/nginx/webhook_fullchain.pem

Если Nginx панели Remnawave запускается в Docker, добавьте сертификаты в volumes сервиса Nginx:

services:
  remnawave-nginx:
    volumes:
      - ./webhook_fullchain.pem:/etc/nginx/ssl/webhook_fullchain.pem:ro
      - ./webhook_privkey.key:/etc/nginx/ssl/webhook_privkey.key:ro

После изменения конфигурации перезапустите Nginx:

cd /opt/remnawave/nginx
docker compose down
docker compose up -d
docker compose logs -f -t

Caddy

Для схемы с Caddy используйте docker-compose-caddy.yml и Caddyfile. Caddy публикует наружу 80 и 443, выпускает TLS-сертификаты и проксирует вебхуки и Web App на разные внутренние порты.

Пример Caddyfile:

webhook.domain.com {
    encode zstd gzip
    reverse_proxy remnawave-minishop:{$WEB_SERVER_PORT:8080}
}

app.domain.com {
    encode zstd gzip
    reverse_proxy remnawave-minishop:{$WEBAPP_SERVER_PORT:8081}
}

В .env укажите:

WEBHOOK_BASE_URL=https://webhook.domain.com
SUBSCRIPTION_MINI_APP_URL=https://app.domain.com/

Запуск:

docker compose -f docker-compose-caddy.yml up -d --build

В BotFather укажите домен Mini App через настройки домена, чтобы он совпадал с SUBSCRIPTION_MINI_APP_URL.

Проверка

docker compose ps
docker compose logs -f remnawave-minishop

Проверьте:

  • бот отвечает в Telegram;
  • Telegram webhook установлен без ошибок в логах;
  • платежные вебхуки доходят до приложения;
  • Remnawave webhook проходит проверку PANEL_WEBHOOK_SECRET;
  • Web App открывается по домену из SUBSCRIPTION_MINI_APP_URL;
  • в BotFather разрешены URL Web App и callback.