refactor: update Dockerfile and docker-compose.yml for Next.js 16 optimization and improved build process
This commit is contained in:
+49
-14
@@ -1,26 +1,61 @@
|
|||||||
# docker-compose.yml
|
# =============================================================================
|
||||||
version: "3.8"
|
# Docker Compose - Production Configuration for Coolify
|
||||||
|
# =============================================================================
|
||||||
|
# Optimized for:
|
||||||
|
# - Fast cold starts
|
||||||
|
# - Minimal resource usage
|
||||||
|
# - Zero-downtime deployments
|
||||||
|
# - Coolify compatibility
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
services:
|
services:
|
||||||
frontend:
|
app:
|
||||||
build:
|
build:
|
||||||
context: .
|
context: .
|
||||||
dockerfile: Dockerfile
|
dockerfile: Dockerfile
|
||||||
|
# Enable BuildKit for faster builds and layer caching
|
||||||
args:
|
args:
|
||||||
- NODE_ENV=${NODE_ENV}
|
- BUILDKIT_INLINE_CACHE=1
|
||||||
- DEV_MODE=${DEV_MODE}
|
- DOCKER_BUILDKIT=1
|
||||||
- NEXT_TELEMETRY_DISABLED=1
|
# Cache strategy for faster rebuilds
|
||||||
- NEXT_PUBLIC_API_URL=${NEXT_PUBLIC_API_URL}
|
cache_from:
|
||||||
- NEXT_PUBLIC_CLIENT_ID=${NEXT_PUBLIC_CLIENT_ID}
|
- node:20-alpine
|
||||||
- NEXT_PUBLIC_CLIENT_SECRET=${NEXT_PUBLIC_CLIENT_SECRET}
|
|
||||||
|
# Container restart policy
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
|
||||||
|
# Dynamic port mapping (Coolify manages external port)
|
||||||
ports:
|
ports:
|
||||||
- "${APP_PORT}:3000"
|
- "3000"
|
||||||
|
|
||||||
|
# Environment variables
|
||||||
|
# Note: Coolify injects these automatically from project settings
|
||||||
environment:
|
environment:
|
||||||
- NEXT_TELEMETRY_DISABLED=1
|
# Node.js
|
||||||
- DEV_MODE=${DEV_MODE}
|
- NODE_ENV=${NODE_ENV:-production}
|
||||||
|
- PORT=3000
|
||||||
|
- HOSTNAME=0.0.0.0
|
||||||
|
- DEV_MODE=false
|
||||||
- NEXT_PUBLIC_API_URL=${NEXT_PUBLIC_API_URL}
|
- NEXT_PUBLIC_API_URL=${NEXT_PUBLIC_API_URL}
|
||||||
- NEXT_PUBLIC_CLIENT_ID=${NEXT_PUBLIC_CLIENT_ID}
|
- NEXT_PUBLIC_CLIENT_ID=${NEXT_PUBLIC_CLIENT_ID}
|
||||||
- NEXT_PUBLIC_CLIENT_SECRET=${NEXT_PUBLIC_CLIENT_SECRET}
|
- NEXT_PUBLIC_CLIENT_SECRET=${NEXT_PUBLIC_CLIENT_SECRET}
|
||||||
- APP_PORT=${APP_PORT}
|
|
||||||
- NODE_ENV=${NODE_ENV}
|
# Resource limits (optimized for low traffic sites)
|
||||||
|
deploy:
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
cpus: "0.5"
|
||||||
|
memory: 512M
|
||||||
|
reservations:
|
||||||
|
cpus: "0.1"
|
||||||
|
memory: 128M
|
||||||
|
|
||||||
|
# Networks (Coolify uses bridge network)
|
||||||
|
networks:
|
||||||
|
- coolify
|
||||||
|
|
||||||
|
# Network configuration
|
||||||
|
networks:
|
||||||
|
coolify:
|
||||||
|
driver: bridge
|
||||||
|
external: true
|
||||||
|
|||||||
+101
-27
@@ -1,48 +1,122 @@
|
|||||||
# Dockerfile for Next.js 14 - Optimized for Production
|
# =============================================================================
|
||||||
|
# Dockerfile for Next.js 16 - Production Optimized for Coolify
|
||||||
|
# =============================================================================
|
||||||
|
# Multi-stage build for minimal image size and maximum performance
|
||||||
|
# Compatible with: Coolify, Docker Compose, Kubernetes
|
||||||
|
# Node Version: 20 LTS (Alpine)
|
||||||
|
# Package Manager: npm (native to project)
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
# Use the official Node.js image with Alpine Linux for a smaller footprint
|
# -----------------------------------------------------------------------------
|
||||||
FROM node:22-alpine AS base
|
# Stage 1: Dependencies (deps)
|
||||||
|
# Install only production dependencies with locked versions
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
FROM node:20-alpine AS deps
|
||||||
|
|
||||||
|
# Install system dependencies required by Node.js native modules
|
||||||
|
RUN apk add --no-cache libc6-compat
|
||||||
|
|
||||||
# Set the working directory in the container
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
# Copy package.json and package-lock.json (or yarn.lock)
|
# Copy package files for dependency installation
|
||||||
COPY package*.json ./
|
COPY package.json package-lock.json ./
|
||||||
|
|
||||||
# Install dependencies - leveraging Docker cache
|
# Install dependencies with npm ci (clean install from lock file)
|
||||||
RUN npm i --force
|
# This ensures reproducible builds and faster installs
|
||||||
|
RUN npm ci --only=production --ignore-scripts && \
|
||||||
|
npm cache clean --force
|
||||||
|
|
||||||
# Copy the rest of the application code
|
# -----------------------------------------------------------------------------
|
||||||
|
# Stage 2: Builder (builder)
|
||||||
|
# Build the Next.js application with all dev dependencies
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
FROM node:20-alpine AS builder
|
||||||
|
|
||||||
|
# Install system dependencies for Prisma and build tools
|
||||||
|
RUN apk add --no-cache \
|
||||||
|
libc6-compat \
|
||||||
|
openssl
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Copy package files
|
||||||
|
COPY package.json package-lock.json ./
|
||||||
|
|
||||||
|
# Install ALL dependencies (including devDependencies for build)
|
||||||
|
RUN npm ci --ignore-scripts && \
|
||||||
|
npm cache clean --force
|
||||||
|
|
||||||
|
# Copy application source
|
||||||
COPY . .
|
COPY . .
|
||||||
|
|
||||||
# Build the Next.js application
|
# Set build-time environment variables
|
||||||
|
ENV NEXT_TELEMETRY_DISABLED=1
|
||||||
|
ENV NODE_ENV=production
|
||||||
|
|
||||||
|
# Generate Prisma Client
|
||||||
|
RUN npx prisma generate
|
||||||
|
|
||||||
|
# Build Next.js application with standalone output
|
||||||
|
# This creates a minimal server bundle in .next/standalone
|
||||||
RUN npm run build
|
RUN npm run build
|
||||||
|
|
||||||
# Stage 2: Production image - smaller and leaner
|
# -----------------------------------------------------------------------------
|
||||||
FROM node:22-alpine AS runner
|
# Stage 3: Runner (production)
|
||||||
|
# Minimal runtime image with only necessary files
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
FROM node:20-alpine AS runner
|
||||||
|
|
||||||
|
# Install runtime dependencies
|
||||||
|
RUN apk add --no-cache \
|
||||||
|
libc6-compat \
|
||||||
|
openssl \
|
||||||
|
wget \
|
||||||
|
dumb-init && \
|
||||||
|
rm -rf /var/cache/apk/*
|
||||||
|
|
||||||
# Set the working directory
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
# Set environment variables
|
# Set production environment variables
|
||||||
ENV NODE_ENV $NODE_ENV
|
ENV NODE_ENV=production
|
||||||
ENV NEXT_TELEMETRY_DISABLED 1
|
ENV NEXT_TELEMETRY_DISABLED=1
|
||||||
|
ENV PORT=3000
|
||||||
|
ENV HOSTNAME=0.0.0.0
|
||||||
|
|
||||||
# Add a non-root user for security
|
# Create 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
|
# Copy Prisma runtime files
|
||||||
COPY --from=base /app/next.config.js ./
|
COPY --from=builder --chown=nextjs:nodejs /app/node_modules/.prisma ./node_modules/.prisma
|
||||||
COPY --from=base /app/public ./public
|
COPY --from=builder --chown=nextjs:nodejs /app/node_modules/@prisma ./node_modules/@prisma
|
||||||
COPY --from=base --chown=nextjs:nodejs /app/.next/standalone ./
|
|
||||||
COPY --from=base --chown=nextjs:nodejs /app/.next/static ./.next/static
|
|
||||||
|
|
||||||
# Change ownership of all copied files to the non-root user
|
# Copy standalone Next.js server
|
||||||
|
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
|
||||||
|
|
||||||
|
# Copy static files
|
||||||
|
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
|
||||||
|
|
||||||
|
# Copy public directory
|
||||||
|
COPY --from=builder --chown=nextjs:nodejs /app/public ./public
|
||||||
|
|
||||||
|
# Copy Prisma schema for runtime (if needed)
|
||||||
|
COPY --from=builder --chown=nextjs:nodejs /app/prisma ./prisma
|
||||||
|
|
||||||
|
# Copy scripts directory for seed and admin tools
|
||||||
|
COPY --from=builder --chown=nextjs:nodejs /app/scripts ./scripts
|
||||||
|
|
||||||
|
# Switch to non-root user
|
||||||
USER nextjs
|
USER nextjs
|
||||||
|
|
||||||
# Expose the port Next.js listens on
|
# Expose application port
|
||||||
EXPOSE 3000
|
EXPOSE 3000
|
||||||
|
|
||||||
# Command to start the Next.js server in production mode
|
# Health check for container orchestration
|
||||||
|
HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \
|
||||||
|
CMD wget --no-verbose --tries=1 --spider http://localhost:3000/api/health || exit 1
|
||||||
|
|
||||||
|
# Use dumb-init to handle signals properly
|
||||||
|
ENTRYPOINT ["dumb-init", "--"]
|
||||||
|
|
||||||
|
# Start the Next.js server
|
||||||
CMD ["node", "server.js"]
|
CMD ["node", "server.js"]
|
||||||
Reference in New Issue
Block a user