НИИLacuna
Свой инстанс Discord-бота Lacuna для НИИ «ТехноПрон».
- Панель: https://lacuna.tehnopron.org
- API: https://api.lacuna.tehnopron.org
- Telegram: https://t.me/nii_tehnopro
Официальные образы ghcr.io/lacunahub/* закрытые. Сборка идёт локально из этого репозитория, приватные npm-пакеты лежат в vendor/.
Как развёрнуто на хосте
Стек крутится не на Proxmox-хосте напрямую, а в LXC. Снаружи его закрывает уже существующий nginx, не контейнерный nginx из апстрима Lacuna.
| Роль | Где |
|---|---|
| Контейнер бота | LXC, Debian 13, hostname lacunabot |
| Сеть контейнера | LAN 10.4.10.0/24, статический IP 10.4.10.90, шлюз 10.4.10.1 |
| Ресурсы | 4 CPU, 8 GB RAM, диск на SSD-хранилище (~50 GB), nesting + keyctl + fuse (нужно для Docker) |
| Автозапуск | LXC onboot=1, Docker restart: unless-stopped |
| Обратный прокси | уже существующий nginx на 10.4.10.2 |
| HTTPS снаружи | DNS на внешний IP, 80/443 как у остальных сайтов; сертификаты Let's Encrypt через certbot на nginx |
Внутри LXC Docker Compose:
| Сервис | Контейнер | Заметки |
|---|---|---|
| MongoDB 7 | lacuna-mongo |
данные в volume, только внутренняя сеть |
| Redis 7 | lacuna-redis |
с паролем из .env |
| Lavalink 4 | lacuna-lavalink |
музыка; порт 2333 наружу не торчит |
| broker | lacuna-broker |
оркестрация шардов через Redis |
| bot | lacuna-bot |
сам Discord-бот |
| api | lacuna-api |
HTTP API, 0.0.0.0:5810 на LXC |
Профиль app (broker/bot/api) поднимается отдельно, когда уже живы mongo/redis/lavalink.
nginx на 10.4.10.2:
https://api.lacuna.tehnopron.org→http://10.4.10.90:5810https://lacuna.tehnopron.org→ статика SPA из/var/www/lacuna(try_filesдля Vue Router history)
Секреты только в /opt/lacuna/.env на LXC. В git их нет (см. .env.example).
Discord-приложение
Создаётся на Discord Developer Portal. В .env нужны LCN_DISCORD_CLIENT_ID, LCN_DISCORD_CLIENT_SECRET, LCN_DISCORD_CLIENT_TOKEN.
Privileged Gateway Intents (вкладка Bot):
- SERVER MEMBERS INTENT
- MESSAGE CONTENT INTENT
OAuth2 Redirects (вкладка OAuth2), без слэша на конце у сайта:
https://lacuna.tehnopron.org
https://api.lacuna.tehnopron.org/authorize/callback
https://api.lacuna.tehnopron.org/authorize/linked-roles/callback
Приглашение бота (подставь свой client id):
https://discord.com/oauth2/authorize?client_id=<CLIENT_ID>&permissions=8&scope=bot%20applications.commands
Повторный деплой
Рабочая директория на LXC: /opt/lacuna.
cd /opt/lacuna
git pull
cp -n .env.example .env # если файла ещё нет; секреты не затирать
# проверь .env: Discord, пароли mongo/redis/lavalink, URL панели и API
docker compose up -d mongo redis lavalink
docker build -f docker/Dockerfile -t lacunabot:local .
docker compose --profile app up -d --force-recreate broker bot api
Первый старт broker ждёт redis/mongo, затем ~20–30 секунд на назначение шарда. В логах бота должно быть connected to discord и added to guild.
Веб-панель
cd /opt/lacuna
# Node 22 + pnpm на LXC
pnpm install --no-frozen-lockfile --filter @lacunabot/web...
pnpm -F @lacunabot/web build
Сборка: apps/web/dist/spa. Её копируют на nginx-хост в /var/www/lacuna (владелец www-data). После выкладки — Ctrl+F5 в браузере.
API пускает запросы панели только с разрешённых referrer. Они лежат в MongoDB, база lcnqm, коллекция internal-storages:
allowedAPIReferrers— в том числеhttps://lacuna.tehnopron.orgpublicAPIPaths—/authorize,/auth,/common/state,/common/versionи webhook-пути
Без записи сервера в Mongo панель открывает гильдию с 404. Документ создаётся при GuildCreate / старте бота (servers.fetch). Если бота добавили, пока события ещё не грузились — перезапусти bot или один раз создай документ через servers.fetch с _id гильдии.
Полезные команды
На LXC:
cd /opt/lacuna
docker compose --profile app ps
docker logs -f lacuna-bot
docker logs -f lacuna-api
docker logs -f lacuna-broker
docker compose --profile app restart bot api broker
nginx (на 10.4.10.2): сайты lacuna.tehnopron.org и api.lacuna.tehnopron.org, сертификат Let's Encrypt, продление как у остальных vhost.
Что не коммитить
.envи любые токены/паролиnode_modules/,dist/,logs/- данные Mongo/Redis (docker volumes)
Имя в Discord и статус бота: НИИLacuna, custom status НИИ "ТехноПрон".