Skip to content

🧰 chore: bootstrap fixes, env cleanup, deployment doc, optional pgweb#4

Open
kamikazebr wants to merge 5 commits intoHanake0:mainfrom
kamikazebr:fix/docker-compose-bootstrap
Open

🧰 chore: bootstrap fixes, env cleanup, deployment doc, optional pgweb#4
kamikazebr wants to merge 5 commits intoHanake0:mainfrom
kamikazebr:fix/docker-compose-bootstrap

Conversation

@kamikazebr
Copy link
Copy Markdown

@kamikazebr kamikazebr commented Apr 17, 2026

Summary

Groups everything needed to make a fresh clone of the repo bootable end-to-end from docker compose up -d, plus documents the production deployment topology (currently undocumented in the repo). Found and fixed several subtle issues that block first-time users.

Commits

  1. 🐛 fix(docker) — gowa/postgres images + bootstrap
  2. 📝 docs(env) — stale defaults + missing consumed vars
  3. 📝 docs — new docs/DEPLOYMENT.md (production topology)
  4. feat(compose) — optional pgweb profile
  5. 🐛 fix(compose) — persist GOWA session + device_id guidance

Bugs the repo had (now fixed)

1. GOWA image name doesn't exist

aldinokemal/go-whatsapp-web-multidevice:latest → 404 on Docker Hub. Correct namespace is aldinokemal2104/.... Pinned to v8.3.3 because upgrades have changed the webhook payload and REST API in the past.

2. Postgres missing pgvector

postgres:17-alpine lacks the vector extension — EF migrations fail immediately with extension "vector" is not available. Swapped to pgvector/pgvector:pg17.

3. POSTGRES_PASSWORD silently empty

Compose reads ${POSTGRES_PASSWORD} but .env.example didn't define it — Postgres booted with a blank password every time. Added.

4. GOWA session not persisted

The repo's compose had no volume on gowa, so /app/storages/{whatsapp,chatstorage}.db lives only inside the container. Any docker compose restart gowa (or a recreate triggered by backend/service changes) drops the pairing. Added gowa-data:/app/storages.

5. GOWA_DEVICE_ID=default rejected by GOWA v8.3.3

After pairing, GOWA requires an X-Device-Id header that matches a paired device UUID. The env default default triggers 404 DEVICE_NOT_FOUND on every outbound API call (mark-read, send-reply, group-info). Users see GOWA forward webhooks successfully but Lis can't reply. Shipped empty with a comment explaining the post-pairing flow.

6. Env defaults too conservative

  • ANTHROPIC_MODEL=claude-sonnet-4-20250514 — dated API ID instead of the current alias.
  • ANTHROPIC_MAX_TOKENS=4096 — cuts off normal replies.
  • ANTHROPIC_CONTEXT_BUDGET=12000 — triggers compaction almost immediately, destroys cache hits.

7. .env.example missing vars that code consumes

LIS_GROUP_CONTEXT_MESSAGES, LIS_NEW_SESSION_ON_AGENT_SWITCH, LIS_WEB_SEARCH_ENABLED, LIS_WEB_SEARCH_API_KEY. Added ANTHROPIC_AUTH_MODE too (optional — OAuth tokens sk-ant-oat01-... from claude setup-token are already auto-detected by prefix in AnthropicProvider.cs:30, but the override exists).

8. No deployment doc

Production uses a two-stack topology (Caddy reverse proxy + managed Postgres, Lis and services as separate compose stacks sharing a proxy network) documented only in a private file. Added docs/DEPLOYMENT.md as the canonical version, scrubbed of host-specific references (no domains, no real connection strings).

9. No local DB UI

Production uses Neon Database Studio for inspection/edits (the seeder only creates the default agent, so additional agents need runtime creation via /agent new or direct DB work). Added an opt-in pgweb profile: docker compose --profile db-ui up -dlocalhost:8081.

Known gaps not fixed here

  • Container name drift: dev compose uses backend, production uses lis. Webhook URLs line up internally in each stack, but the name difference makes copy-pasting between envs error-prone. Left as-is — changing backendlis would rename logs/metrics without fixing anything substantive.
  • Device pre-creation: in production it's cleaner to POST /devices with a known ID before pairing (so GOWA_DEVICE_ID stays stable across re-pairings). Dev flow still requires post-pairing lookup. Out of scope for this PR.
  • No healthchecks on any compose service. Would catch vector-extension missing, unpaired GOWA, and backend crash loops earlier. Out of scope.
  • oauth_credential table observed in the reference production DB is not in any migration and not referenced in code — appears to be a manually created table outside the scope of the repo. Not touched here.
  • Stale vars in reference prod config (LIS_MAX_RECENT_MESSAGES, LIS_SUMMARIZATION_THRESHOLD, LIS_DEBUG_ANTHROPIC) were intentionally not added to .env.example — they're not read anywhere in code, and Plans/resume-and-session-id.md flags at least one for removal.

Test plan

  • Fresh clone → cp .env.example .env → fill minimums → docker compose up -d → backend reaches Application started, gowa serves on :3000
  • QR pairing via GOWA UI persists across docker compose down && up -d (volume works)
  • docker compose --profile db-ui up -d brings up pgweb at :8081, auto-connected to lis DB
  • docker compose config validates with and without the db-ui profile
  • OAuth token accepted — AnthropicProvider.cs:30 auto-detects sk-ant-oat prefix and switches to Bearer + required headers/URL rewrite
  • End-to-end WhatsApp round-trip with a real GOWA_DEVICE_ID (in progress by reporter)

- gowa: aldinokemal → aldinokemal2104, pin to v8.3.3
- postgres: switch to pgvector/pgvector:pg17 (vector extension required by migrations)
- .env.example: expose POSTGRES_PASSWORD consumed by compose
- README: document `claude setup-token` OAuth option and POSTGRES_PASSWORD
- ANTHROPIC_MODEL: claude-sonnet-4-20250514 → claude-sonnet-4-6
- ANTHROPIC_MAX_TOKENS: 4096 → 16000 (prod-aligned)
- ANTHROPIC_CONTEXT_BUDGET: 12000 → 300000 (avoid immediate compaction)
- Add ANTHROPIC_AUTH_MODE (optional — OAuth is auto-detected by prefix)
- Add LIS_GROUP_CONTEXT_MESSAGES, LIS_NEW_SESSION_ON_AGENT_SWITCH (consumed in code)
- Add LIS_WEB_SEARCH_ENABLED / LIS_WEB_SEARCH_API_KEY (Brave Search)
- Clarify ANTHROPIC_THINKING_EFFORT accepted values
Documents the two-stack topology used in production: services/ (Caddy
reverse proxy + GOWA) and lis/ (the agent), sharing a proxy network.
Covers TLS, managed Postgres with pgvector, secret matrix, boot order,
QR pairing, and backup. Scrubbed of host-specific references.
Enable with: docker compose --profile db-ui up -d
Then open http://localhost:8081

Off by default — no impact on standard 'docker compose up -d'.
Gives parity with the Neon Database Studio used in production, so
dev users can inspect/edit tables (agents, chats, sessions, etc.)
without installing a native client.
@kamikazebr kamikazebr changed the title 🐛 fix(docker): correct gowa/postgres images and document bootstrap 🧰 chore: bootstrap fixes, env cleanup, deployment doc, optional pgweb Apr 17, 2026
- Add gowa-data volume mounted at /app/storages so the WhatsApp session
  survives container restarts. Without it, any 'docker compose restart gowa'
  (or recreate triggered by backend changes) drops the QR pairing.
- .env.example: GOWA_DEVICE_ID was 'default', which GOWA v8.3.3 rejects
  with '404 DEVICE_NOT_FOUND' because no paired device matches that ID.
  Ship empty and document that users must fill in the real UUID (from
  /devices) after pairing.
Comment thread docker-compose.yml
WHATSAPP_WEBHOOK_SECRET: "${GOWA_WEBHOOK_SECRET}"
WHATSAPP_WEBHOOK_EVENTS: "message"
volumes:
- gowa-data:/app/storages
Copy link
Copy Markdown
Owner

@Hanake0 Hanake0 Apr 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you want to endorse a cannonical setup, i would probably recomend also using pg as the storage backend for gowa.
File Storage is probably fine, but we are alreading setting up pg for the agent, using it for gowa is ok too.

Volume storage is probably recommended to still be kept tho, if you have automatic media download setup on gowa.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants