Bot + web Dockerfiles tried to addgroup -g 1000 app on top of
node:22-alpine, which already ships a `node` group at gid 1000.
Build aborted at runtime stage 5/5 with:
addgroup: gid '1000' in use
Drop the addgroup/adduser pair on both images and just chown +
USER node onto the existing node user. Same hardening posture
(non-root, no shell login on the runtime image), one less moving
part. The compose dev overlay's `user: ${HOST_UID:-1000}:${HOST_GID:-1000}`
matches uid 1000 either way.
Plus:
- New docker-compose.portainer.yml: pulls cm-whatsapp-{bot,web}
from gitea.04080616.xyz/yiekheng instead of building from
source. Named volumes for sessions / media so the operator
doesn't need shell access to manage state. Healthchecks on
both services so Portainer's UI surfaces unhealthy containers.
- New docs/deploy-portainer.md walking through registry auth,
stack creation, env vars, migrations, first sign-in, future
redeploys, rollbacks.
- README links the Portainer guide alongside the dev path.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
robots.ts + metadata.robots blocks indexing.
serverActions.allowedOrigins gates cross-origin Server Action posts.
Bot + web Dockerfiles add a non-root 'app' user (uid 1000) with
chmod 700 on /data/sessions.
sendTestAction grows a per-group rate limit (3/60s).
resumeReminderRunAction + cancelReminderRunAction get a per-IP
rate limit (30/10s).
.env.example documents every required key.
packages/db/src/scripts/{set-password,create-user}.ts + thin shell
wrappers in scripts/ — first admin sets their password via
./scripts/set-password.sh admin before signing in.
Replace corepack-prepared pnpm with `npm install -g pnpm@9.12.0` so the
binary lives in /usr/local/bin (readable by any UID) instead of root's
corepack cache. Avoids re-downloading pnpm on every container restart
when running as a non-root host user.
Also populate .env.development with real dev credentials (Postgres at
192.168.0.210/wabot, dev Telegram bot, operator Telegram ID 818380985).