Φόρτωση περιεχομένου...
Φόρτωση περιεχομένου...
Βελτιστοποιήστε δραστικά το μέγεθος των Docker images χρησιμοποιώντας multi-stage builds και το Next.js standalone output.
Ένα τυπικό λάθος των προγραμματιστών είναι η δημιουργία εικόνων Docker που περιέχουν ολόκληρο το Node.js SDK, όλα τα devDependencies, compilers (TypeScript, GCC) και τον source κώδικα. Αυτό οδηγεί σε τεράστια images μεγέθους 1.5GB+ με σοβαρά κενά ασφαλείας.
Σε αυτό το μάθημα θα δούμε πώς να μειώσετε το image μιας εφαρμογής Next.js 16 στα 85MB, εκμεταλλευόμενοι τα Multi-Stage Builds και το Standalone Output.
Στο αρχείο next.config.ts, προσθέστε τη ρύθμιση output: 'standalone':
typescriptimport type { NextConfig } from 'next'; const nextConfig: NextConfig = { output: 'standalone', // ... υπόλοιπες ρυθμίσεις }; export default nextConfig;
Αυτή η ρύθμιση λέει στο Next.js να εντοπίσει αυτόματα ποιες ακριβώς εξαρτήσεις από το node_modules χρειάζονται στο runtime και να δημιουργήσει ένα αυτόνομο bundle στον φάκελο .next/standalone. Δεν χρειάζεται πλέον να κουβαλάτε ολόκληρο το φάκελο node_modules!
Δημιουργήστε το αρχείο Dockerfile στη ρίζα του project:
dockerfile# syntax=docker/dockerfile:1 # ------------------------------------------------------------- # Stage 1: Base & Dependencies # ------------------------------------------------------------- FROM node:20-alpine AS deps RUN apk add --no-cache libc6-compat WORKDIR /app # Αντιγραφή αρχείων εξαρτήσεων για αξιοποίηση του Docker layer cache COPY package.json package-lock.json ./ RUN npm ci --frozen-lockfile # ------------------------------------------------------------- # Stage 2: Builder # ------------------------------------------------------------- FROM node:20-alpine AS builder WORKDIR /app COPY /app/node_modules ./node_modules COPY . . # Απενεργοποίηση Next.js telemetry κατά το build ENV NEXT_TELEMETRY_DISABLED=1 ENV NODE_ENV=production # Μεταγλώττιση Next.js RUN npm run build # ------------------------------------------------------------- # Stage 3: Runner (Μινιμαλιστική τελική εικόνα) # ------------------------------------------------------------- FROM node:20-alpine AS runner WORKDIR /app ENV NODE_ENV=production ENV NEXT_TELEMETRY_DISABLED=1 ENV PORT=3000 ENV HOSTNAME="0.0.0.0" # Δημιουργία μη-προνομιούχου χρήστη συστήματος για ασφάλεια RUN addgroup --system --gid 1001 nodejs && adduser --system --uid 1001 nextjs # Αντιγραφή static assets και standalone bundle COPY /app/public ./public COPY /app/.next/standalone ./ COPY /app/.next/static ./.next/static # Εκτέλεση ως μη-root χρήστης USER nextjs EXPOSE 3000 CMD ["node", "server.js"]
.dockerignoreΧωρίς σωστό .dockerignore, το Docker θα στέλνει γιγαντιαία άχρηστα αρχεία στο Docker daemon build context:
gitignoreDockerfile .dockerignore node_modules npm-debug.log .git .gitignore .next out .env*.local .env .vscode .idea
Εκτελέστε το build με το BuildKit ενεργοποιημένο:
bashdocker build -t roboschool-app:latest .
Ελέγξτε το μέγεθος της τελικής εικόνας:
bashdocker images | grep roboschool-app # roboschool-app latest 85.4MB
Η εικόνα περιλαμβάνει μόνο τα απολύτως απαραίτητα αρχεία runtime, ξεκινά σε κλάσματα δευτερολέπτου και έχει ελάχιστη επιφάνεια επίθεσης (attack surface).
Active Syntax: Multi-Stage Standalone DirectivesΣυμπληρώστε τα κενά σημεία1COPY --from= /app/public ./public2COPY --from= --chown=nextjs:nodejs /app/.next/standalone ./3USERToken Bank (Κάντε κλικ σε ένα token για αυτόματη εισαγωγή):