Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a7c11ccbd0 | ||
|
|
24939b58d5 |
No files matched your search
+9
-9
@@ -26,10 +26,14 @@ Der Build braucht Internet für `next/font` (Schriften werden eingebettet), aber
|
|||||||
## 2. Einmalig einrichten
|
## 2. Einmalig einrichten
|
||||||
|
|
||||||
1. **Overlay anpassen** (`k8s/overlays/production/`): Image-Namen und Tag, Domain in `kustomization.yaml` (APP_URL) und `ingress.yaml`, `ingressClassName` (`kubectl get ingressclass`), ClusterIssuer (Beispiel `letsencrypt-prod`) und TLS-Secret-Name.
|
1. **Overlay anpassen** (`k8s/overlays/production/`): Image-Namen und Tag, Domain in `kustomization.yaml` (APP_URL) und `ingress.yaml`, `ingressClassName` (`kubectl get ingressclass`), ClusterIssuer (Beispiel `letsencrypt-prod`) und TLS-Secret-Name.
|
||||||
2. **StorageClasses:**
|
2. **Speicher:**
|
||||||
- PostgreSQL bekommt Blockspeicher mit ReadWriteOnce, auf keinen Fall eine SMB-Freigabe (Begründung in `k8s/base/postgres.yaml`).
|
- **PostgreSQL** bekommt Blockspeicher mit ReadWriteOnce (StorageClass im StatefulSet), auf keinen Fall eine SMB-Freigabe (Begründung in `k8s/base/postgres.yaml`).
|
||||||
- Das Medienvolume braucht ReadWriteMany, sonst `replicas: 1`.
|
- **Medien und Sicherungen** liegen auf SMB, über `k8s/overlays/production/smb-volumes.yaml`:
|
||||||
- Das Backup-Volume darf NFS oder SMB sein.
|
1. csi-driver-smb installieren, Befehl steht im Kopf der Datei.
|
||||||
|
2. Auf dem NAS die Ordner `modelcamp-media` und `modelcamp-backup` anlegen und `source` in der Datei anpassen.
|
||||||
|
3. Das SMB-Secret anlegen: `kubectl -n artista create secret generic artista-modelcamp-smb --from-literal=username='…' --from-literal=password='…'`. Empfohlen ist ein eigener NAS-Benutzer, der nur diese Ordner sieht.
|
||||||
|
- Die PVCs sind statisch an die PVs gebunden. Die Rechte setzen die `mountOptions`: `uid=1001` für die App, `uid=70` für den Backup-Job, der mit `0700` bzw. `0600` geschützt ist, weil die Dumps personenbezogene Daten enthalten. Auf SMB wirkt `fsGroup` nicht.
|
||||||
|
- Ohne SMB: `smb-volumes.yaml` und die beiden PVC-Patches im Overlay entfernen, dann greift die Default-StorageClass. Das Medienvolume braucht dann ReadWriteMany, sonst `replicas: 1`.
|
||||||
3. **Secret anlegen:** Befehl steht in `k8s/secret.example.yaml`, besser über Sealed Secrets oder den External Secrets Operator.
|
3. **Secret anlegen:** Befehl steht in `k8s/secret.example.yaml`, besser über Sealed Secrets oder den External Secrets Operator.
|
||||||
4. **Anwenden:** `kubectl apply -k k8s/overlays/production`
|
4. **Anwenden:** `kubectl apply -k k8s/overlays/production`
|
||||||
5. **Migration** (siehe Abschnitt 3), danach das erste Admin-Konto:
|
5. **Migration** (siehe Abschnitt 3), danach das erste Admin-Konto:
|
||||||
@@ -108,10 +112,6 @@ Die Software trifft keine Storno-Entscheidung, sie setzt sie nur nachvollziehbar
|
|||||||
|
|
||||||
## 9. Medien
|
## 9. Medien
|
||||||
|
|
||||||
Dateien (jpg, png, webp, avif, mp4, webm) in das Volume `artista-modelcamp-media` kopieren:
|
Dateien (jpg, png, webp, avif, mp4, webm) direkt in den SMB-Ordner `modelcamp-media` legen, z. B. über den Windows-Explorer (`\\nas…\artista\modelcamp-media`). Die App sieht sie sofort unter `/media/<dateiname>`. Im Pod ist das Volume schreibgeschützt eingehängt.
|
||||||
|
|
||||||
```bash
|
|
||||||
kubectl -n artista cp villa-aussen.jpg <app-pod>:/app/media/villa-aussen.jpg # Volume ist im App-Pod read-only → einen Hilfs-Pod mit Schreibzugriff nutzen
|
|
||||||
```
|
|
||||||
|
|
||||||
Danach in `src/content/site.ts` eintragen. Hotlinking fremder Bilder, etwa von Booking.com, ist nicht vorgesehen: Nur Bilder mit geklärter Nutzungsberechtigung ablegen.
|
Danach in `src/content/site.ts` eintragen. Hotlinking fremder Bilder, etwa von Booking.com, ist nicht vorgesehen: Nur Bilder mit geklärter Nutzungsberechtigung ablegen.
|
||||||
@@ -7,6 +7,9 @@ namespace: artista
|
|||||||
resources:
|
resources:
|
||||||
- ../../base
|
- ../../base
|
||||||
- ingress.yaml
|
- ingress.yaml
|
||||||
|
# Medien und Sicherungen auf SMB (PostgreSQL bewusst nicht, siehe Datei).
|
||||||
|
# Ohne SMB: diese Zeile und die beiden PVC-Patches unten entfernen.
|
||||||
|
- smb-volumes.yaml
|
||||||
|
|
||||||
images:
|
images:
|
||||||
# Gebaut von .gitea/workflows/docker-build.yml: Git-Tag "v0.1.0" pushen
|
# Gebaut von .gitea/workflows/docker-build.yml: Git-Tag "v0.1.0" pushen
|
||||||
@@ -20,6 +23,26 @@ images:
|
|||||||
newTag: "0.1.0"
|
newTag: "0.1.0"
|
||||||
|
|
||||||
patches:
|
patches:
|
||||||
|
# PVCs fest an die SMB-PersistentVolumes binden (statisch, ohne StorageClass).
|
||||||
|
- target: { kind: PersistentVolumeClaim, name: artista-modelcamp-media }
|
||||||
|
patch: |-
|
||||||
|
- op: add
|
||||||
|
path: /spec/storageClassName
|
||||||
|
value: ""
|
||||||
|
- op: add
|
||||||
|
path: /spec/volumeName
|
||||||
|
value: artista-modelcamp-media-smb
|
||||||
|
- target: { kind: PersistentVolumeClaim, name: artista-modelcamp-db-backup }
|
||||||
|
patch: |-
|
||||||
|
- op: add
|
||||||
|
path: /spec/storageClassName
|
||||||
|
value: ""
|
||||||
|
- op: add
|
||||||
|
path: /spec/volumeName
|
||||||
|
value: artista-modelcamp-db-backup-smb
|
||||||
|
- op: replace
|
||||||
|
path: /spec/accessModes
|
||||||
|
value: ["ReadWriteMany"]
|
||||||
- target: { kind: ConfigMap, name: artista-modelcamp-config }
|
- target: { kind: ConfigMap, name: artista-modelcamp-config }
|
||||||
patch: |-
|
patch: |-
|
||||||
- op: replace
|
- op: replace
|
||||||
|
|||||||
@@ -0,0 +1,79 @@
|
|||||||
|
# PersistentVolumes auf einer SMB-Freigabe (csi-driver-smb, smb.csi.k8s.io).
|
||||||
|
#
|
||||||
|
# VORAUSSETZUNG: csi-driver-smb im Cluster installiert, z. B.:
|
||||||
|
# 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
|
||||||
|
# und das Zugangs-Secret "artista-modelcamp-smb" (k8s/secret.example.yaml).
|
||||||
|
#
|
||||||
|
# ANZUPASSEN: "source" (//<nas>/<freigabe>/<ordner>) je Volume. Die Ordner
|
||||||
|
# muessen auf der Freigabe bereits existieren.
|
||||||
|
#
|
||||||
|
# BEWUSST NICHT AUF SMB: das PostgreSQL-Datenverzeichnis. SMB bildet
|
||||||
|
# POSIX-Sperren, fsync-Garantien und Dateirechte nicht so ab, wie PostgreSQL
|
||||||
|
# sie fuer Absturzsicherheit braucht (Briefing §13). Die Datenbank bleibt auf
|
||||||
|
# Blockspeicher und wird taeglich per pg_dump auf das Backup-Volume unten
|
||||||
|
# gesichert — damit liegen die Geschaeftsdaten trotzdem auf dem NAS.
|
||||||
|
#
|
||||||
|
# Rechte: fsGroup wirkt auf SMB nicht. Besitz und Rechte setzen deshalb
|
||||||
|
# uid/gid/dir_mode/file_mode in den mountOptions (Muster aus Wabenhain).
|
||||||
|
# Aenderungen an mountOptions greifen erst beim naechsten Einhaengen.
|
||||||
|
# reclaimPolicy Retain: Loeschen von PVC/PV laesst die Dateien auf dem NAS.
|
||||||
|
|
||||||
|
# --- Medien (Bilder/Videos) ----------------------------------------------------
|
||||||
|
# Die App liest nur (readOnly-Mount). Neue Bilder legst du direkt ueber die
|
||||||
|
# SMB-Freigabe ab, z. B. vom Windows-Explorer aus.
|
||||||
|
apiVersion: v1
|
||||||
|
kind: PersistentVolume
|
||||||
|
metadata:
|
||||||
|
name: artista-modelcamp-media-smb
|
||||||
|
spec:
|
||||||
|
capacity:
|
||||||
|
storage: 5Gi
|
||||||
|
accessModes: ["ReadWriteMany"]
|
||||||
|
persistentVolumeReclaimPolicy: Retain
|
||||||
|
storageClassName: ""
|
||||||
|
mountOptions:
|
||||||
|
- vers=3.0
|
||||||
|
- uid=1001 # Containerbenutzer "nextjs" (Dockerfile)
|
||||||
|
- gid=1001
|
||||||
|
- dir_mode=0770
|
||||||
|
- file_mode=0660
|
||||||
|
- mfsymlinks
|
||||||
|
- nobrl
|
||||||
|
csi:
|
||||||
|
driver: smb.csi.k8s.io
|
||||||
|
# Muss im Cluster eindeutig sein.
|
||||||
|
volumeHandle: artista-modelcamp-media-smb
|
||||||
|
volumeAttributes:
|
||||||
|
source: //nas.example.lan/artista/modelcamp-media
|
||||||
|
nodeStageSecretRef:
|
||||||
|
name: artista-modelcamp-smb
|
||||||
|
namespace: artista
|
||||||
|
---
|
||||||
|
# --- Datenbank-Sicherungen ------------------------------------------------------
|
||||||
|
apiVersion: v1
|
||||||
|
kind: PersistentVolume
|
||||||
|
metadata:
|
||||||
|
name: artista-modelcamp-db-backup-smb
|
||||||
|
spec:
|
||||||
|
capacity:
|
||||||
|
storage: 10Gi
|
||||||
|
accessModes: ["ReadWriteMany"]
|
||||||
|
persistentVolumeReclaimPolicy: Retain
|
||||||
|
storageClassName: ""
|
||||||
|
mountOptions:
|
||||||
|
- vers=3.0
|
||||||
|
- uid=70 # Benutzer "postgres" im pg_dump-Job (postgres:18-alpine)
|
||||||
|
- gid=70
|
||||||
|
- dir_mode=0700 # Sicherungen enthalten personenbezogene Daten
|
||||||
|
- file_mode=0600
|
||||||
|
- mfsymlinks
|
||||||
|
- nobrl
|
||||||
|
csi:
|
||||||
|
driver: smb.csi.k8s.io
|
||||||
|
volumeHandle: artista-modelcamp-db-backup-smb
|
||||||
|
volumeAttributes:
|
||||||
|
source: //nas.example.lan/artista/modelcamp-backup
|
||||||
|
nodeStageSecretRef:
|
||||||
|
name: artista-modelcamp-smb
|
||||||
|
namespace: artista
|
||||||
@@ -26,3 +26,20 @@ stringData:
|
|||||||
SMTP_HOST: "<smtp.example.org>"
|
SMTP_HOST: "<smtp.example.org>"
|
||||||
SMTP_USER: "<benutzer>"
|
SMTP_USER: "<benutzer>"
|
||||||
SMTP_PASSWORD: "<passwort>"
|
SMTP_PASSWORD: "<passwort>"
|
||||||
|
---
|
||||||
|
# Zugang zur SMB-Freigabe fuer die PersistentVolumes
|
||||||
|
# (k8s/overlays/production/smb-volumes.yaml). Eigener, auf die Artista-
|
||||||
|
# Ordner beschraenkter NAS-Benutzer empfohlen.
|
||||||
|
# kubectl -n artista create secret generic artista-modelcamp-smb \
|
||||||
|
# --from-literal=username='…' --from-literal=password='…'
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: artista-modelcamp-smb
|
||||||
|
namespace: artista
|
||||||
|
type: Opaque
|
||||||
|
stringData:
|
||||||
|
username: "<nas-benutzer>"
|
||||||
|
password: "<nas-passwort>"
|
||||||
|
# Optional bei Domaenenkonten:
|
||||||
|
# domain: "<domaene>"
|
||||||
Reference in new issue
Block a user