-
Notifications
You must be signed in to change notification settings - Fork 580
Expand file tree
/
Copy pathDockerfile
More file actions
84 lines (77 loc) · 4.08 KB
/
Copy pathDockerfile
File metadata and controls
84 lines (77 loc) · 4.08 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# syntax=docker/dockerfile:1
# DeskcommCRM — imagem de produção self-host (Next.js standalone).
# Build: docker build --build-arg NEXT_PUBLIC_SUPABASE_URL=... -t deskcomm-app .
# ---- deps: instala dependências (layer cacheável) ----
FROM node:22-alpine AS deps
WORKDIR /app
RUN corepack enable && corepack prepare [email protected] --activate
COPY package.json pnpm-lock.yaml ./
COPY patches ./patches
RUN pnpm install --frozen-lockfile
# ---- build: gera .next/standalone ----
FROM node:22-alpine AS build
WORKDIR /app
RUN corepack enable && corepack prepare [email protected] --activate
COPY --from=deps /app/node_modules ./node_modules
COPY . .
# IMAGEM GENÉRICA: os NEXT_PUBLIC_* recebem placeholders no build. Os valores
# REAIS do usuário são injetados em RUNTIME — no browser via <PublicEnvScript/>
# (window.__PUBLIC_ENV__) e no servidor via lib/env.ts (parseia process.env em
# runtime). Assim UMA imagem serve qualquer projeto Supabase, sem rebuild.
# (Segredos de runtime NUNCA entram no build — guarda de fase em lib/env.ts.)
ARG NEXT_PUBLIC_SUPABASE_URL=https://placeholder.supabase.co
ARG NEXT_PUBLIC_SUPABASE_ANON_KEY=placeholder-anon-key
ARG NEXT_PUBLIC_APP_URL=https://placeholder.invalid
ARG NEXT_PUBLIC_ADMIN_URL=https://placeholder.invalid
# O build do Next é faminto: o heap default do Node (~2GB) estoura. NODE_OPTIONS
# eleva pra 4GB. Isso é custo de QUEM BUILDA — o CI —, não de quem instala: o
# caminho normal do self-hoster é `docker compose pull`, e o install.sh não
# builda o app. Buildar na VPS é o override opcional de docker-compose.build.yml,
# e é lá que o requisito de RAM de build se aplica (docs/runbooks/deploy.md §4).
ENV NEXT_PUBLIC_SUPABASE_URL=$NEXT_PUBLIC_SUPABASE_URL \
NEXT_PUBLIC_SUPABASE_ANON_KEY=$NEXT_PUBLIC_SUPABASE_ANON_KEY \
NEXT_PUBLIC_APP_URL=$NEXT_PUBLIC_APP_URL \
NEXT_PUBLIC_ADMIN_URL=$NEXT_PUBLIC_ADMIN_URL \
NODE_ENV=production \
NEXT_TELEMETRY_DISABLED=1 \
NODE_OPTIONS=--max-old-space-size=4096
# Turbopack (`pnpm build`): ~4min vs ~34min do webpack num VPS. O bloco `webpack:`
# do Sentry (tree-shake + upload de sourcemap em build-time) é ignorado, mas o
# Sentry RUNTIME segue ativo (DSN hardcoded nas configs). Sourcemap upload é
# concern só da Vercel; aqui o ganho de tempo de build é o que importa pro leigo.
RUN pnpm build
# ---- runner: imagem slim de produção ----
FROM node:22-alpine AS runner
WORKDIR /app
# Procedência (doutrina de packaging, invariante 2). O CI já injeta os labels
# OCI via docker/metadata-action; estes aqui são defesa em profundidade — valem
# para qualquer build, inclusive o local de docker-compose.build.yml, que não
# passa pelo metadata-action e sem isto sairia sem origem nenhuma.
LABEL org.opencontainers.image.source="https://github.com/melgarafael/DeskcommCRM" \
org.opencontainers.image.licenses="MIT" \
org.opencontainers.image.title="DeskcommCRM"
# A versão que /api/v1/health reporta (invariante 7). Precisa vir por ARG: a
# alternativa anterior era `process.env.npm_package_version`, que é `undefined`
# sob `CMD ["node","server.js"]` — só existe quando o processo nasce de um
# `npm`/`pnpm run`. Toda instalação do mundo reportava o fallback "0.1.0".
ARG APP_VERSION=dev
ENV NODE_ENV=production \
PORT=3000 \
HOSTNAME=0.0.0.0 \
NEXT_TELEMETRY_DISABLED=1 \
APP_VERSION=$APP_VERSION
# ffmpeg: a derivação de vídeo (Onda 3.1) roda no processo do app — o cron
# event-log-drain executa o media_derive handler, que chama `ffmpeg` via spawn
# pra extrair áudio+frames. Sem o binário, todo vídeo recebido falha a derivação.
RUN apk add --no-cache ffmpeg
# non-root
RUN addgroup -g 1001 -S nodejs && adduser -S nextjs -u 1001
# O output standalone NÃO inclui public/ nem .next/static — copiar explicitamente,
# senão CSS/JS/assets retornam 404 (app "sem estilo").
COPY --from=build --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=build --chown=nextjs:nodejs /app/.next/static ./.next/static
COPY --from=build --chown=nextjs:nodejs /app/public ./public
USER nextjs
EXPOSE 3000
# server.js é o entrypoint gerado pelo output standalone.
CMD ["node", "server.js"]