src/lib/dev-login-config.ts — startup assertion: throws if NODE_ENV=production + ENABLE_DEV_LOGIN=true, scoped to runtime (skipped during next build).
Container
scripts/migrate.mjs — runs Drizzle migrations against DATABASE_URL.
deploy/docker-entrypoint.sh — runs migrations then exec node server.js. Skip with RUN_MIGRATIONS=false.
Dockerfile — copies drizzle/, scripts/migrate.mjs, entrypoint into runner stage; ENTRYPOINT now points at the script.
Compose
deploy/compose.yaml — famapp now image: ${FAMAPP_IMAGE:-ghcr.io/ginnoir/famapp:latest} (build still works locally as fallback). Authentik pinned via AUTHENTIK_IMAGE_TAG (default 2024.12.3). New RUN_MIGRATIONS env passed through.
.env.production.example — documents FAMAPP_IMAGE, AUTHENTIK_IMAGE_TAG, RUN_MIGRATIONS.
CI/CD
.github/workflows/ci.yml — push/PR: typecheck + lint + format:check + build.
.github/workflows/release.yml — v* tag: build + push ghcr.io/ginnoir/famapp:vX.Y.Z, :X.Y, :latest to GHCR.
Docs
deploy/README.md — full deploy/rollback/release runbook.
CHANGELOG.md — release log seeded with an Unreleased entry.
docs/tasks/09-pre-deploy-checklist.md — task 09 reframed from one-shot removal to a recurring pre-deploy checklist.
STATUS.md — updated.
Verified: pnpm typecheck, pnpm format, pnpm build, and docker compose config all clean.
45 lines
1.9 KiB
Docker
45 lines
1.9 KiB
Docker
# syntax=docker/dockerfile:1
|
|
|
|
# ── Stage 1: fetch dependencies ───────────────────────────────────────────────
|
|
FROM node:22-alpine AS deps
|
|
RUN corepack enable && corepack prepare pnpm@10.33.3 --activate
|
|
WORKDIR /app
|
|
COPY package.json pnpm-lock.yaml .npmrc ./
|
|
# Populate the pnpm virtual store; this layer is cached until lock file changes.
|
|
RUN pnpm fetch
|
|
|
|
# ── Stage 2: build ────────────────────────────────────────────────────────────
|
|
FROM deps AS builder
|
|
WORKDIR /app
|
|
# CI=true prevents pnpm from prompting for TTY confirmation when removing modules dir
|
|
ENV CI=true
|
|
ENV NEXT_TELEMETRY_DISABLED=1
|
|
COPY . .
|
|
RUN pnpm install --offline --frozen-lockfile
|
|
RUN pnpm build
|
|
|
|
# ── Stage 3: production runtime ───────────────────────────────────────────────
|
|
FROM node:22-alpine AS runner
|
|
WORKDIR /app
|
|
ENV NODE_ENV=production
|
|
ENV PORT=3000
|
|
ENV HOSTNAME=0.0.0.0
|
|
|
|
RUN addgroup --system --gid 1001 nodejs \
|
|
&& adduser --system --uid 1001 nextjs
|
|
|
|
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
|
|
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
|
|
COPY --from=builder --chown=nextjs:nodejs /app/public ./public
|
|
|
|
# Migration assets — drizzle/ holds SQL + meta journal; migrate.mjs uses
|
|
# drizzle-orm + postgres which Next.js standalone already traces in.
|
|
COPY --from=builder --chown=nextjs:nodejs /app/drizzle ./drizzle
|
|
COPY --from=builder --chown=nextjs:nodejs /app/scripts/migrate.mjs ./scripts/migrate.mjs
|
|
COPY --chown=nextjs:nodejs deploy/docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh
|
|
RUN chmod +x /usr/local/bin/docker-entrypoint.sh
|
|
|
|
USER nextjs
|
|
EXPOSE 3000
|
|
ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"]
|