Docker und JavaScript: Containerisierung von Node.js-Anwendungen (Fortgeschrittenenniveau)

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Einleitung: Vom Monolithen zu Microservices mit Docker und JavaScript

Moderne Webentwicklung in JavaScript (insbesondere im Node.js-Ökosystem) ist ohne Containerisierung undenkbar. Docker hat aufgehört, nur ein Werkzeug zum "Verpacken" einer Anwendung zu sein — es ist der De-facto-Standard für die Auslieferung, Skalierung und Verwaltung von Microservices. Wenn Sie bereits die grundlegenden Dockerfile- und docker run-Befehle beherrschen, ist es Zeit, zum fortgeschrittenen Level überzugehen.

In diesem Artikel analysieren wir, wie man effiziente, sichere und schlanke Docker-Images für Node.js erstellt, Multi-Container-Umgebungen mit Docker Compose konfiguriert, die serviceübergreifende Kommunikation über Netzwerke organisiert und Daten über Volumes kompetent verwaltet. Das Material richtet sich an Entwickler, die produktionsreife Architekturen erstellen möchten.



1. Optimierung des Dockerfile für Node.js: Layer, Caching und Sicherheit

Ein klassisches Dockerfile für Node.js sieht oft so aus: FROM node:18, COPY . /app, RUN npm install. Dieser Ansatz führt jedoch zu riesigen Images (über 1 GB) und langen Build-Zeiten. Fortgeschrittene Optimierung basiert auf drei Prinzipien:



1.1 Multi-Stage-Builds

Trennen Sie den Prozess in eine Build-Stufe (mit Compilern und dev-Abhängigkeiten) und eine Laufzeit-Stufe (nur Laufzeit). Dadurch wird das endgültige Image um das 5- bis 10-fache reduziert.

# ---- Build Stage ----FROM node:18-alpine AS builderWORKDIR /appCOPY package*.json ./RUN npm ci --only=productionCOPY . .RUN npm run build

# ---- Runtime Stage ----FROM node:18-alpineWORKDIR /appCOPY --from=builder /app/dist ./distCOPY --from=builder /app/node_modules ./node_modulesEXPOSE 3000CMD ["node", "dist/main.js"]


1.2 Verwendung von .dockerignore und Layer-Caching

Docker cached Layer. Um ein erneutes Ausführen von npm install bei jeder Codeänderung zu vermeiden, kopieren Sie package.json separat. Fügen Sie eine .dockerignore-Datei hinzu:

node_modules.git*.md.envdist

Jetzt wird npm install nur ausgeführt, wenn sich Abhängigkeiten ändern, nicht das gesamte Projekt.



1.3 Sicherheit: Nicht-Root-Benutzer und minimales Basis-Image

Verwenden Sie node:18-alpine (oder sogar scratch mit einem kompilierten Binary über pkg). Führen Sie Node.js niemals als root aus:

RUN addgroup -S appgroup && adduser -S appuser -G appgroupUSER appuser

Dies verhindert eine Rechteausweitung im Falle einer Kompromittierung der Anwendung.



2. Docker Compose: Multi-Container-Anwendung (Node.js + Redis + Nginx)

Eine echte Anwendung besteht selten aus nur einem Dienst. Docker Compose ermöglicht es Ihnen, die gesamte Infrastruktur mit einem einzigen Befehl docker-compose up hochzufahren. Betrachten wir ein fortgeschrittenes Beispiel: Node.js-API, Redis für Caching und Nginx als Reverse-Proxy.



2.1 Struktur der docker-compose.yml

version: '3.8'services:  app:    build:      context: ./app      dockerfile: Dockerfile.prod    ports:      - "3000:3000"    environment:      - REDIS_URL=redis://redis:6379      - NODE_ENV=production    depends_on:      - redis    restart: unless-stopped

redis: image: redis:7-alpine volumes: - redis-data:/data healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 3s retries: 3

nginx: image: nginx:alpine ports: - "80:80" volumes: - ./nginx.conf:/etc/nginx/nginx.conf:ro depends_on: - app

volumes: redis-data:


2.2 Fortgeschrittene Einstellungen: Healthcheck und Abhängigkeiten

depends_on garantiert die Startreihenfolge, wartet aber nicht auf die Bereitschaft des Dienstes. Verwenden Sie healthcheck für Redis und ein Warteskript in der Anwendung:

// In index.js Node.js
const co                

Blogs

Buchempfehlungen