Add full Docker deployment: setup.sh, update.sh, healthcheck, TURN support

- setup.sh: interactive/non-interactive one-shot installer (build, DB
  healthcheck, migrate, seed, start), idempotent secret generation, NPM
  reverse-proxy network auto-detection and optional join, optional
  AUTO_UPDATE cron install.
- update.sh: release-tag-gated updates only (never bare main), DB backup
  with retention before every update, lock file against concurrent runs,
  automatic code rollback on failed post-update healthcheck.
- Dockerfile: multi-stage build, non-root user, built-in HEALTHCHECK against
  the new /api/health route, wholesale COPY so new source dirs (e.g.
  scripts/) never silently go missing at runtime.
- docker-compose.yml: internal anouma-network (configurable), named volume
  for Postgres, app depends_on postgres healthy, no unnecessary published
  ports; docker-compose.override.yml.example documents joining an existing
  NPM network without ever touching NPM itself.
- Fix host-detection: isHost was Boolean(user), wrongly granting host
  privileges to logged-in customers; now checks user.collection === "users".
- Wire configurable STUN/TURN servers through to the WebRTC client
  (lib/meeting/iceServers.ts) so a TURN server can be added later via env
  vars only, no code changes.
- DEPLOYMENT.md, updated README.md and .env.example documenting the whole
  flow: NPM integration, env vars, WebRTC, updates, backups, rollback.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-25 21:50:28 +02:00
co-authored by Claude Sonnet 5
parent d3d53e68a9
commit 50c39a70e0
16 changed files with 886 additions and 68 deletions
+56 -16
View File
@@ -1,28 +1,68 @@
# PostgreSQL connection string used by Payload (see docker-compose.yml for a
# local database, or use a hosted Postgres such as Neon/Supabase).
DATABASE_URI=postgresql://postgres:postgres@127.0.0.1:5432/anouma
# ── Database ────────────────────────────────────────────────────────────
# PostgreSQL connection string used by Payload. setup.sh fills this in
# automatically (host "postgres" when running the full stack via Docker
# Compose, matching POSTGRES_USER/PASSWORD/DB below). For a host-only Next
# dev server against the Dockerized Postgres, use "127.0.0.1" instead.
DATABASE_URI=postgresql://postgres:postgres@postgres:5432/anouma
# Long random string used to sign Payload's auth tokens/cookies.
# Generate one with: openssl rand -base64 48
# Only used by the "postgres" service in docker-compose.yml — keep these in
# sync with DATABASE_URI above (setup.sh does this for you).
POSTGRES_USER=postgres
POSTGRES_PASSWORD=replace-with-a-long-random-secret
POSTGRES_DB=anouma
# ── Core secrets ────────────────────────────────────────────────────────
# Signs Payload's auth tokens/cookies. Generate with: openssl rand -base64 48
PAYLOAD_SECRET=replace-with-a-long-random-secret
# Public URL of this site — used by Payload for absolute admin/media links,
# and to build the meeting join link inside reminder emails.
# Set this to the real domain in production (e.g. https://anouma.org).
NEXT_PUBLIC_SERVER_URL=http://localhost:3000
# Long random string used to sign meeting join tokens (separate from
# PAYLOAD_SECRET on purpose). Generate one with: openssl rand -base64 48
# Signs meeting join tokens (kept separate from PAYLOAD_SECRET on purpose).
# Generate with: openssl rand -base64 48
MEETING_SESSION_SECRET=replace-with-a-long-random-secret
# Secret the external cron job must send as "Authorization: Bearer <value>"
# to trigger /api/cron/event-reminders. Generate with: openssl rand -hex 32
# Sent as "Authorization: Bearer <value>" by the external cron job that
# triggers /api/cron/event-reminders. Generate with: openssl rand -hex 32
CRON_SECRET=replace-with-a-long-random-secret
# SMTP settings for the existing ANOUMA mail system (reminder emails).
# No external newsletter service — plain SMTP via nodemailer.
# ── Public URL ──────────────────────────────────────────────────────────
# Used by Payload for absolute admin/media links, and to build meeting join
# links inside emails. Set this to the real domain in production.
NEXT_PUBLIC_SERVER_URL=http://localhost:3000
# Port the app container publishes on the host (behind a reverse proxy this
# usually doesn't need to be reachable directly — see DEPLOYMENT.md).
APP_PORT=3000
# ── Email (SMTP) ────────────────────────────────────────────────────────
# The existing ANOUMA mail system — no external newsletter service.
SMTP_HOST=
SMTP_PORT=587
SMTP_USER=
SMTP_PASSWORD=
SMTP_FROM="ANOUMA <support@anouma.org>"
# ── WebRTC (STUN/TURN) ──────────────────────────────────────────────────
# P2P works with just STUN for most networks. Add a TURN server later for
# restrictive NATs/firewalls — no code changes needed, just set these.
STUN_SERVER=stun:stun.l.google.com:19302
TURN_SERVER=
TURN_USERNAME=
TURN_PASSWORD=
# ── Docker networking ───────────────────────────────────────────────────
# Internal network name for ANOUMA's own containers.
DOCKER_NETWORK=anouma-network
# Name of an existing external Docker network to join (e.g. Nginx Proxy
# Manager's network) so a reverse proxy can reach the app container
# directly. Leave empty if you don't use one — setup.sh auto-detects this.
NPM_NETWORK=
# ── Updates & backups (used by update.sh) ──────────────────────────────
# When true, setup.sh installs a cron entry that checks for new releases
# and updates automatically. Off by default — update.sh can always be run
# manually regardless of this setting.
AUTO_UPDATE=false
# How long (days) to keep database backups created by update.sh before
# deleting them.
BACKUP_RETENTION_DAYS=14