mirror of
https://github.com/whekin/household-bot.git
synced 2026-03-31 19:04:02 +00:00
refactor(deploy): pivot compose target to coolify
Co-authored-by: claw <stanislavkalishin+claw@gmail.com>
This commit is contained in:
126
docs/runbooks/coolify-compose-deploy.md
Normal file
126
docs/runbooks/coolify-compose-deploy.md
Normal file
@@ -0,0 +1,126 @@
|
||||
# Coolify Docker Compose Deployment Plan
|
||||
|
||||
## Goal
|
||||
|
||||
Deploy `household-bot` on a VPS that already runs Coolify, while keeping Supabase external and preserving cloud compatibility in the codebase.
|
||||
|
||||
## Why Coolify-first
|
||||
|
||||
Coolify already provides:
|
||||
|
||||
- Git-based deployments
|
||||
- domains and TLS
|
||||
- environment variable management
|
||||
- Docker Compose deployment support
|
||||
|
||||
That makes it a better target than a hand-rolled VPS deploy workflow for this project.
|
||||
|
||||
## Deployment shape
|
||||
|
||||
Use a Docker Compose deployment in Coolify with three services:
|
||||
|
||||
- `bot` — Telegram webhook/API
|
||||
- `miniapp` — static frontend container
|
||||
- `scheduler` — periodic due-dispatch runner
|
||||
|
||||
Database stays external:
|
||||
|
||||
- Supabase / managed Postgres
|
||||
|
||||
## Compose principles for Coolify
|
||||
|
||||
For Coolify Compose deployments:
|
||||
|
||||
- the compose file is the source of truth
|
||||
- define environment variables inline with `${VAR}` placeholders
|
||||
- let Coolify manage domains/proxying instead of bundling Caddy/Nginx reverse proxy for the public edge
|
||||
- do not rely on external `env_file` paths on the host
|
||||
|
||||
## Scheduler strategy
|
||||
|
||||
Keep the self-hosted scheduled dispatch provider introduced in this PR.
|
||||
|
||||
Runtime model:
|
||||
|
||||
- `bot` handles webhook/API traffic
|
||||
- `scheduler` calls the internal due-dispatch endpoint repeatedly
|
||||
- both services share the same app image build but run different commands
|
||||
|
||||
## Migrations
|
||||
|
||||
For the first Coolify version, run DB migrations from the bot startup command before the server starts.
|
||||
|
||||
This is intentionally pragmatic:
|
||||
|
||||
- no extra one-off deploy script is required
|
||||
- no host SSH deploy step is required
|
||||
- drizzle migrations are idempotent enough for single-service startup usage here
|
||||
|
||||
If the deployment setup matures later, split migrations into a dedicated release/predeploy step.
|
||||
|
||||
## Domains
|
||||
|
||||
Suggested public domains:
|
||||
|
||||
- `household-bot.whekin.dev` -> `bot`
|
||||
- `household.whekin.dev` -> `miniapp`
|
||||
|
||||
Coolify should manage the public routing/TLS for these services.
|
||||
|
||||
## Required Coolify variables
|
||||
|
||||
Core bot/runtime:
|
||||
|
||||
- `DATABASE_URL`
|
||||
- `DB_SCHEMA` (default `public`)
|
||||
- `TELEGRAM_BOT_TOKEN`
|
||||
- `TELEGRAM_WEBHOOK_SECRET`
|
||||
- `TELEGRAM_WEBHOOK_PATH`
|
||||
- `MINI_APP_URL`
|
||||
- `MINI_APP_ALLOWED_ORIGINS`
|
||||
- `SCHEDULER_SHARED_SECRET`
|
||||
- `SCHEDULED_DISPATCH_PROVIDER` (`self-hosted`)
|
||||
|
||||
Optional AI/runtime:
|
||||
|
||||
- `OPENAI_API_KEY`
|
||||
- `PURCHASE_PARSER_MODEL`
|
||||
- `ASSISTANT_MODEL`
|
||||
- `TOPIC_PROCESSOR_MODEL`
|
||||
- assistant timeout/rate-limit variables
|
||||
|
||||
Miniapp:
|
||||
|
||||
- `BOT_API_URL`
|
||||
|
||||
Scheduler:
|
||||
|
||||
- `SCHEDULER_POLL_INTERVAL_MS`
|
||||
- `SCHEDULER_DUE_SCAN_LIMIT`
|
||||
|
||||
## Cloud compatibility rule
|
||||
|
||||
Keep these intact in the app/config layer even if Coolify becomes the main path:
|
||||
|
||||
- Cloud Run compatibility
|
||||
- AWS compatibility
|
||||
- existing cloud-specific scheduler env vars/adapters
|
||||
|
||||
The deployment target changes; the app should not become Coolify-only.
|
||||
|
||||
## Recommended rollout
|
||||
|
||||
1. Add Coolify compose file
|
||||
2. Remove VPS-specific deploy glue from this PR
|
||||
3. Create a Coolify Docker Compose app from the repo
|
||||
4. Fill required variables in Coolify UI
|
||||
5. Assign domains to `bot` and `miniapp`
|
||||
6. Deploy and verify webhook + miniapp + scheduler behavior
|
||||
|
||||
## Notes for later
|
||||
|
||||
Possible future upgrades:
|
||||
|
||||
- add Codex/CodeRabbit review automation around PRs
|
||||
- move migrations to a dedicated release step
|
||||
- codify Coolify resources with Terraform/Pulumi later if that still feels worth it
|
||||
@@ -1,182 +0,0 @@
|
||||
# VPS Docker Compose Deployment Plan
|
||||
|
||||
## Goal
|
||||
|
||||
Make the VPS deployment path first-class without removing the existing Cloud Run / AWS paths.
|
||||
|
||||
Primary target:
|
||||
|
||||
- bot API on Docker Compose
|
||||
- mini app on Docker Compose
|
||||
- reverse proxy with HTTPS on the VPS
|
||||
- scheduled reminder delivery without Cloud Tasks / Cloud Scheduler
|
||||
- GitHub Actions CD that deploys to the VPS
|
||||
|
||||
Compatibility requirement:
|
||||
|
||||
- keep existing cloud deployment code and workflows available
|
||||
- avoid deleting GCP/AWS-specific adapters unless they are clearly dead and isolated
|
||||
|
||||
## Deployment Shape
|
||||
|
||||
Recommended production services:
|
||||
|
||||
- `bot` - Bun runtime for Telegram webhook/API
|
||||
- `miniapp` - static assets served behind reverse proxy
|
||||
- `scheduler` - separate service that periodically triggers due scheduled dispatch processing
|
||||
- `caddy` - TLS + reverse proxy for `bot.<domain>` and `app.<domain>`
|
||||
|
||||
Database:
|
||||
|
||||
- keep Supabase / managed Postgres external
|
||||
- do not move Postgres onto the VPS in this phase
|
||||
|
||||
## Scheduler Replacement Strategy
|
||||
|
||||
Current app logic already stores scheduled dispatches in Postgres and uses provider adapters for one-shot execution.
|
||||
|
||||
For VPS:
|
||||
|
||||
1. Add a self-hosted scheduled dispatch provider.
|
||||
2. Keep dispatch records in the database as before.
|
||||
3. Add a due-dispatch scan endpoint/handler in the bot runtime.
|
||||
4. Run a dedicated scheduler service in Compose that periodically triggers that scan.
|
||||
5. Keep GCP Cloud Tasks and AWS EventBridge adapters intact for backward compatibility.
|
||||
|
||||
This keeps reminder behavior deterministic while removing dependency on cloud schedulers.
|
||||
|
||||
## Image / Runtime Plan
|
||||
|
||||
### Bot image
|
||||
|
||||
- keep multi-stage build
|
||||
- build runtime entrypoints for:
|
||||
- bot server
|
||||
- scheduler runner
|
||||
- DB migrate command
|
||||
- keep runtime image lean
|
||||
|
||||
### Mini app image
|
||||
|
||||
- keep static build + nginx/alpine runtime
|
||||
|
||||
### Reverse proxy image
|
||||
|
||||
- use an off-the-shelf slim image (Caddy)
|
||||
|
||||
## CD Plan
|
||||
|
||||
Add a separate GitHub Actions workflow for VPS deploy:
|
||||
|
||||
1. run on successful `main` CI and manual dispatch
|
||||
2. build/push bot and miniapp images to GHCR
|
||||
3. SSH into VPS
|
||||
4. pull latest images
|
||||
5. run DB migrations
|
||||
6. restart Compose services
|
||||
7. run smoke checks
|
||||
8. sync Telegram webhook
|
||||
|
||||
Keep existing GCP and AWS workflows untouched.
|
||||
|
||||
## Secrets / Env Plan
|
||||
|
||||
Phase 1:
|
||||
|
||||
- keep runtime env files on the VPS outside the repo
|
||||
- Compose loads env files from a deploy directory
|
||||
|
||||
Optional later upgrade:
|
||||
|
||||
- add 1Password-backed rendering or injection without changing app runtime contracts
|
||||
- keep the runtime contract env-file-based so 1Password remains an overlay, not a hard dependency
|
||||
|
||||
Compatibility rule:
|
||||
|
||||
- do not remove existing env vars for GCP/AWS paths
|
||||
- only add new VPS/self-hosted vars where needed
|
||||
|
||||
## Expected Repo Changes
|
||||
|
||||
### App/runtime
|
||||
|
||||
- add self-hosted scheduler adapter
|
||||
- add due-dispatch scan support
|
||||
- add scheduler runner entrypoint
|
||||
- extend config parsing with VPS/self-hosted provider
|
||||
|
||||
### Docker / deploy
|
||||
|
||||
- add production compose file
|
||||
- add Caddy config
|
||||
- add VPS deploy helper scripts
|
||||
|
||||
### CI/CD
|
||||
|
||||
- add VPS deploy workflow
|
||||
- keep `cd.yml` and `cd-aws.yml`
|
||||
|
||||
### Docs
|
||||
|
||||
- add VPS deployment runbook
|
||||
- document required env files and domains
|
||||
|
||||
## Domain Assumption
|
||||
|
||||
Base domain: `whekin.dev`
|
||||
|
||||
Suggested hostnames:
|
||||
|
||||
- `household-bot.whekin.dev` for bot API / webhook
|
||||
- `household.whekin.dev` for mini app
|
||||
|
||||
These can be adjusted later without changing the deployment shape.
|
||||
|
||||
## Rollout Order
|
||||
|
||||
1. Add docs/plan
|
||||
2. Implement self-hosted scheduler path
|
||||
3. Add production compose + reverse proxy config
|
||||
4. Add VPS deploy scripts
|
||||
5. Add GitHub Actions VPS CD
|
||||
6. Validate builds/tests where practical
|
||||
7. Push branch and open PR
|
||||
|
||||
## Runtime Env Files on VPS
|
||||
|
||||
Expected files under `/opt/household-bot/env`:
|
||||
|
||||
- `bot.env`
|
||||
- `miniapp.env`
|
||||
- `caddy.env`
|
||||
|
||||
Templates live in `deploy/vps/*.env.example`.
|
||||
|
||||
- `miniapp.env` should set `VITE_BOT_API_URL` for the frontend build/runtime config.
|
||||
|
||||
## GitHub Actions Inputs / Secrets
|
||||
|
||||
Recommended repository variables:
|
||||
|
||||
- `VPS_HOST`
|
||||
- `VPS_USER` (default `root`)
|
||||
- `VPS_PORT` (default `22`)
|
||||
- `VPS_DEPLOY_ROOT` (default `/opt/household-bot`)
|
||||
- `VPS_BOT_URL` (default `https://household-bot.whekin.dev`)
|
||||
- `VPS_MINIAPP_URL` (default `https://household.whekin.dev`)
|
||||
|
||||
Required repository secrets:
|
||||
|
||||
- `VPS_SSH_KEY`
|
||||
- `VPS_KNOWN_HOSTS`
|
||||
|
||||
Optional for webhook sync and smoke verification:
|
||||
|
||||
- `TELEGRAM_BOT_TOKEN`
|
||||
- `TELEGRAM_WEBHOOK_SECRET`
|
||||
|
||||
## First-Time VPS Bootstrap
|
||||
|
||||
Use `scripts/ops/vps-bootstrap-ubuntu.sh` to install Docker Engine + Compose plugin on Ubuntu 24.04.
|
||||
|
||||
Then place env files in `/opt/household-bot/env` before running the first deploy.
|
||||
Reference in New Issue
Block a user