Files
beauty-bookings/docs/docker-build-stages.md

5.3 KiB

Docker Build Stages

Das Dockerfile definiert drei Build-Stages für unterschiedliche Deployment-Szenarien.

Stages Übersicht

1. builder

Zweck: Baut sowohl Client als auch Server-Artefakte

Verwendung: Wird als Basis für production Stage verwendet

Prozess:

  • Installiert alle Dependencies (inkl. devDependencies)
  • Baut Client mit Vite (dist/)
  • Baut Server mit TypeScript (server-dist/)
  • Kompiliert native Module (bcrypt) für Alpine Linux

2. production

Zweck: Vollständiger Build für Remote-Deployment (CI/CD, Production-Server)

Verwendung:

# docker-compose-prod.yml
build:
  context: .
  target: production

Prozess:

  1. Kopiert Source-Code (Client + Server) in Container
  2. Baut Client mit Vite (dist/)
  3. Baut Server mit TypeScript (server-dist/)
  4. Installiert nur Production-Dependencies
  5. Kompiliert native Module (bcrypt) für Alpine Linux
  6. Verifiziert bcrypt Installation

Vorteile:

  • Vollständig autark (keine lokalen Builds nötig)
  • Reproduzierbare Builds
  • Ideal für CI/CD-Pipelines

Nachteile:

  • ⏱️ Längere Build-Zeit (Client + Server werden im Container gebaut)

3. production-prebuilt

Zweck: Schnelles lokales Testing mit vorgebauten Artefakten

Verwendung:

# docker-compose.yml (lokal)
build:
  context: .
  target: production-prebuilt

Voraussetzungen:

  • dist/ und server-dist/ müssen bereits existieren
  • .dockerignore darf diese Verzeichnisse NICHT ausschließen
  • Lokal ausführen: pnpm run build vor docker compose build/up

Prozess:

  1. Kopiert vorgebaute dist/ und server-dist/ aus Build-Context
  2. Installiert nur Production-Dependencies
  3. Kompiliert native Module (bcrypt) für Alpine Linux
  4. Verifiziert bcrypt Installation
  5. Bei Fehlern schlägt der Build fehl

Vorteile:

  • Sehr schnelle Container-Builds (kein TypeScript/Vite-Build)
  • 🔄 Ideal für lokale Entwicklung und Testing

Nachteile:

  • Benötigt lokale Builds vor Docker-Build
  • Nicht geeignet für Remote-Deployment

Verwendungsempfehlungen

Lokale Entwicklung

# 1. Baue Artefakte lokal (Client + Server)
pnpm install --frozen-lockfile
pnpm run build   # erzeugt dist/ und server-dist/

# 2. Baue & starte Container mit production-prebuilt
docker compose build
docker compose up -d

Production-Deployment

# Nutzt production Stage (baut alles im Container)
docker-compose -f docker-compose-prod.yml up --build

CI/CD-Pipeline

# Explizit production Stage verwenden
docker build --target production -t myapp:latest .

Troubleshooting

Problem: "Cannot find module 'bcrypt'"

Ursache: Native Module (bcrypt) nicht korrekt für Alpine Linux kompiliert.

Lösung: Der Build schlägt jetzt absichtlich fehl, wenn bcrypt nicht kompiliert werden kann. Prüfe die Build-Logs und stelle sicher, dass Build-Tools (python3, make, g++) installiert sind. Im production-prebuilt-Szenario erfolgt ein Rebuild beim Container-Start.

Problem: "dist/ not found" im production-prebuilt Stage

Ursache: Lokale Builds fehlen

Lösung: Führe pnpm build vor docker-compose up aus

Problem: Container startet nicht in Production

Ursache: docker-compose-prod.yml nutzt falschen Stage

Lösung: Setze explizit target: production in docker-compose-prod.yml


Native Module (bcrypt)

bcrypt ist ein natives Node.js-Modul, das für die jeweilige Plattform kompiliert werden muss.

Im Dockerfile (Build & Verifikation):

# Build-Dependencies für native Module
RUN apk add --no-cache python3 make g++ libc6-compat

# Nach pnpm install: bcrypt neu kompilieren (Fehler NICHT unterdrücken) und verifizieren
RUN echo "[production] Rebuilding bcrypt for Alpine Linux..." \
 && pnpm rebuild bcrypt --build-from-source \
 && echo "[production] Verifying bcrypt installation..." \
 && node -e "require('bcrypt')"

Im Startup (production-prebuilt): Der Container verifiziert vor dem Start, dass bcrypt verfügbar ist, und bricht mit klarer Fehlermeldung ab, falls nicht.


Troubleshooting: Native Module (bcrypt)

Problem: bcrypt_lib.node nicht gefunden

Symptom: Container startet mit Fehler:

Error: Cannot find module '/app/node_modules/.pnpm/bcrypt@5.1.1/node_modules/bcrypt/lib/binding/napi-v3/bcrypt_lib.node'

Ursache: Native Module wie bcrypt müssen für die Zielplattform (Alpine Linux) kompiliert werden. Wenn lokal auf Windows/Mac gebaut wird, sind die Bindings inkompatibel.

Lösung:

  1. Für lokale Entwicklung (docker-compose.yml mit production-prebuilt):

    • Der Container rebuildet bcrypt automatisch beim Start
    • Prüfe Logs: docker compose logs stargirlnails | grep bcrypt
    • Bei Fehlern: docker compose down && docker compose build --no-cache
  2. Für Production (docker-compose-prod.yml mit production):

    • bcrypt wird während des Docker-Builds kompiliert
    • Build-Tools (python3, make, g++) sind im Image vorhanden
    • Bei Fehlern: Prüfe Build-Logs auf Compiler-Fehler
  3. Manuelle Verifikation:

docker compose exec stargirlnails node -e "require('bcrypt')"

Sollte ohne Fehler durchlaufen.

Best Practices

  • Niemals || true bei native Module Rebuilds verwenden
  • Immer Build-Tools im Production-Image behalten (python3, make, g++)
  • Testen nach jedem Dependency-Update mit --no-cache Build