Compare commits

...
2 Commits
Author SHA1 Message Date
Nick SzaunigandClaude Opus 5.5 9c7d2d02a2 docs(k8s): Deployment Schritt fuer Schritt wie bei Wabenhain
Docker-Images bauen und veroeffentlichen / build-and-push (push) Successful in 1m53s
Voraussetzungen pruefen (Traefik, cert-manager, csi-driver-smb),
Einzel-Applies in Reihenfolge mit kubectl wait auf Postgres,
Fehlersuche fuer Migration, App und Zertifikat.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
2026-09-28 06:33:47 +02:00
Nick SzaunigandClaude Opus 5.5 cddc36bee8 feat(k8s): Ingress, Zertifikat und Netzwerk nach Muster Wabenhain/ApiCore
- Ingress: HTTP->HTTPS-Middleware redirect-to-https wieder am Ingress
  (wie Wabenhain), Service-Port als Nummer, cert-manager letsencrypt-prod.
- NetworkPolicy: Traefik ueber das Pod-Label (traefik/rke2-traefik) in
  jedem Namespace erkannt statt fester Namespace "traefik" - verhindert,
  dass die Seite unerreichbar wird, wenn Traefik z. B. in kube-system laeuft.
- README: Voraussetzungen pruefen und Deployment Schritt fuer Schritt
  (kubectl wait auf Postgres) wie bei Wabenhain.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
2026-09-28 06:33:22 +02:00
3 changed files with 80 additions and 32 deletions

No files matched your search

+15 -2
View File
@@ -1,4 +1,5 @@
# ANPASSEN: Domain (2x, auch APP_URL in 01-config.yaml), ClusterIssuer. # Ingress fuer Traefik + cert-manager (gleiches Muster wie Wabenhain).
# ANPASSEN: Domain (2x, auch APP_URL in 01-config.yaml).
apiVersion: networking.k8s.io/v1 apiVersion: networking.k8s.io/v1
kind: Ingress kind: Ingress
metadata: metadata:
@@ -6,6 +7,8 @@ metadata:
namespace: artista namespace: artista
annotations: annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod cert-manager.io/cluster-issuer: letsencrypt-prod
# HTTP -> HTTPS ueber die Middleware unten (Praefix = Namespace).
traefik.ingress.kubernetes.io/router.middlewares: artista-redirect-to-https@kubernetescrd
spec: spec:
ingressClassName: traefik ingressClassName: traefik
tls: tls:
@@ -21,4 +24,14 @@ spec:
service: service:
name: artista-modelcamp-app name: artista-modelcamp-app
port: port:
name: http number: 80
---
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: redirect-to-https
namespace: artista
spec:
redirectScheme:
scheme: https
permanent: true
+9 -4
View File
@@ -1,5 +1,7 @@
# Datenbank nur fuer App und Worker erreichbar; App nur ueber Traefik. # Datenbank nur fuer App und Worker erreichbar; App nur ueber Traefik.
# ANPASSEN: Namespace deines Traefik ("kubectl get pods -A | grep traefik"). # Traefik wird am Pod-Label erkannt, egal in welchem Namespace es laeuft
# (eigene Installation "traefik" oder RKE2-Paket "rke2-traefik").
# Pruefen: kubectl get pods -A -l 'app.kubernetes.io/name in (traefik,rke2-traefik)'
apiVersion: networking.k8s.io/v1 apiVersion: networking.k8s.io/v1
kind: NetworkPolicy kind: NetworkPolicy
metadata: metadata:
@@ -28,8 +30,11 @@ spec:
app: artista-modelcamp-app app: artista-modelcamp-app
ingress: ingress:
- from: - from:
- namespaceSelector: - namespaceSelector: {}
matchLabels: podSelector:
kubernetes.io/metadata.name: traefik matchExpressions:
- key: app.kubernetes.io/name
operator: In
values: [traefik, rke2-traefik]
ports: ports:
- port: 3000 - port: 3000
+56 -26
View File
@@ -1,37 +1,67 @@
# Kubernetes (RKE2, Traefik, cert-manager) # ARTISTA Modelcamp in Kubernetes (RKE2)
## Einmalig Rohe Manifeste wie bei Wabenhain, Nummerierung = Reihenfolge. Voraussetzungen im Cluster (wie bei Wabenhain):
- **Traefik** als Ingress-Controller (IngressClass `traefik`)
- **cert-manager** mit dem ClusterIssuer `letsencrypt-prod`
- **csi-driver-smb** für die SMB-Volumes
1. **csi-driver-smb installieren:** Prüfen:
```bash
kubectl get ingressclass
kubectl get clusterissuer letsencrypt-prod
kubectl get pods -A -l 'app.kubernetes.io/name in (traefik,rke2-traefik)'
```
## Einmalige Vorbereitung
1. **Images:** `.gitea/workflows/docker-build.yml` baut bei jedem Push auf `main` die Images `git.encry.de/nick.rosenloecher/artista-modelcamp:latest` und `…-tools:latest`. Voraussetzung ist das Repo-Secret `REGISTRY_TOKEN` (Personal Access Token mit `package`-Scope), wie bei Wabenhain.
2. **csi-driver-smb** (falls noch nicht vorhanden):
```bash ```bash
helm repo add csi-driver-smb https://raw.githubusercontent.com/kubernetes-csi/csi-driver-smb/master/charts helm repo add csi-driver-smb https://raw.githubusercontent.com/kubernetes-csi/csi-driver-smb/master/charts
helm install csi-driver-smb csi-driver-smb/csi-driver-smb -n kube-system helm install csi-driver-smb csi-driver-smb/csi-driver-smb -n kube-system
``` ```
2. **Auf dem NAS** die Ordner `artista/modelcamp-postgres` (leer) und `artista/modelcamp-media` anlegen und SMB-Verschlüsselung erlauben. 3. **NAS:** Die Ordner `artista/modelcamp-postgres` (leer) und `artista/modelcamp-media` anlegen und SMB-Verschlüsselung erlauben. `nas.example.lan` in `02-storage.yaml` anpassen.
3. **Anpassen:** 4. **Domain:** `modelcamp.example.org` in `01-config.yaml` (APP_URL) und `05-ingress.yaml` (2×) ersetzen. Der DNS-Eintrag muss auf den Cluster zeigen, sonst stellt cert-manager kein Zertifikat aus.
- `nas.example.lan` in `02-storage.yaml` 5. **Secrets:** `cp k8s/secrets.yaml.example k8s/secrets.yaml` und ausfüllen. Die Datei steht in `.gitignore`, bitte **nie** mit echten Werten committen.
- `modelcamp.example.org` in `01-config.yaml` und `05-ingress.yaml`
- den Traefik-Namespace in `07-networkpolicy.yaml`
4. **Secrets:** `cp k8s/secrets.yaml.example k8s/secrets.yaml`, die Werte eintragen.
5. **Ausrollen:**
```bash
kubectl apply -f k8s/00-namespace.yaml
kubectl apply -f k8s/secrets.yaml
kubectl apply -f k8s/
```
6. **Admin anlegen** (E-Mail und Name ersetzen; das einmalige Passwort wird ausgegeben, die 2FA richtest du bei der ersten Anmeldung unter `/admin` ein):
```bash
kubectl -n artista run admin-create --rm -i --restart=Never \
--image=git.encry.de/nick.rosenloecher/artista-modelcamp-tools:latest --labels=db-client=true \
--overrides='{"spec":{"securityContext":{"runAsNonRoot":true,"runAsUser":1001,"seccompProfile":{"type":"RuntimeDefault"}},"containers":[{"name":"admin-create","image":"git.encry.de/nick.rosenloecher/artista-modelcamp-tools:latest","command":["tsx","scripts/create-admin.ts","--email","[email protected]","--name","Dein Name"],"envFrom":[{"configMapRef":{"name":"artista-modelcamp-config"}},{"secretRef":{"name":"artista-modelcamp-secrets"}}],"securityContext":{"allowPrivilegeEscalation":false,"capabilities":{"drop":["ALL"]}}}]}}'
```
## Update ## Deployment
Bei jedem Push auf `main` baut die Gitea-Pipeline die Images mit dem Tag `latest`. Danach:
```bash ```bash
kubectl -n artista rollout restart deploy/artista-modelcamp-app kubectl apply -f k8s/00-namespace.yaml
kubectl apply -f k8s/secrets.yaml
kubectl apply -f k8s/01-config.yaml
kubectl apply -f k8s/02-storage.yaml
kubectl apply -f k8s/03-postgres.yaml
kubectl wait --for=condition=ready pod -l app=artista-modelcamp-postgres -n artista --timeout=180s
kubectl apply -f k8s/04-app.yaml
kubectl apply -f k8s/05-ingress.yaml
kubectl apply -f k8s/06-worker.yaml
kubectl apply -f k8s/07-networkpolicy.yaml
``` ```
Der initContainer migriert die Datenbank automatisch. Die Migration läuft automatisch als initContainer vor dem App-Start. Den Fortschritt zeigt `kubectl rollout status deployment/artista-modelcamp-app -n artista`, das Zertifikat `kubectl get certificate -n artista`.
## Erstes Admin-Konto
E-Mail und Name ersetzen. Das einmalige Passwort wird ausgegeben, die 2FA richtest du bei der ersten Anmeldung unter `/admin` ein.
```bash
kubectl -n artista run admin-create --rm -i --restart=Never \
--image=git.encry.de/nick.rosenloecher/artista-modelcamp-tools:latest --labels=db-client=true \
--overrides='{"spec":{"securityContext":{"runAsNonRoot":true,"runAsUser":1001,"seccompProfile":{"type":"RuntimeDefault"}},"containers":[{"name":"admin-create","image":"git.encry.de/nick.rosenloecher/artista-modelcamp-tools:latest","command":["tsx","scripts/create-admin.ts","--email","[email protected]","--name","Dein Name"],"envFrom":[{"configMapRef":{"name":"artista-modelcamp-config"}},{"secretRef":{"name":"artista-modelcamp-secrets"}}],"securityContext":{"allowPrivilegeEscalation":false,"capabilities":{"drop":["ALL"]}}}]}}'
```
## Bei einem neuen Image (Redeploy)
```bash
kubectl rollout restart deployment/artista-modelcamp-app -n artista
```
## Fehlersuche
```bash
kubectl -n artista logs deploy/artista-modelcamp-app -c migrate # Migration
kubectl -n artista logs deploy/artista-modelcamp-app -c app # App
kubectl -n artista describe certificate artista-modelcamp-tls # Zertifikat
```