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:
+21
-19
@@ -1,16 +1,19 @@
|
||||
# Runs a custom Node server (server.ts) for the WebRTC signaling WebSocket,
|
||||
# so this can't use Next's "standalone" output — we ship the full app +
|
||||
# node_modules instead. DATABASE_URI/PAYLOAD_SECRET etc. are only needed at
|
||||
# runtime, not at build time (see docker-compose.yml and .env.example).
|
||||
# Multi-stage build for the ANOUMA app (Next.js + Payload CMS + WebRTC
|
||||
# signaling, all served by the custom server.ts — see next.config.ts for why
|
||||
# this can't use Next's "standalone" output). DATABASE_URI/PAYLOAD_SECRET/etc.
|
||||
# are only needed at *runtime*, not at build time (see docker-compose.yml and
|
||||
# .env.example) — this image builds without a database connection.
|
||||
|
||||
FROM node:22-alpine AS base
|
||||
|
||||
# ---- deps: install once, cached as its own layer -------------------------
|
||||
FROM base AS deps
|
||||
RUN apk add --no-cache libc6-compat
|
||||
WORKDIR /app
|
||||
COPY package.json package-lock.json ./
|
||||
RUN npm ci
|
||||
|
||||
# ---- builder: full source + production build ------------------------------
|
||||
FROM base AS builder
|
||||
WORKDIR /app
|
||||
COPY --from=deps /app/node_modules ./node_modules
|
||||
@@ -18,6 +21,7 @@ COPY . .
|
||||
ENV NEXT_TELEMETRY_DISABLED=1
|
||||
RUN npm run build
|
||||
|
||||
# ---- runner: the actual runtime image --------------------------------------
|
||||
FROM base AS runner
|
||||
WORKDIR /app
|
||||
ENV NODE_ENV=production
|
||||
@@ -26,21 +30,16 @@ ENV NEXT_TELEMETRY_DISABLED=1
|
||||
RUN addgroup --system --gid 1001 nodejs \
|
||||
&& adduser --system --uid 1001 nextjs
|
||||
|
||||
COPY --from=builder --chown=nextjs:nodejs /app/node_modules ./node_modules
|
||||
COPY --from=builder --chown=nextjs:nodejs /app/.next ./.next
|
||||
COPY --from=builder --chown=nextjs:nodejs /app/public ./public
|
||||
COPY --from=builder --chown=nextjs:nodejs /app/server.ts ./server.ts
|
||||
COPY --from=builder --chown=nextjs:nodejs /app/lib ./lib
|
||||
COPY --from=builder --chown=nextjs:nodejs /app/payload.config.ts ./payload.config.ts
|
||||
COPY --from=builder --chown=nextjs:nodejs /app/collections ./collections
|
||||
COPY --from=builder --chown=nextjs:nodejs /app/globals ./globals
|
||||
COPY --from=builder --chown=nextjs:nodejs /app/access ./access
|
||||
COPY --from=builder --chown=nextjs:nodejs /app/fields ./fields
|
||||
COPY --from=builder --chown=nextjs:nodejs /app/components ./components
|
||||
COPY --from=builder --chown=nextjs:nodejs /app/next.config.ts ./next.config.ts
|
||||
COPY --from=builder --chown=nextjs:nodejs /app/tsconfig.json ./tsconfig.json
|
||||
COPY --from=builder --chown=nextjs:nodejs /app/package.json ./package.json
|
||||
RUN mkdir -p media && chown nextjs:nodejs media
|
||||
# Copied wholesale (not a hand-picked list of directories) so newly added
|
||||
# source folders (collections, scripts, lib/*, components/*, ...) are never
|
||||
# silently missing at runtime — .dockerignore already excludes what doesn't
|
||||
# belong in the image (node_modules is re-added explicitly below, .next is
|
||||
# the build output we do want).
|
||||
COPY --from=builder --chown=nextjs:nodejs /app /app
|
||||
|
||||
# Writable at runtime, independent of the image — actual data lives in the
|
||||
# Docker volumes mounted over these paths (see docker-compose.yml).
|
||||
RUN mkdir -p media backups && chown -R nextjs:nodejs media backups
|
||||
|
||||
USER nextjs
|
||||
|
||||
@@ -48,4 +47,7 @@ EXPOSE 3000
|
||||
ENV PORT=3000
|
||||
ENV HOSTNAME=0.0.0.0
|
||||
|
||||
HEALTHCHECK --interval=30s --timeout=5s --start-period=30s --retries=3 \
|
||||
CMD node -e "fetch('http://127.0.0.1:3000/api/health').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))"
|
||||
|
||||
CMD ["npm", "start"]
|
||||
|
||||
Reference in New Issue
Block a user