# syntax=docker/dockerfile:1 # ---------- Dependências ---------- FROM node:24-alpine AS deps WORKDIR /app # libc6-compat: binários nativos (ex.: SWC do Next) esperam glibc RUN apk add --no-cache libc6-compat COPY package.json package-lock.json ./ RUN npm ci # ---------- Build ---------- FROM node:24-alpine AS builder WORKDIR /app COPY --from=deps /app/node_modules ./node_modules COPY . . ENV NEXT_TELEMETRY_DISABLED=1 # O build não acessa o banco (as páginas são renderizadas por requisição) RUN npm run build && npm run build:migrate # ---------- Runtime ---------- FROM node:24-alpine AS runner WORKDIR /app ENV NODE_ENV=production \ NEXT_TELEMETRY_DISABLED=1 \ PORT=3000 \ HOSTNAME=0.0.0.0 \ RUN_MIGRATIONS=true \ STORAGE_DIR=/storage RUN addgroup -S -g 1001 nodejs && adduser -S -u 1001 -G nodejs nextjs # Ponto de montagem do volume de PDFs; o dono 1001 é copiado para o volume quando ele é criado RUN mkdir -p /storage && chown nextjs:nodejs /storage # Servidor standalone + assets estáticos 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 # Migrations (script empacotado + arquivos SQL) COPY --from=builder --chown=nextjs:nodejs /app/dist/migrate.js ./migrate.js COPY --from=builder --chown=nextjs:nodejs /app/drizzle ./drizzle USER nextjs EXPOSE 3000 # Aplica migrations pendentes (desligue com RUN_MIGRATIONS=false) e sobe o servidor CMD ["sh", "-c", "if [ \"$RUN_MIGRATIONS\" = \"true\" ]; then node migrate.js || exit 1; fi; exec node server.js"]