refactor(docker): update Dockerfile for Next.js 15 and improve environment variable handling
This commit is contained in:
+4
-4
@@ -14,10 +14,10 @@ build
|
|||||||
coverage
|
coverage
|
||||||
.nyc_output
|
.nyc_output
|
||||||
|
|
||||||
# Environment files
|
# Environment files — never bake secrets into the image; pass via build args / runtime env
|
||||||
.env*.local
|
.env
|
||||||
.env.development
|
.env.*
|
||||||
.env.test
|
!.env.example
|
||||||
|
|
||||||
# IDE
|
# IDE
|
||||||
.vscode
|
.vscode
|
||||||
|
|||||||
+60
-28
@@ -1,48 +1,80 @@
|
|||||||
# Dockerfile for Next.js 14 - Optimized for Production
|
# syntax=docker/dockerfile:1
|
||||||
|
# Multi-stage Dockerfile for Next.js 15 (App Router, output: 'standalone')
|
||||||
|
# Based on the official Next.js Docker example, tuned for Coolify.
|
||||||
|
# Reference: https://github.com/vercel/next.js/blob/canary/examples/with-docker/Dockerfile
|
||||||
|
|
||||||
# Use the official Node.js image with Alpine Linux for a smaller footprint
|
# ----------------------------------------------------------------------------
|
||||||
|
# Base image
|
||||||
|
# ----------------------------------------------------------------------------
|
||||||
FROM node:22-alpine AS base
|
FROM node:22-alpine AS base
|
||||||
|
# libc6-compat is recommended by the Next.js image for some native deps (sharp, etc.)
|
||||||
# Set the working directory in the container
|
RUN apk add --no-cache libc6-compat
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
# Copy package.json and package-lock.json (or yarn.lock)
|
# ----------------------------------------------------------------------------
|
||||||
COPY package*.json ./
|
# 1. Dependencies — installed in a dedicated layer so they are cached as long
|
||||||
|
# as package.json / lockfile / .npmrc do not change.
|
||||||
|
# ----------------------------------------------------------------------------
|
||||||
|
FROM base AS deps
|
||||||
|
COPY package.json package-lock.json .npmrc ./
|
||||||
|
# Reproducible install honouring the lockfile (.npmrc provides legacy-peer-deps).
|
||||||
|
RUN npm ci
|
||||||
|
|
||||||
# Install dependencies - leveraging Docker cache
|
# ----------------------------------------------------------------------------
|
||||||
RUN npm i --force
|
# 2. Builder — produces the standalone output.
|
||||||
|
# NEXT_PUBLIC_* values are inlined into the client bundle at BUILD time,
|
||||||
|
# so they must be passed as build args. DEV_MODE is read in app/layout.js
|
||||||
|
# to enable Google Analytics, so it must also be present at build time.
|
||||||
|
# ----------------------------------------------------------------------------
|
||||||
|
FROM base AS builder
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
# Copy the rest of the application code
|
# Build-time arguments (Coolify: set these as Build Variables)
|
||||||
|
ARG NEXT_PUBLIC_API_URL
|
||||||
|
ARG NEXT_PUBLIC_CLIENT_ID
|
||||||
|
ARG NEXT_PUBLIC_CLIENT_SECRET
|
||||||
|
ARG DEV_MODE=FALSE
|
||||||
|
|
||||||
|
# Expose them to `next build`
|
||||||
|
ENV NEXT_PUBLIC_API_URL=$NEXT_PUBLIC_API_URL
|
||||||
|
ENV NEXT_PUBLIC_CLIENT_ID=$NEXT_PUBLIC_CLIENT_ID
|
||||||
|
ENV NEXT_PUBLIC_CLIENT_SECRET=$NEXT_PUBLIC_CLIENT_SECRET
|
||||||
|
ENV DEV_MODE=$DEV_MODE
|
||||||
|
ENV NEXT_TELEMETRY_DISABLED=1
|
||||||
|
ENV NODE_ENV=production
|
||||||
|
|
||||||
|
COPY --from=deps /app/node_modules ./node_modules
|
||||||
COPY . .
|
COPY . .
|
||||||
|
|
||||||
# Build the Next.js application
|
|
||||||
RUN npm run build
|
RUN npm run build
|
||||||
|
|
||||||
# Stage 2: Production image - smaller and leaner
|
# ----------------------------------------------------------------------------
|
||||||
FROM node:22-alpine AS runner
|
# 3. Runner — minimal production image running the standalone server.
|
||||||
|
# ----------------------------------------------------------------------------
|
||||||
# Set the working directory
|
FROM base AS runner
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
# Set environment variables
|
ENV NODE_ENV=production
|
||||||
ENV NODE_ENV $NODE_ENV
|
ENV NEXT_TELEMETRY_DISABLED=1
|
||||||
ENV NEXT_TELEMETRY_DISABLED 1
|
# The standalone server must bind to all interfaces inside the container.
|
||||||
|
ENV HOSTNAME=0.0.0.0
|
||||||
|
ENV PORT=3000
|
||||||
|
|
||||||
# Add a non-root user for security
|
# Run as a non-root user for security.
|
||||||
RUN addgroup -g 1001 -S nodejs
|
RUN addgroup --system --gid 1001 nodejs \
|
||||||
RUN adduser -S nextjs -u 1001
|
&& adduser --system --uid 1001 nextjs
|
||||||
|
|
||||||
# Copy only the necessary files from the builder stage
|
# Public assets (served by the standalone server).
|
||||||
COPY --from=base /app/next.config.js ./
|
COPY --from=builder /app/public ./public
|
||||||
COPY --from=base /app/public ./public
|
|
||||||
COPY --from=base --chown=nextjs:nodejs /app/.next/standalone ./
|
# Standalone output already contains a minimal node_modules + server.js.
|
||||||
COPY --from=base --chown=nextjs:nodejs /app/.next/static ./.next/static
|
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
|
||||||
|
# Static assets are NOT included in standalone and must be copied separately.
|
||||||
|
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
|
||||||
|
|
||||||
# Change ownership of all copied files to the non-root user
|
|
||||||
USER nextjs
|
USER nextjs
|
||||||
|
|
||||||
# Expose the port Next.js listens on
|
|
||||||
EXPOSE 3000
|
EXPOSE 3000
|
||||||
|
|
||||||
# Command to start the Next.js server in production mode
|
# server.js is generated by Next.js at the root of the standalone output.
|
||||||
CMD ["node", "server.js"]
|
CMD ["node", "server.js"]
|
||||||
Reference in New Issue
Block a user