Gandhara VPN
Remnawave backend, PostgreSQL, Valkey, subscription page и Remnanode. Основная панель: panelka.404.mn.
Внутренняя документация
Живая шпаргалка по нашим панелям, контейнерам, базам, ботам, Remnawave API, бэкапам и типовым эксплуатационным действиям.
Карта проекта
Remnawave backend, PostgreSQL, Valkey, subscription page и Remnanode. Основная панель: panelka.404.mn.
Express и SQLite. Тянет клиентов из Remnawave API, считает оплату, напоминания, рефералов и маржу.
Операторская панель, PostgreSQL, Telegram bot и Discord bot. Тикеты обновляются онлайн.
Self-hosted SSH vault с командным доступом через браузер и общей командной базой хостов.
DNS и Caddy
| Домен | Назначение | Upstream |
|---|---|---|
| panelka.404.mn | Главная Remnawave панель | remnawave:3000 |
| subscription.gandhara.404.mn | Страница подписки | remnawave-subscription-page:3010 |
| gandhara.404.mn | Бухгалтерия | gandhara-site:1328 |
| support.gandhara.404.mn | Support panel | web + api route |
| skiff.gandhara.404.mn | Skiff SSH vault | skiff:8080 |
| docs.gandhara.404.mn | Эта документация | Caddy file_server |
Docker
remnawave, remnawave-db, remnawave-redis, remnawave-subscription-page, remnanode.
support-panel-api, support-panel-web, support-panel-postgres-1, support-panel-telegram-bot-1, support-panel-discord-bot-1.
gandhara-site, skiff, caddy, amnezia-awg2.
sudo docker ps
sudo docker volume ls
sudo docker network ls
Runbook
cd /opt/remnawave
sudo docker compose up -d remnawave
sudo docker compose ps remnawave
sudo docker logs --tail 80 remnawave
docker restart remnawave-subscription-page
sudo docker logs --tail 80 remnawave-subscription-page
cd /opt/support-panel
sudo docker compose -f docker-compose.prod.yml up -d --build
sudo docker compose -f docker-compose.prod.yml ps
cd /opt/support-panel
sudo docker compose -f docker-compose.prod.yml restart telegram-bot discord-bot
sudo docker logs --tail 80 support-panel-telegram-bot-1
sudo docker logs --tail 80 support-panel-discord-bot-1
VPN core
/opt/remnawave/docker-compose.yml.remnawave-db-data.valkey-socket./opt/remnawave/frontend-custom смонтирован read-only в /opt/app/frontend./tmp/patch-remna-custom-icons.py.cd /opt/remnawave
sudo docker compose up -d remnawave
curl -fsSkI https://panelka.404.mn
Учёт
Проект: /opt/gandhara-site. Контейнер: gandhara-site. SQLite хранится в volume gandhara-site_gandhara-site-data как /data/gandhara.db.
Синхронизация пользователей идёт через Remnawave API. Ручное обновление вызывает /api/users?sync=force.
ADMIN_EMAIL=operator
ADMIN_PASSWORD=strong-password
AUTH_SECRET=at-least-32-random-characters
REMNAWAVE_API_BASE=http://remnawave:3000
REMNAWAVE_API_TOKEN=secret-token
REMNAWAVE_PROXY_HOST=panelka.404.mn
REMNAWAVE_SYNC_INTERVAL_MS=60000
Не учитывать в оплате подписки считает клиента оплаченным, но не включает его в маржу и денежный отчёт.Маржа показывает сумму, которую реально имеем после исключений и реферальных скидок.Ticket Hub
OPEN Открытые, ANSWERED Отвеченные, CLOSED Закрытые.
Назначение внутри открытого тикета: Amnezis, xAikq, Natsunagi, Citation. На закрытых тикетах исполнитель не отображается.
Список, сообщения, статусы и исполнитель подтягиваются онлайн, чтобы несколько операторов видели одно состояние.
GET /health
POST /auth/login
GET /tickets
GET /tickets/:id
PATCH /tickets/:id/assignee
POST /tickets/:id/reply
PATCH /tickets/:id/status
GET /bot/tickets/active
POST /bot/tickets
POST /bot/tickets/by-channel/:channelId/messages
GET /bot/users/:source/:externalUserId/preferences
PUT /bot/users/:source/:externalUserId/preferences
JWT_SECRET=secret
BOT_API_SECRET=secret
ADMIN_EMAIL=login
ADMIN_PASSWORD=strong-password
TELEGRAM_BOT_TOKEN=token
DISCORD_BOT_TOKEN=token
DISCORD_CLIENT_ID=id
DISCORD_TICKET_CATEGORY_ID=optional
DISCORD_SUPPORT_ROLE_ID=optional
CORS_ORIGIN=https://support.gandhara.404.mn
Интеграции
/start и /menu показывают меню./ticket открывает поддержку без повторного приветственного экрана./setup-tickets публикует панель создания тикетов./ticket открывает форму тикета.SSH vault
Skiff хранит SSH-хосты и открывает терминал в браузере. Проект расположен в /opt/skiff, контейнер skiff, данные в /opt/skiff/data.
cd /opt/skiff
sudo docker compose -f docker-compose.prod.yml up -d --build
sudo docker logs --tail 80 skiff
Данные
Общий механизм живёт в /opt/gandhara-backups, запускается cron каждый день в 03:20 UTC, хранит данные в /home/amnezis/backups/databases, retention по умолчанию 30 дней.
BACKUP_ROOT=/home/amnezis/backups/databases RETENTION_DAYS=30 bash /opt/gandhara-backups/scripts/backup-databases.sh
crontab -l
tail -n 80 /home/amnezis/backups/databases/backup.log
| Что | Где | Формат |
|---|---|---|
| Remnawave PostgreSQL | remnawave-postgres | pg_dumpall sql.gz |
| Support PostgreSQL | support-panel-postgres | pg_dumpall sql.gz |
| Remnawave Valkey | remnawave-valkey | rdb.gz |
| Skiff data | skiff-data | tar.gz |
| Бухгалтерия SQLite volume | gandhara-site-data | tar.gz |
Безопасность
x-bot-api-secret..env, не в git и не в документации.Проверки
curl -fsSkI https://panelka.404.mn
curl -fsSk https://gandhara.404.mn/healthz
curl -fsSk https://support.gandhara.404.mn/api/health
curl -fsSk https://skiff.gandhara.404.mn/api/health
curl -fsSkI https://docs.gandhara.404.mn
sudo docker logs --tail 100 remnawave
sudo docker logs --tail 100 gandhara-site
sudo docker logs --tail 100 support-panel-api
sudo docker logs --tail 100 support-panel-telegram-bot-1
sudo docker logs --tail 100 support-panel-discord-bot-1
sudo docker logs --tail 100 caddy