Установка
Требования
Заголовок раздела «Требования»- Linux сервер или VPS
- Установленные Docker и Docker Compose
- Доменное имя с SSL-сертификатом
- Реверс-прокси (Caddy или Nginx)
- Установленная и настроенная панель Remnawave
- Файл Docker образа приватной версии (
.tar)
Варианты установки
Заголовок раздела «Варианты установки»Выберите способ установки в зависимости от вашей конфигурации:
Установка рядом с панелью Remnawave
Заголовок раздела «Установка рядом с панелью Remnawave»Используйте этот способ, если бот будет работать на том же сервере, что и панель Remnawave. Бот подключается к Remnawave через внутреннюю Docker-сеть.
-
Создайте директорию проекта
Окно терминала mkdir -p /opt/private-remnawave-telegram-shop-botcd /opt/private-remnawave-telegram-shop-bot -
Загрузите Docker образ
Скачайте файл образа из приватного канала.
Окно терминала docker load -i rwp_shop-<VERSION>.tar -
Создайте необходимые директории
Окно терминала mkdir -p uploads translationssudo chmod -R 777 uploads translations -
Скачайте файлы переводов
Скачайте
en.jsonиru.jsonиз приватного канала и поместите в папкуtranslations:Окно терминала # Скопируйте скачанные файлы в директорию translationscp en.json ru.json ./translations/ -
Создайте конфигурацию Docker Compose
Окно терминала nano compose.yamlname: rwp_shopservices:bot:image: rwp_shop:<VERSION>container_name: rwp_shoprestart: unless-stoppedports:- "127.0.0.1:9912:8080"depends_on:db:condition: service_healthyvolumes:- ./translations:/translations- ./uploads:/uploads- /etc/machine-id:/etc/machine-id:roenvironment:- REMNAWAVE_URL=${REMNAWAVE_URL}- REMNAWAVE_TOKEN=${REMNAWAVE_TOKEN}- TELEGRAM_TOKEN=${TELEGRAM_TOKEN}- ADMIN_TELEGRAM_ID=${ADMIN_TELEGRAM_ID}- DATABASE_URL=postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB}?sslmode=disable- BOT_ADMIN_URL=${BOT_ADMIN_URL}- LOG_LEVEL=${LOG_LEVEL:-info}- ACCESS_LOG_ENABLED=${ACCESS_LOG_ENABLED:-true}- ACCESS_LOG_PATH=${ACCESS_LOG_PATH:-}- LICENSE_KEY=${LICENSE_KEY:-}networks:- remnawave-networkdb:image: postgres:17-alpinecontainer_name: rwp_shop_dbrestart: unless-stoppedenvironment:- POSTGRES_USER=${POSTGRES_USER}- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}- POSTGRES_DB=${POSTGRES_DB}- TZ=UTCports:- "127.0.0.1:9999:5432"volumes:- rwp_shop_db_data:/var/lib/postgresql/datahealthcheck:test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]interval: 3stimeout: 10sretries: 3networks:- remnawave-networkvolumes:rwp_shop_db_data:networks:remnawave-network:name: remnawave-networkexternal: true -
Создайте файл окружения
Окно терминала nano .envОкно терминала # Подключение к Remnawave (внутренняя Docker-сеть)REMNAWAVE_URL=http://remnawave:3000REMNAWAVE_TOKEN=ваш_api_токен_remnawave# TelegramTELEGRAM_TOKEN=ваш_токен_telegram_ботаADMIN_TELEGRAM_ID=123456789,987654321# База данныхPOSTGRES_USER=postgresPOSTGRES_PASSWORD=postgresPOSTGRES_DB=postgres# URL админ-панели (требуется HTTPS)BOT_ADMIN_URL=https://bot.example.com# Логирование (опционально)# LOG_LEVEL=info# ACCESS_LOG_ENABLED=true# ACCESS_LOG_PATH=LICENSE_KEY= -
Добавьте volume machine-id для лицензии
Лицензия привязана к уникальному идентификатору вашего сервера. Добавьте этот volume в
compose.yamlв секциюbot:volumes:- ./translations:/translations- ./uploads:/uploads- /etc/machine-id:/etc/machine-id:ro -
Запустите бота
Окно терминала docker compose up -d
Установка на отдельном сервере
Заголовок раздела «Установка на отдельном сервере»Используйте этот способ, если бот будет работать на другом сервере, отличном от панели Remnawave. Бот подключается к Remnawave через внешний HTTPS URL.
-
Создайте директорию проекта
Окно терминала mkdir -p /opt/private-remnawave-telegram-shop-botcd /opt/private-remnawave-telegram-shop-bot -
Загрузите Docker образ
Скачайте файл образа из приватного канала.
Окно терминала docker load -i rwp_shop-<VERSION>.tar -
Создайте необходимые директории
Окно терминала mkdir -p uploads translationssudo chmod -R 777 uploads translations -
Скачайте файлы переводов
Скачайте
en.jsonиru.jsonиз приватного канала и поместите в папкуtranslations:Окно терминала # Скопируйте скачанные файлы в директорию translationscp en.json ru.json ./translations/ -
Создайте конфигурацию Docker Compose
Окно терминала nano compose.yamlname: rwp_shopservices:bot:image: rwp_shop:<VERSION>container_name: rwp_shoprestart: unless-stoppedports:- "127.0.0.1:9912:8080"depends_on:db:condition: service_healthyvolumes:- ./translations:/translations- ./uploads:/uploads- /etc/machine-id:/etc/machine-id:roenvironment:- REMNAWAVE_URL=${REMNAWAVE_URL}- REMNAWAVE_TOKEN=${REMNAWAVE_TOKEN}- TELEGRAM_TOKEN=${TELEGRAM_TOKEN}- ADMIN_TELEGRAM_ID=${ADMIN_TELEGRAM_ID}- DATABASE_URL=postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB}?sslmode=disable- BOT_ADMIN_URL=${BOT_ADMIN_URL}- LOG_LEVEL=${LOG_LEVEL:-info}- ACCESS_LOG_ENABLED=${ACCESS_LOG_ENABLED:-true}- ACCESS_LOG_PATH=${ACCESS_LOG_PATH:-}- LICENSE_KEY=${LICENSE_KEY:-}db:image: postgres:17-alpinecontainer_name: rwp_shop_dbrestart: unless-stoppedenvironment:- POSTGRES_USER=${POSTGRES_USER}- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}- POSTGRES_DB=${POSTGRES_DB}- TZ=UTCports:- "127.0.0.1:9999:5432"volumes:- rwp_shop_db_data:/var/lib/postgresql/datahealthcheck:test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]interval: 3stimeout: 10sretries: 3volumes:rwp_shop_db_data: -
Создайте файл окружения
Окно терминала nano .envОкно терминала # Подключение к Remnawave (внешний HTTPS URL)REMNAWAVE_URL=https://panel.example.comREMNAWAVE_TOKEN=ваш_api_токен_remnawave# TelegramTELEGRAM_TOKEN=ваш_токен_telegram_ботаADMIN_TELEGRAM_ID=123456789,987654321# База данныхPOSTGRES_USER=postgresPOSTGRES_PASSWORD=postgresPOSTGRES_DB=postgres# URL админ-панели (требуется HTTPS)BOT_ADMIN_URL=https://bot.example.com# Логирование (опционально)# LOG_LEVEL=info# ACCESS_LOG_ENABLED=true# ACCESS_LOG_PATH=LICENSE_KEY= -
Добавьте volume machine-id для лицензии
Лицензия привязана к уникальному идентификатору вашего сервера. Добавьте этот volume в
compose.yamlв секциюbot:volumes:- ./translations:/translations- ./uploads:/uploads- /etc/machine-id:/etc/machine-id:ro -
Запустите бота
Окно терминала docker compose up -d
Настройка реверс-прокси
Заголовок раздела «Настройка реверс-прокси»Добавьте в Caddyfile:
bot.example.com { @html path_regexp \.html$|^/$ header @html Cache-Control "no-cache, no-store, must-revalidate"
@assets_js path /assets/*.js header @assets_js Cache-Control "no-cache, no-store, must-revalidate"
@immutable { path /assets/* not path *.js } header @immutable Cache-Control "public, max-age=31536000, immutable"
reverse_proxy 127.0.0.1:9912}Перезапустите Caddy:
sudo systemctl reload caddyСоздайте конфиг:
sudo nano /etc/nginx/sites-available/bot.example.comserver { listen 80; server_name bot.example.com;
location ~* \.html$ { add_header Cache-Control "no-cache, no-store, must-revalidate" always; proxy_pass http://127.0.0.1:9912; proxy_set_header Host $host; 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; }
location ~* ^/assets/.*\.js$ { add_header Cache-Control "no-cache, no-store, must-revalidate" always; proxy_pass http://127.0.0.1:9912; proxy_set_header Host $host; 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; }
location /assets/ { add_header Cache-Control "public, max-age=31536000, immutable" always; proxy_pass http://127.0.0.1:9912; proxy_set_header Host $host; 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; }
location / { proxy_pass http://127.0.0.1:9912; proxy_set_header Host $host; 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;
client_max_body_size 50M; }}Активируйте и перезапустите:
sudo ln -s /etc/nginx/sites-available/bot.example.com /etc/nginx/sites-enabled/sudo nginx -tsudo systemctl reload nginxПроверка установки
Заголовок раздела «Проверка установки»docker compose logs -f botНастройка access-логов с ротацией
Заголовок раздела «Настройка access-логов с ротацией»Для записи access-логов в файл с автоматической ротацией:
-
Создайте директорию для логов
Окно терминала mkdir -p logssudo chmod 777 logs -
Добавьте volume в compose.yaml
В секции
botдобавьте:volumes:- ./translations:/translations- ./uploads:/uploads- ./logs:/logs -
Укажите путь к логам в .env
Окно терминала ACCESS_LOG_PATH=/logs/access.log -
Перезапустите бота
Окно терминала docker compose up -d -
Установите logrotate (если не установлен)
Окно терминала # Debian/Ubuntusudo apt update && sudo apt install -y logrotate# CentOS/RHEL/Fedorasudo dnf install -y logrotate -
Создайте конфиг logrotate
Окно терминала sudo nano /etc/logrotate.d/rwp-shop/opt/private-remnawave-telegram-shop-bot/logs/access.log {dailyrotate 14compressdelaycompressmissingoknotifemptycopytruncate} -
Проверьте конфигурацию
Окно терминала sudo logrotate -d /etc/logrotate.d/rwp-shopФлаг
-dзапускает в debug-режиме без реальной ротации. -
Тестовый запуск ротации
Окно терминала sudo logrotate -f /etc/logrotate.d/rwp-shopФлаг
-fпринудительно выполняет ротацию.
| Параметр | Описание |
|---|---|
daily | Ротация раз в день |
rotate 14 | Хранить 14 архивов |
compress | Сжимать архивы gzip |
delaycompress | Сжимать со второго архива |
missingok | Не ругаться если файла нет |
notifempty | Не ротировать пустой файл |
copytruncate | Копировать и обрезать без перезапуска |
S3 хранилище (опционально)
Заголовок раздела «S3 хранилище (опционально)»По умолчанию загруженные файлы (вложения поддержки, изображения FAQ, файлы партнёров) хранятся локально в директории ./uploads. Опционально можно использовать S3-совместимое хранилище (MinIO, RustFS, AWS S3 и др.) для лучшей масштабируемости и надёжности.
-
Добавьте переменные S3 в .env
Окно терминала # S3 хранилище (опционально)S3_ENABLED=trueS3_ENDPOINT=http://rustfs:9000S3_ACCESS_KEY=your_access_keyS3_SECRET_KEY=your_secret_keyS3_PUBLIC_URL=https://s3.example.com -
Добавьте сервис S3 в compose.yaml (при использовании RustFS)
rustfs:image: ghcr.io/rustfs/rustfs:latestcontainer_name: rwp_shop_rustfsrestart: unless-stoppedcommand: server /data --console-address ":9001"environment:- RUSTFS_ROOT_USER=your_access_key- RUSTFS_ROOT_PASSWORD=your_secret_keyvolumes:- rustfs_data:/dataports:- "127.0.0.1:9001:9001"networks:- remnawave-networkДобавьте volume:
volumes:rwp_shop_db_data:rustfs_data: -
Настройте reverse proxy для S3
Добавьте поддомен для публичного доступа к S3 (требуется для presigned URLs):
s3.example.com {reverse_proxy rustfs:9000}server {listen 443 ssl http2;server_name s3.example.com;location / {proxy_pass http://127.0.0.1:9000;proxy_set_header Host $host;client_max_body_size 100M;}} -
Перезапустите бота
Окно терминала docker compose up -d
Справка по портам
Заголовок раздела «Справка по портам»| Сервис | Внутренний порт | Рекомендуемый внешний |
|---|---|---|
| Bot HTTP | 8080 | 9912 или 12345 |
| PostgreSQL | 5432 | - |
После установки
Заголовок раздела «После установки»После установки:
- Откройте
https://bot.example.comв Telegram Mini App - Войдите с вашим админским Telegram-аккаунтом
- Настройте параметры в админ-панели:
- Платёжные системы
- Тарифные планы
- Брендинг
- Роли и разрешения
Все остальные настройки управляются через UI админ-панели.
Полезные советы
Заголовок раздела «Полезные советы»Добавление кнопки меню в Telegram
Заголовок раздела «Добавление кнопки меню в Telegram»Чтобы добавить кнопку “Open” в Telegram, которая открывает личный кабинет вместо набора команд:
- Откройте @BotFather
- Выберите вашего бота
- Перейдите в Bot Settings → Menu Button
- Укажите URL вашего дашборда:
https://bot.example.com
Это добавит кнопку в чате Telegram, которая открывает Mini App с личным кабинетом пользователя.