diff --git a/DEPLOYMENT.md b/DEPLOYMENT.md index 4a6949c..0f9358e 100644 --- a/DEPLOYMENT.md +++ b/DEPLOYMENT.md @@ -40,9 +40,14 @@ Die Pipeline wird durch `.gitea/workflows/deploy.yml` definiert und umfasst: ### Docker Images Alle Images werden in der Harbor Registry gespeichert: -- `registry.julianvollmer.de/florale-emotion/florale-emotion-frontend` -- `registry.julianvollmer.de/florale-emotion/florale-emotion-backend` -- `registry.julianvollmer.de/florale-emotion/florale-emotion-bot` +- `registry.julianvollmer.de/florale-emotion/florale-emotion-frontend` (Node.js 20 + Angular 17) +- `registry.julianvollmer.de/florale-emotion/florale-emotion-backend` (Node.js 20 + Express) +- `registry.julianvollmer.de/florale-emotion/florale-emotion-bot` (Node.js 20 + Cron Jobs) + +### Technische Anforderungen +- **Node.js Version:** 20+ (erforderlich für AWS SDK) +- **Angular CLI:** Wird als devDependency installiert +- **Build-Prozess:** Multi-stage Docker Build für optimale Image-Größe ## Kubernetes-Manifeste @@ -63,12 +68,21 @@ Alle Images werden in der Harbor Registry gespeichert: - Scheduled/Cron-basierte Ausführung - Resource Limits: 256Mi RAM, 100m CPU -### Ingress Konfiguration +### Ingress Konfiguration (Traefik) - **Production** (`ingress.yaml`): florale-emotion.de, www.florale-emotion.de, api.florale-emotion.de - **Development** (`ingress-dev.yaml`): dev.florale-emotion.de, api-dev.florale-emotion.de +- Traefik als Kubernetes Ingress Controller - Automatische SSL-Zertifikate via Let's Encrypt - HTTPS-Weiterleitung aktiviert +### DNS-Konfiguration +Folgende DNS-Einträge sind erforderlich: +``` +dev.florale-emotion.de CNAME traefik.julianvollmer.de +api-dev.florale-emotion.de CNAME traefik.julianvollmer.de +api.florale-emotion.de CNAME traefik.julianvollmer.de +``` + ## Deployment-Prozess ### Automatisches Deployment diff --git a/website/Dockerfile b/website/Dockerfile index 220dc10..d5386df 100644 --- a/website/Dockerfile +++ b/website/Dockerfile @@ -1,5 +1,5 @@ # Multi-stage build for Angular Frontend -FROM node:18-alpine AS builder +FROM node:20-alpine AS builder # Set working directory WORKDIR /app @@ -7,14 +7,14 @@ WORKDIR /app # Copy package files COPY package*.json ./ -# Install dependencies -RUN npm ci --only=production +# Install ALL dependencies (including devDependencies for Angular CLI) +RUN npm ci # Copy source code COPY . . -# Build the Angular application -RUN npm run build --prod +# Build the Angular application for production +RUN npm run build:prod # Production stage FROM nginx:alpine diff --git a/website/backend/Dockerfile b/website/backend/Dockerfile index aafca2b..fdef5b9 100644 --- a/website/backend/Dockerfile +++ b/website/backend/Dockerfile @@ -1,4 +1,4 @@ -FROM node:18-alpine +FROM node:20-alpine # Set working directory WORKDIR /app diff --git a/website/backend/healthcheck.js b/website/backend/healthcheck.js index ac95b0c..c0142e5 100644 --- a/website/backend/healthcheck.js +++ b/website/backend/healthcheck.js @@ -3,7 +3,7 @@ const http = require('http'); const options = { hostname: 'localhost', port: process.env.PORT || 3000, - path: '/health', + path: '/api/health', method: 'GET', timeout: 2000 }; diff --git a/website/backend/package.json b/website/backend/package.json index 4817860..0087b4b 100644 --- a/website/backend/package.json +++ b/website/backend/package.json @@ -19,6 +19,6 @@ "nodemon": "^3.0.1" }, "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" } } \ No newline at end of file diff --git a/website/k8s/backend.yaml b/website/k8s/backend.yaml index e6e23ec..368ac10 100644 --- a/website/k8s/backend.yaml +++ b/website/k8s/backend.yaml @@ -35,13 +35,13 @@ spec: cpu: "300m" livenessProbe: httpGet: - path: /health + path: /api/health port: 3000 initialDelaySeconds: 30 periodSeconds: 10 readinessProbe: httpGet: - path: /health + path: /api/health port: 3000 initialDelaySeconds: 10 periodSeconds: 5 diff --git a/website/k8s/bot.yaml b/website/k8s/bot.yaml index 6a4853c..c7450e6 100644 --- a/website/k8s/bot.yaml +++ b/website/k8s/bot.yaml @@ -31,16 +31,5 @@ spec: cpu: "100m" # Social Media Bot läuft als Cronjob/Scheduled Task # Keine Health Checks nötig da es kein HTTP Service ist ---- -apiVersion: v1 -kind: Service -metadata: - name: florale-emotion-bot-service -spec: - selector: - app: florale-emotion-bot - ports: - - protocol: TCP - port: 8080 - targetPort: 8080 - type: ClusterIP \ No newline at end of file +# Bot läuft als interner Service ohne öffentliche Exposition +# Kein Service nötig, da keine HTTP-Requests von außen \ No newline at end of file diff --git a/website/k8s/ingress-dev.yaml b/website/k8s/ingress-dev.yaml index 7c3a7b0..84ce280 100644 --- a/website/k8s/ingress-dev.yaml +++ b/website/k8s/ingress-dev.yaml @@ -3,11 +3,9 @@ kind: Ingress metadata: name: florale-emotion-dev-ingress annotations: - kubernetes.io/ingress.class: "nginx" + kubernetes.io/ingress.class: "traefik" cert-manager.io/cluster-issuer: "letsencrypt-prod" - nginx.ingress.kubernetes.io/ssl-redirect: "true" - nginx.ingress.kubernetes.io/force-ssl-redirect: "true" - nginx.ingress.kubernetes.io/redirect-to-https: "true" + traefik.ingress.kubernetes.io/redirect-to-https: "true" spec: tls: - hosts: diff --git a/website/k8s/ingress.yaml b/website/k8s/ingress.yaml index 7f0ade8..646cc3e 100644 --- a/website/k8s/ingress.yaml +++ b/website/k8s/ingress.yaml @@ -3,11 +3,9 @@ kind: Ingress metadata: name: florale-emotion-ingress annotations: - kubernetes.io/ingress.class: "nginx" + kubernetes.io/ingress.class: "traefik" cert-manager.io/cluster-issuer: "letsencrypt-prod" - nginx.ingress.kubernetes.io/ssl-redirect: "true" - nginx.ingress.kubernetes.io/force-ssl-redirect: "true" - nginx.ingress.kubernetes.io/redirect-to-https: "true" + traefik.ingress.kubernetes.io/redirect-to-https: "true" spec: tls: - hosts: diff --git a/website/social-media-bot/Dockerfile b/website/social-media-bot/Dockerfile index 67ea7d5..4203cd2 100644 --- a/website/social-media-bot/Dockerfile +++ b/website/social-media-bot/Dockerfile @@ -1,4 +1,4 @@ -FROM node:18-alpine +FROM node:20-alpine # Set working directory WORKDIR /app diff --git a/website/social-media-bot/package.json b/website/social-media-bot/package.json index 246b719..d701562 100644 --- a/website/social-media-bot/package.json +++ b/website/social-media-bot/package.json @@ -17,6 +17,6 @@ "nodemon": "^3.0.1" }, "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" } } \ No newline at end of file