chore(docker): .dockerignore angepasst; lokale Build-Schritte in Rebuild-Skripten; Doku/README zu production vs production-prebuilt aktualisiert

This commit is contained in:
2025-10-06 18:59:17 +02:00
parent 7a84130aec
commit 1124b1f40b
24 changed files with 1149 additions and 270 deletions

181
docs/docker-build-stages.md Normal file
View File

@@ -0,0 +1,181 @@
# 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:**
```yaml
# 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:**
```yaml
# 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
```bash
# 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
```bash
# Nutzt production Stage (baut alles im Container)
docker-compose -f docker-compose-prod.yml up --build
```
### CI/CD-Pipeline
```bash
# 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):**
```dockerfile
# 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**:
```bash
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