diff --git a/docs/deployment.md b/docs/deployment.md new file mode 100644 index 0000000..e0b0cf5 --- /dev/null +++ b/docs/deployment.md @@ -0,0 +1,233 @@ +# Deployment Notes + +Two active environments share one Convex deployment (`dev:befitting-dalmatian-161`). +Each runs its own web server, Flue agents process, and `.env` file. + +## Environments + +| | Local Mac Dev | Cheaptricks Staging | +| --- | --- | --- | +| SSH alias | (local) | `cheaptricks` | +| Repo path | `/Users/puter/Workspace/zopu/code` | `/workspace/code` | +| Tailscale IPv4 | `100.101.157.28` | `100.122.185.111` | +| Web URL | `http://100.101.157.28:5173` | `https://zopu.cheaptricks.puter.wtf` | +| Flue URL (internal) | `http://100.101.157.28:3585` | `http://127.0.0.1:3585` | +| Flue URL (browser-facing) | `http://100.101.157.28:3585` | `https://zopu.cheaptricks.puter.wtf/api` | +| Caddy | none (direct Tailscale) | `zopu.cheaptricks.puter.wtf` HTTPS termination | +| Bun | installed directly | symlink at `/workspace/.bun` | +| Process manager | manual `bun run dev:tailscale:*` | `nohup` into `/tmp/zopu-*.log` | + +## Shared Convex deployment + +Deployment name: `dev:befitting-dalmatian-161` +Convex URL: `https://befitting-dalmatian-161.convex.cloud` +Convex Site URL: `https://befitting-dalmatian-161.convex.site` + +Convex env vars are deployment-scoped, not per-machine. Authenticate from any +machine with `npx convex dev` inside `packages/backend`. + +Key Convex env var: + +``` +SITE_URL = +``` + +This controls `trustedOrigins` in the Better Auth config +(`packages/backend/convex/auth.ts`). It must match the URL the browser +actually visits, or sign-in fails silently with a CORS rejection. + +When switching between environments: + +```bash +cd packages/backend + +# For local Mac testing: +npx convex env set SITE_URL 'http://100.101.157.28:5173' + +# For Cheaptricks staging: +npx convex env set SITE_URL 'https://zopu.cheaptricks.puter.wtf' +``` + +## Local Mac Dev `.env` + +```env +CONVEX_DEPLOYMENT=dev:befitting-dalmatian-161 +CONVEX_URL=https://befitting-dalmatian-161.convex.cloud +CONVEX_SITE_URL=https://befitting-dalmatian-161.convex.site +SITE_URL=http://100.101.157.28:5173 +NATIVE_APP_URL=code:// + +VITE_CONVEX_URL=https://befitting-dalmatian-161.convex.cloud +VITE_CONVEX_SITE_URL=https://befitting-dalmatian-161.convex.site +VITE_FLUE_URL=http://100.101.157.28:3585 + +DAEMON_ID=local-macbook +DAEMON_NAME=Local MacBook +DAEMON_VERSION=0.0.0 +DAEMON_HEARTBEAT_MS=15000 +DAEMON_COMMAND_LEASE_MS=60000 + +FLUE_DB_TOKEN= + +AGENT_MODEL_PROVIDER=xiaomi +AGENT_MODEL_NAME=mimo-v2.5 +AGENT_MODEL_API=openai-completions +AGENT_MODEL_BASE_URL= +AGENT_MODEL_API_KEY= +AGENT_MODEL_CONTEXT_WINDOW=1048576 +AGENT_MODEL_MAX_TOKENS=131072 + +GITEA_URL=https://git.openputer.com +GITEA_TOKEN= +``` + +### Start local dev + +```bash +bun run dev:tailscale:agents -- --port 3585 & +bun run dev:tailscale:web & +``` + +Both bind `0.0.0.0` so they are reachable over Tailscale from a phone. + +Before testing locally, flip the Convex `SITE_URL`: + +```bash +cd packages/backend && npx convex env set SITE_URL 'http://100.101.157.28:5173' +``` + +## Cheaptricks Staging `.env` + +Located at `/workspace/code/.env` on the `cheaptricks` host. + +```env +CONVEX_DEPLOYMENT=dev:befitting-dalmatian-161 +CONVEX_URL=https://befitting-dalmatian-161.convex.cloud +CONVEX_SITE_URL=https://befitting-dalmatian-161.convex.site +SITE_URL=https://zopu.cheaptricks.puter.wtf +NATIVE_APP_URL=code:// + +VITE_CONVEX_URL=https://befitting-dalmatian-161.convex.cloud +VITE_CONVEX_SITE_URL=https://befitting-dalmatian-161.convex.site +VITE_FLUE_URL=https://zopu.cheaptricks.puter.wtf/api + +VITE_ZOPU_SERVER_URL=https://zopu.cheaptricks.puter.wtf/api +PORT=3590 + +DAEMON_ID=local-macbook +DAEMON_NAME=Local MacBook +DAEMON_VERSION=0.0.0 +DAEMON_HEARTBEAT_MS=15000 +DAEMON_COMMAND_LEASE_MS=60000 + +FLUE_DB_TOKEN= + +AGENT_MODEL_PROVIDER=xiaomi +AGENT_MODEL_NAME=mimo-v2.5 +AGENT_MODEL_API=openai-completions +AGENT_MODEL_BASE_URL=https://ai.cheaptricks.puter.wtf/v1 +AGENT_MODEL_API_KEY= +AGENT_MODEL_CONTEXT_WINDOW=1048576 +AGENT_MODEL_MAX_TOKENS=131072 + +GITEA_URL=https://git.openputer.com +GITEA_TOKEN= +``` + +### Caddy config + +File: `/etc/caddy/Caddyfile` on `cheaptricks` + +``` +zopu.cheaptricks.puter.wtf { + bind 135.181.82.179 2a01:4f9:c013:4a64::1 + encode zstd gzip + + handle_path /api/* { + reverse_proxy 127.0.0.1:3585 + } + + reverse_proxy 127.0.0.1:5173 +} +``` + +`/api/*` routes to the Flue agents process (port 3585). +Everything else routes to the web dev server (port 5173). + +Reload after changes: + +```bash +sudo systemctl reload caddy +``` + +### Vite allowedHosts + +`apps/web/vite.config.ts` must include `server: { allowedHosts: true }` or +Vite rejects requests arriving through the Caddy domain. + +### Start staging dev + +```bash +ssh cheaptricks +export PATH=$PATH:/workspace/.bun/bin +cd /workspace/code + +# Pull latest +git pull origin feat/web-integrarion +bun install + +# Start both processes with nohup so they survive SSH disconnect +nohup bun run dev:tailscale:agents -- --port 3585 > /tmp/zopu-agents.log 2>&1 & +nohup bun run dev:tailscale:web > /tmp/zopu-web.log 2>&1 & +``` + +Before testing on staging, flip the Convex `SITE_URL`: + +```bash +cd packages/backend && npx convex env set SITE_URL 'https://zopu.cheaptricks.puter.wtf' +``` + +### Verify staging + +```bash +curl -sS -o /dev/null -w '%{http_code}\n' https://zopu.cheaptricks.puter.wtf/ +# expect: 200 + +curl -sS -D - -o /dev/null \ + 'https://befitting-dalmatian-161.convex.site/api/auth/get-session' \ + -H 'Origin: https://zopu.cheaptricks.puter.wtf' | grep access-control-allow-origin +# expect: access-control-allow-origin: https://zopu.cheaptricks.puter.wtf +``` + +## Model configuration + +Both environments use the same model via the Cheaptricks AI gateway: + +- Provider identity: `xiaomi` (Flue catalog maps this to MiMo multimodal metadata) +- Model: `mimo-v2.5` +- API protocol: `openai-completions` +- Context window: `1048576` +- Max output tokens: `131072` +- Multimodal: text + image input + +The `AGENT_MODEL_BASE_URL` differs: +- Local Mac: uses the external gateway URL +- Cheaptricks: uses `https://ai.cheaptricks.puter.wtf/v1` (local to the box) + +## Known gotchas + +1. **Convex SITE_URL is single-valued.** Only one origin can be trusted at a + time. Switch it when moving between local and staging, or sign-in breaks + silently with a CORS error in the browser console. + +2. **Vite blocks unknown hosts by default.** Caddy domain must be allowed + via `server.allowedHosts` in `apps/web/vite.config.ts`. + +3. **Flue port changed from 3583 to 3585.** The old Caddy config pointed at + 3583/13100. Current ports are 3585 (Flue) and 5173 (web). + +4. **`.env` is gitignored.** Each machine maintains its own copy. The repo + ships `.env.example` as the template. + +5. **Convex CLI auth is per-machine.** Run `npx convex dev` once inside + `packages/backend` on each new machine to authenticate the CLI.