# discord-bot — for the bot dev Start with **AGENT.md** in this folder: the stack, the rules, the layout, the web-UI auth contract. Your code goes in this folder (`bot/app/`). The container runs `python -u /app/main.py` and restarts it if it exits. No `main.py` yet → the container idles and logs a hint. ## Day to day (on the server, in ~/vanguard-stream) docker compose logs -f discord-bot # live log docker compose restart discord-bot # after editing code docker compose build discord-bot && docker compose up -d discord-bot # after editing requirements.txt docker compose exec discord-bot python # a REPL inside the container Edit files directly in `~/vanguard-stream/bot/app/` (they are bind-mounted) or scp them up. ## Environment the container gives you | var | value | |-----|-------| | `DISCORD_BOT_TOKEN` | from `.env` (bundle root) — the Bot added to the existing Authentik Discord application | | `DISCORD_GUILD_ID` | the server | | `DB_HOST` / `DB_PORT` | `host.docker.internal` / `3306` (MariaDB runs on the host network) | | `DB_NAME` / `DB_USER` / `DB_PASSWORD` | your own database + user (`vanguardbot` / `bot` / generated) | | `MEDIA_CLIPS` | `/media/clips` — rw mount of `/srv/media/clips` (folder per user, for clip submissions) | | `/data` | persistent scratch dir owned by the bot | | `WEB_HOST` / `WEB_PORT` | `0.0.0.0` / `8000` — your web UI; public as `https://bot./` via Caddy + Authentik | | `WEB_PUBLIC_URL` | `https://bot.` for absolute links | | `AUTH_HEADER_USER` / `_GROUPS` / `_EMAIL` | `X-Authentik-Username` / `X-Authentik-Groups` / `X-Authentik-Email` — identity injected by Caddy, trust these, implement no login | | `TZ` | America/New_York | SQLAlchemy URL: `mysql+pymysql://{DB_USER}:{DB_PASSWORD}@{DB_HOST}:{DB_PORT}/{DB_NAME}` async: `mysql+aiomysql://...` ## Database from your own machine MariaDB is reachable directly: `ovh1.dumpstervigilantes.rip:3306`, user `bot`, database `vanguardbot`, password from the admin (`./configure.py --show` on the server). Root is local-only. New connections are rate limited at the firewall; if yours get dropped, ask the admin to add your IP to `db_allow`. ## Conventions - Run as uid 1000 (files you write under `/media/clips` are owned like everything else there). - If you write clips: `/media/clips//.mp4` plus `.json` with `{"timestamp": "", "source": "medal", "source_url": "...", "uploader": "...", "title": "..."}` — the Jellyfin plugin reads that sidecar for the exact recording time. - Log to stdout; the container captures it.