Next.js-Anwendung auf Docker Hub bereitstellen

Cover Image for Next.js-Anwendung auf Docker Hub bereitstellen

Voraussetzungen

Stellen Sie sicher, dass Sie die Voraussetzungen aus dem vorherigen Beitrag erfüllt haben. Vergewissern Sie sich außerdem, dass Sie ein Konto bei Docker Hub haben und Docker auf Ihrem System installiert ist. Eine Anleitung zur Installation von Docker finden Sie hier.

Ein einfaches Dockerfile erstellen

Um eine Next.js-Anwendung auf Docker Hub bereitzustellen, müssen wir ein Dockerfile im Stammverzeichnis unseres Projekts erstellen. Für den Anfang reicht ein sehr einfaches Setup:

Dockerfile
FROM node:18
 
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD npm run dev

Dieses Dockerfile nutzt das offizielle node-Image als Basis. Es setzt das Arbeitsverzeichnis auf /app, kopiert die package.json- und package-lock.json-Dateien, installiert die Abhängigkeiten, kopiert den Rest der Dateien, gibt den Port 3000 frei und startet die Next.js-Anwendung im Entwicklungsmodus.

Sie können das Docker-Image nun wie folgt bauen:

docker build -t my-next-js-app .

Und den Docker-Container starten:

docker run -p 3000:3000 my-next-js-app

Ihre Anwendung ist nun unter http://localhost:3000 im Browser erreichbar. Das funktioniert zwar für den Anfang, ist aber nicht für den produktiven Einsatz geeignet.

Ein produktionsreifes Dockerfile erstellen

Für ein produktionsreifes Dockerfile empfiehlt es sich, die Vorlage von Vercel zu nutzen. Diese bietet gegenüber dem einfachen Dockerfile mehrere Vorteile:

  • Multi-Stage Build: Reduziert die Größe des fertigen Images massiv.
  • Output Traces: Nutzt automatische Abhängigkeitsanalyse, um den Speicherplatzbedarf weiter zu minimieren.
  • Sicherheit: Die Anwendung läuft unter einem Non-Root-User.
  • Kein Dev-Modus: Schaltet Entwicklungs-Features aus und schützt Quellcodes im Live-Betrieb.

Hier ist das optimierte Dockerfile:

Dockerfile
FROM node:18-alpine AS base
 
# Install dependencies only when needed
FROM base AS deps
RUN apk add --no-cache libc6-compat
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci
 
# Rebuild the source code only when needed
FROM base AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npm run build
 
# Production image, copy all the files and run next
FROM base AS runner
WORKDIR /app
ENV NODE_ENV production
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs
 
COPY --from=builder /app/public ./public
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
 
USER nextjs
EXPOSE 3000
ENV PORT 3000
CMD ["node", "server.js"]

Beachten Sie, dass dieses Dockerfile anonyme Telemetriedaten sammelt. Sie können dies deaktivieren, indem Sie die Umgebungsvariable NEXT_TELEMETRY_DISABLED auf 1 setzen.

Bevor wir das Image bauen können, müssen wir die next.config.(m)js bearbeiten und die Option output: "standalone" hinzufügen:

next.config.(m)js
/** @type {import('next').NextConfig} */
const nextConfig = { output: "standalone" };
 
export default nextConfig;

Jetzt können wir unser Produktions-Docker-Image erstellen, indem wir folgenden Befehl ausführen:

docker build -t my-next-js-app .

Und den Docker-Container starten via:

docker run -p 3000:3000 my-next-js-app

Das Docker-Image auf Docker Hub pushen

Bevor wir das Docker-Image auf Docker Hub hochladen, müssen wir ein Repository erstellen. Melde dich dazu in einem Browser bei deinem Docker Hub-Konto an > klicke auf Create Repository > lege einen Namen für das Repository fest > wähle die Sichtbarkeit > klicke auf Create.

Nun können wir das Docker-Image auf Docker Hub pushen. Zuerst müssen wir uns über das Terminal bei Docker Hub anmelden:

docker login

Jetzt können wir das Docker-Image mit dem Repository-Namen taggen:

docker tag my-next-js-app:latest mein-docker-hub-benutzername/my-next-js-app:latest

Und das Docker-Image zu Docker Hub hochladen:

docker push mein-docker-hub-benutzername/my-next-js-app:latest

Glückwunsch! Deine Next.js-Anwendung ist nun auf Docker Hub verfügbar! 🥳

Fazit

Die Containerisierung deiner Anwendung ist die größte Hürde im modernen Deployment. Jetzt, da dein Image gehostet ist, hast du die Tür zu professioneller Skalierung weit geöffnet.

Bringe dein Projekt auf das nächste Level:

Nächste Artikel.

Cover Image for Internal TryHackMe Write-Up

Internal TryHackMe Write-Up

The Internal room on TryHackMe is an hard challenge that let's you slip in the role of a penetration tester, where your objective is to perform a thorough penetration test