# Operations (Runbook) ## Deployment ### Development (bind mount + hot reload) ```bash cd bot docker compose -f docker-compose.dev.yml up -d --build ``` ### Production (immutable image) ```bash git pull docker compose build telegram-bot docker compose up -d telegram-bot ``` Production uses the `production` Dockerfile target: source compiled into `dist/`, deps installed with `--omit=dev`, no host source bind-mount. ## Environment All config via `.env` (see `.env.example`). Secrets in the repo's `../SECRETS.md`. The container joins external network `mem0_net` to reach `mem0-postgres` and `litellm`. ### Memory (user long-term memory, D17) - `SUMMARY_ENABLED` (default `true`) — `false`/`0` disables both `user_memory` reads/writes and summarization (falls back to `NoopMemory`). - `SUMMARY_MODEL` (optional) — LiteLLM model alias for background summarization; empty = reuse `LLM_MODEL` (`mem0-openai`). Set a cheaper alias here if desired. ## Webhook go-live checklist 1. Confirm `bot.digikedai.com` DNS/CF-tunnel route reaches this container (`:8080`). 2. Set `TELEGRAM_WEBHOOK_URL` + `TELEGRAM_WEBHOOK_SECRET` in `.env`. 3. Restart; the bot calls `setWebhook` on boot. 4. Verify: `curl -s https://api.telegram.org/bot/getWebhookInfo` shows the correct URL and no `last_error_message`. ### Deployment notes - **Container**: `digikedai-bot` (build target `production`), restart `unless-stopped`. - **Networks**: joins the external networks that host Postgres/LiteLLM (`mem0_net`) and the ingress (`bridge_hoelee`). - **Ingress**: a Cloudflare tunnel routes the public hostname → **`http://digikedai-bot:8080`** directly (no reverse-proxy hop). The bot's Hono server serves `/health`, `/` (JSON), and `POST //webhook`. - **Webhook secret**: set via `TELEGRAM_WEBHOOK_SECRET` in `.env` (see `.env.example`). - **LLM**: LiteLLM model alias `mem0-openai` (NOT `gpt-5-mini` — LiteLLM only serves declared aliases). - **Redeploy after code change**: `git pull` then `docker compose -f docker-compose.yml up -d --build` (or `--force-recreate` for env-only changes). ## Health checks - HTTP: `GET /health` → `{"status":"ok"}`. - DB: the bot self-migrates on startup; a failed migration aborts boot (fail-fast). - Telegram: `getWebhookInfo` (above) for delivery errors. ## Logs ```bash docker logs -f digikedai-bot ``` JSON in production (pino), pretty in development. Internal errors carry full detail; user-facing replies never expose stack traces or secrets (spec §14.1). ## Backups - Postgres data is on the DSM `mem0` volume (`mem0-postgres`). Backups are the DSM stack's responsibility (duplicati / DSM snapshot); the `bot` database lives inside the same `mem0-postgres` data dir, so it is covered by existing backups. - Conversation audit trail = `message` table. ## Common failures | Symptom | Likely cause | Fix | |---|---|---| | Bot doesn't reply in prod | Webhook not set / route unreachable | `getWebhookInfo`; check tunnel/Traefik; ensure `setWebhook` ran | | Dev bot uses polling unexpectedly | `TELEGRAM_WEBHOOK_URL` unset | Expected in dev; or set the URL for webhook | | Startup aborts at migration | Postgres unreachable / bad password | Check `mem0_net` attachment and `POSTGRES_*` in `.env` | | LLM errors | LiteLLM unreachable or model name wrong | Verify `LLM_BASE_URL`, `LLM_API_KEY`, `LLM_MODEL` | ## Rollback Redeploy a prior image tag (or rebuild from the previous commit): ```bash git checkout docker compose build telegram-bot docker compose up -d telegram-bot ```