From 67829de19fc479ce4764bf2a1749a1561bef2915 Mon Sep 17 00:00:00 2001 From: Francesco Pauselli Date: Sun, 29 Mar 2026 16:38:48 +0200 Subject: [PATCH 1/3] chore(docker): configure docker build and deployment --- .dockerignore | 24 ++++++++++++++++++++++++ Dockerfile | 32 ++++++++++++++++++++++++++++++++ docker-compose.yml | 20 ++++++++++++++++++++ 3 files changed, 76 insertions(+) create mode 100644 .dockerignore create mode 100644 Dockerfile create mode 100644 docker-compose.yml diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..8bff6f1 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,24 @@ +.next +.git +.gitignore +.eslintignore +.prettierignore +node_modules +npm-debug.log +yarn-debug.log +yarn-error.log +.env +.env.example +.env.local +.env.*.local +.DS_Store +.vscode +.idea +*.md +!README.md +.turbo +.cache +dist +build +coverage +.husky diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..bec39ad --- /dev/null +++ b/Dockerfile @@ -0,0 +1,32 @@ +# Stage 1: Builder +FROM node:24-alpine AS builder +RUN apk add --no-cache libc6-compat curl +WORKDIR /app + +COPY package.json package-lock.json ./ +RUN npm ci --ignore-scripts --no-fund --no-audit + +COPY . . +ENV NODE_ENV=production +RUN npm run build && \ + curl -sf https://gobinaries.com/tj/node-prune | sh && \ + node-prune .next/standalone/node_modules + + +# Stage 2: Runtime (distroless) +FROM gcr.io/distroless/nodejs24-debian12:nonroot +WORKDIR /app + +ENV NODE_ENV=production \ + PORT=3000 \ + HOSTNAME=0.0.0.0 + +# Copy optimized build output +COPY --from=builder --chown=nonroot:nonroot /app/.next/standalone ./ +COPY --from=builder --chown=nonroot:nonroot /app/.next/static ./.next/static +COPY --from=builder --chown=nonroot:nonroot /app/public ./public + +USER nonroot +EXPOSE 3000 + +CMD ["server.js"] diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..e5b485a --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,20 @@ +version: '3.8' + +services: + app: + container_name: next-template + build: . + init: true + + ports: + - '3000:3000' + + environment: + NODE_ENV: production + HOSTNAME: 0.0.0.0 + PORT: 3000 + # Uncomment to enable persistent file storage + # volumes: + # - ./data:/app/data + + restart: unless-stopped From 97b2a384af4403bfb37d6261c57f950fa31be06f Mon Sep 17 00:00:00 2001 From: Francesco Pauselli Date: Sun, 29 Mar 2026 17:07:53 +0200 Subject: [PATCH 2/3] feat(docker): add output standalone validation in build --- Dockerfile | 4 ++++ next.config.ts | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index bec39ad..2dcf922 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,6 +7,10 @@ COPY package.json package-lock.json ./ RUN npm ci --ignore-scripts --no-fund --no-audit COPY . . + +# Check that output: 'standalone' is enabled (not commented) +RUN grep -E "^\s*output:" next.config.ts | grep -q "standalone" || (echo "ERROR: next.config.ts must have output: 'standalone' enabled" && exit 1) + ENV NODE_ENV=production RUN npm run build && \ curl -sf https://gobinaries.com/tj/node-prune | sh && \ diff --git a/next.config.ts b/next.config.ts index 726cb9b..1ad8a22 100644 --- a/next.config.ts +++ b/next.config.ts @@ -1,7 +1,7 @@ import type { NextConfig } from 'next'; const nextConfig: NextConfig = { - /* config options here */ + // output: 'standalone', // Uncomment this for Docker deployments skipProxyUrlNormalize: true }; From 4e1299f7826cfc4b5c9daddaefc4748a3cbb06fa Mon Sep 17 00:00:00 2001 From: Francesco Pauselli Date: Sun, 29 Mar 2026 17:15:12 +0200 Subject: [PATCH 3/3] fix(docker): ensure public directory exists in builder stage --- Dockerfile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Dockerfile b/Dockerfile index 2dcf922..22161ad 100644 --- a/Dockerfile +++ b/Dockerfile @@ -11,6 +11,9 @@ COPY . . # Check that output: 'standalone' is enabled (not commented) RUN grep -E "^\s*output:" next.config.ts | grep -q "standalone" || (echo "ERROR: next.config.ts must have output: 'standalone' enabled" && exit 1) +# Ensure public directory exists (required for COPY in runtime stage) +RUN mkdir -p public + ENV NODE_ENV=production RUN npm run build && \ curl -sf https://gobinaries.com/tj/node-prune | sh && \