SUBPAGE — страница подписки
Отдельный веб-сервер для страницы подписки пользователей. Рекомендуется размещать на независимом сервере с собственным доменом.
Настоятельно рекомендуется использовать отдельный домен для SUBPAGE, не связанный с доменом бота. Например, если бот на
bot.example.com, для SUBPAGE возьмите другой домен. Это повышает безопасность и позволяет независимо управлять подписками.Если ранее SUBPAGE работал на том же домене, что и бот, и вы решаете вынести его на отдельный сервер — необходимо сменить домен бота на новый, а прежний домен привязать к внешнему SUBPAGE-серверу.
В противном случае клиенты продолжат получать подписку через бота, а не через внешний SUBPAGE. В итоге у вас окажутся два активных домена для одной аудитории, и часть клиентов с устаревшими ссылками будет обслуживаться старым адресом.
Подготовка сервера
- 1Сервер с Ubuntu 24.04, доступ root по SSH
- 2Отдельный домен с A-записью, указывающей на IP этого сервера
Пример:sub.example.com - 3Порты
80и443открыты в файрволе
Установка SUBPAGE
Выполните команду на сервере SUBPAGE (не на сервере бота):
bash <(curl -sSL https://update.3xstore.ru/subpagerm/install.sh)
- 1Установит Python 3.12 и необходимые зависимости
- 2Создаст виртуальное окружение и установит пакеты
- 3Создаст systemd-сервис для автозапуска
- 4Установит CLI-утилиту управления
subpage
Настройка .env — адрес API бота
.env менять не нужно — используется встроенный конфиг и домен бота (сертификаты тоже получать не требуется). Этот шаг актуален только для внешнего сервера SUBPAGE.Откройте редактор через CLI: sudo subpage → Редактировать .env файл.
.env не нужно. Обязателен только адрес API и режим настроек.
Остальные переменные имеют рабочие значения по умолчанию, а при API_CUSTOM_SETTINGS=true
настройки берутся из веб-админки (Настройки → Subpage); значения из .env —
фолбэк на случай недоступности API.
# [ОБЯЗАТЕЛЬНО] Адрес API бота: # внешний сервер → публичный URL бота, напр. https://bot.domain.com # под ботом → значение ниже уже верное, менять не нужно API_BASE_URL=http://127.0.0.1:8282 # [ОПЦИОНАЛЬНО] Прокси до API, если сабка не достучаться напрямую # HTTP: http://user:pass@host:8080 SOCKS5: socks5://user:pass@host:1080 # API_PROXY=socks5://user:pass@proxy.example.com:1080 # [ОБЯЗАТЕЛЬНО] Брать настройки из веб-админки; .env — фолбэк при недоступности API API_CUSTOM_SETTINGS=true
Полное описание всех остальных переменных — в комментариях самого файла .env (в конце файла). После изменений: sudo systemctl restart subpage.
Получение SSL-сертификата (внешний сервер)
- 1Запустите CLI:
sudo subpage - 2В меню выберите Управление Nginx
- 3Выберите Установить и настроить Nginx с SSL
- 4Введите домен SUBPAGE: например
sub.example.com - 5Укажите email для Let's Encrypt — уведомления об истечении сертификата
- 6Скрипт получит сертификат через Certbot и настроит nginx как reverse proxy
80 должен быть свободен. Файрвол настраивается там же в CLI (Управление файрволом).sudo systemctl stop nginx sudo systemctl disable nginx sudo systemctl mask nginx
Порты 80 и 443 должны быть свободны — их займёт Caddy.
sudo curl -fsSL https://get.docker.com | sh
mkdir -p /opt/subpage/caddy && cd /opt/subpage/caddy && nano Caddyfile
{
servers {
protocols h1 h2
}
}
вашдомен.ru {
reverse_proxy 127.0.0.1:3004 {
flush_interval -1
}
}
:443 {
tls internal
respond 204
}
Замените вашдомен.ru на свой домен. Несколько доменов — через запятую: домен1.ru, домен2.ru {.
protocols h1 h2 — без HTTP/3 (QUIC). У Happ на Android иначе часто socket closed: Caddy рвёт поток до конца тела. Блок :443 { respond 204 } отвечает пустышкой только на запросы без SNI вашего домена (сканы по IP). Не ставьте его единственным сайтом на 443.
cd /opt/subpage/caddy && nano docker-compose.yml
services:
caddy:
image: caddy:2.9
container_name: caddy
hostname: caddy
restart: always
network_mode: host
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile
- caddy-ssl-data:/data
- caddy-config:/config
volumes:
caddy-ssl-data:
driver: local
name: caddy-ssl-data
caddy-config:
driver: local
name: caddy-config
docker compose up -d && docker compose logs -f -t
sudo ufw allow 22/tcp comment 'SSH' sudo ufw allow 80/tcp comment 'HTTP' sudo ufw allow 443/tcp comment 'HTTPS' sudo ufw enable
Файрвол также настраивается через CLI: sudo subpage → Управление файрволом.
Добавьте ссылку SUBPAGE в настройки бота
- 1Откройте веб-админку бота > Настройки > Подписка
- 2Найдите параметр
sub_page_url - 3Установите значение:
https://ваш-домен-subpage.com - 4Сохраните настройки
Готово
Проверка работы
sudo systemctl status subpage
sudo journalctl -u subpage -n 50 -f
Логи также доступны в CLI-меню: sudo subpage → Просмотр логов (50 / 100 строк или в реальном времени).
https://ваш-домен/sub/test-uuid — должна появиться страница подписки (ошибка UUID — это нормально).Полезные команды управления
sudo subpage
sudo systemctl start subpage # Запустить sudo systemctl stop subpage # Остановить sudo systemctl restart subpage # Перезапустить sudo systemctl status subpage # Статус sudo systemctl enable subpage # Включить автозапуск sudo systemctl disable subpage # Отключить автозапуск
Управление Subpage из веб-админки
В веб-админке есть отдельный раздел Настройки → Subpage. Он нужен, чтобы менять внешний вид и поведение страницы подписки без ручного редактирования каждого поля в .env.
- Основная информация — проект, тема, ссылки поддержки/сайта, анонс, автообновление, заглушки для истёкшей или заблокированной подписки.
- Ссылки приложений — Happ и INCY по платформам: iOS, Android, APK, Windows, macOS, Linux.
- HTTP-заголовки — таблица заголовков, которые уходят клиентским приложениям вместе с подпиской.
- HWID — лимит устройств по HWID и переключатель «Принудительно требовать X-HWID от приложений». Оба включаются здесь, не в
.env.
API_CUSTOM_SETTINGS=true.