From 21b3c00d96bec3c4d9171881b2504ed835e3ef54 Mon Sep 17 00:00:00 2001 From: Francisco Solla Date: Sun, 16 Aug 2026 01:52:11 -0300 Subject: [PATCH] chore(deploy): prepara imagem standalone para homeserver --- .dockerignore | 34 ++++++++++++++++++++++++++++ Dockerfile | 59 +++++++++++++++++++++++++++---------------------- next.config.mjs | 1 + 3 files changed, 67 insertions(+), 27 deletions(-) create mode 100644 .dockerignore diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..05a4644a --- /dev/null +++ b/.dockerignore @@ -0,0 +1,34 @@ +.git +.github +.next +.next-* +node_modules + +.env +.env.* +!.env.example + +.agents +.codex +.cursor +.husky +.impeccable +.opencode +.playwright-cli +.playwright-mcp +.vercel +.vscode +.zed + +coverage +data +docs +media +output +playwright-report +private +test-results + +/*.png +*.log +*.tsbuildinfo diff --git a/Dockerfile b/Dockerfile index 20be6345..a0da5256 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,23 +1,25 @@ -# To use this Dockerfile, you have to set `output: 'standalone'` in your next.config.mjs file. +# syntax=docker/dockerfile:1 + # From https://github.com/vercel/next.js/blob/canary/examples/with-docker/Dockerfile -FROM node:22.17.0-alpine AS base +FROM node:24.19.0-alpine AS base + +RUN apk add --no-cache libc6-compat && corepack enable # Install dependencies only when needed FROM base AS deps -# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed. -RUN apk add --no-cache libc6-compat WORKDIR /app -# Install dependencies based on the preferred package manager -COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml* ./ -RUN \ - if [ -f yarn.lock ]; then yarn --frozen-lockfile; \ - elif [ -f package-lock.json ]; then npm ci; \ - elif [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm i --frozen-lockfile; \ - else echo "Lockfile not found." && exit 1; \ - fi +# Install the pinned package manager and dependency graph. +COPY package.json pnpm-lock.yaml ./ +RUN pnpm install --frozen-lockfile +# One-shot image used to apply committed Payload migrations before a release. +FROM base AS migrator +WORKDIR /app +COPY --from=deps /app/node_modules ./node_modules +COPY . . +CMD ["pnpm", "migrate"] # Rebuild the source code only when needed FROM base AS builder @@ -25,25 +27,24 @@ WORKDIR /app COPY --from=deps /app/node_modules ./node_modules COPY . . -# Next.js collects completely anonymous telemetry data about general usage. -# Learn more here: https://nextjs.org/telemetry -# Uncomment the following line in case you want to disable telemetry during the build. -# ENV NEXT_TELEMETRY_DISABLED 1 +ARG NEXT_PUBLIC_SITE_URL +ENV NEXT_PUBLIC_SITE_URL=$NEXT_PUBLIC_SITE_URL +ENV NEXT_TELEMETRY_DISABLED=1 -RUN \ - if [ -f yarn.lock ]; then yarn run build; \ - elif [ -f package-lock.json ]; then npm run build; \ - elif [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm run build; \ - else echo "Lockfile not found." && exit 1; \ - fi +# Static generation reads Payload data. BuildKit mounts keep credentials out of +# layers and image history; migrations run separately through the migrator. +RUN --mount=type=secret,id=database_url,env=DATABASE_URL \ + --mount=type=secret,id=payload_secret,env=PAYLOAD_SECRET \ + NEXT_OUTPUT_STANDALONE=1 \ + NODE_OPTIONS="--no-deprecation --max-old-space-size=8000" \ + pnpm exec next build # Production image, copy all the files and run next FROM base AS runner WORKDIR /app -ENV NODE_ENV production -# Uncomment the following line in case you want to disable telemetry during runtime. -# ENV NEXT_TELEMETRY_DISABLED 1 +ENV NODE_ENV=production +ENV NEXT_TELEMETRY_DISABLED=1 RUN addgroup --system --gid 1001 nodejs RUN adduser --system --uid 1001 nextjs @@ -64,8 +65,12 @@ USER nextjs EXPOSE 3000 -ENV PORT 3000 +ENV PORT=3000 +ENV HOSTNAME=0.0.0.0 # server.js is created by next build from the standalone output # https://nextjs.org/docs/pages/api-reference/next-config-js/output -CMD HOSTNAME="0.0.0.0" node server.js +HEALTHCHECK --interval=30s --timeout=5s --start-period=20s --retries=3 \ + CMD node -e "fetch('http://127.0.0.1:3000/').then((response) => { if (!response.ok) process.exit(1) }).catch(() => process.exit(1))" + +CMD ["node", "server.js"] diff --git a/next.config.mjs b/next.config.mjs index 9b677705..5cb5aa68 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -5,6 +5,7 @@ const allowedImageHost = process.env.NEXT_PUBLIC_SITE_URL || 'https://jorgesolla const nextConfig = { distDir: process.env.NEXT_DIST_DIR || '.next', + ...(process.env.NEXT_OUTPUT_STANDALONE === '1' ? { output: 'standalone' } : {}), images: { remotePatterns: [new URL(`${allowedImageHost}/**`)], },