refactor(docker): update Dockerfile for Next.js 15 and improve environment variable handling
This commit is contained in:
+61
-29
@@ -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
|
||||
|
||||
# Set the working directory in the container
|
||||
# libc6-compat is recommended by the Next.js image for some native deps (sharp, etc.)
|
||||
RUN apk add --no-cache libc6-compat
|
||||
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 . .
|
||||
|
||||
# Build the Next.js application
|
||||
RUN npm run build
|
||||
|
||||
# Stage 2: Production image - smaller and leaner
|
||||
FROM node:22-alpine AS runner
|
||||
|
||||
# Set the working directory
|
||||
# ----------------------------------------------------------------------------
|
||||
# 3. Runner — minimal production image running the standalone server.
|
||||
# ----------------------------------------------------------------------------
|
||||
FROM base AS runner
|
||||
WORKDIR /app
|
||||
|
||||
# Set environment variables
|
||||
ENV NODE_ENV $NODE_ENV
|
||||
ENV NEXT_TELEMETRY_DISABLED 1
|
||||
ENV NODE_ENV=production
|
||||
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 addgroup -g 1001 -S nodejs
|
||||
RUN adduser -S nextjs -u 1001
|
||||
# Run as a non-root user for security.
|
||||
RUN addgroup --system --gid 1001 nodejs \
|
||||
&& adduser --system --uid 1001 nextjs
|
||||
|
||||
# Copy only the necessary files from the builder stage
|
||||
COPY --from=base /app/next.config.js ./
|
||||
COPY --from=base /app/public ./public
|
||||
COPY --from=base --chown=nextjs:nodejs /app/.next/standalone ./
|
||||
COPY --from=base --chown=nextjs:nodejs /app/.next/static ./.next/static
|
||||
# Public assets (served by the standalone server).
|
||||
COPY --from=builder /app/public ./public
|
||||
|
||||
# Standalone output already contains a minimal node_modules + server.js.
|
||||
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
|
||||
|
||||
# Expose the port Next.js listens on
|
||||
EXPOSE 3000
|
||||
|
||||
# Command to start the Next.js server in production mode
|
||||
CMD ["node", "server.js"]
|
||||
# server.js is generated by Next.js at the root of the standalone output.
|
||||
CMD ["node", "server.js"]
|
||||
|
||||
Reference in New Issue
Block a user