cluster

Infrastructure files for Nordgedanken and Midnightthoughts.
git clone git://archive.git.mtrnord.blog/MTRNord/cluster.git
Log | Files | Refs | README

commit 095adca163786ada371a991a41685631e250152c
parent 6a0a27e551e2c4ce8db44a552db8bac22a42debf
Author: MTRNord <MTRNord@users.noreply.github.com>
Date:   Wed, 18 Feb 2026 21:28:46 +0100

further fixes and revert cgit and freshrss changes

Signed-off-by: MTRNord <MTRNord@users.noreply.github.com>

Diffstat:
Mapps/talos_cluster/blog/wordpress.yaml | 4++++
Mapps/talos_cluster/bookwyrm/deployment.yaml | 100+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mapps/talos_cluster/bookwyrm/keydb.yaml | 2+-
Mapps/talos_cluster/cgit/deployment.yaml | 21+--------------------
Mapps/talos_cluster/draupnir-synapse/keydb.yaml | 2+-
Mapps/talos_cluster/draupnir4all/deployment.yaml | 4++--
Mapps/talos_cluster/freshrss/deployment.yaml | 36++----------------------------------
Mapps/talos_cluster/peertube/deployment.yaml | 59+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
8 files changed, 170 insertions(+), 58 deletions(-)

diff --git a/apps/talos_cluster/blog/wordpress.yaml b/apps/talos_cluster/blog/wordpress.yaml @@ -126,6 +126,8 @@ spec: #- name: wordpress-persistent-storage # mountPath: /var/www/html/wordpress/wp-content/themes # subPath: themes + - name: var-run + mountPath: /var/run readinessProbe: httpGet: path: /wp-login.php @@ -150,6 +152,8 @@ spec: - name: wordpress-persistent-storage persistentVolumeClaim: claimName: wordpress-pvc + - name: var-run + emptyDir: {} --- kind: Service apiVersion: v1 diff --git a/apps/talos_cluster/bookwyrm/deployment.yaml b/apps/talos_cluster/bookwyrm/deployment.yaml @@ -44,9 +44,24 @@ spec: - name: nginx-config configMap: name: nginx + - name: nginx-tmp + emptyDir: {} + - name: nginx-var-cache + emptyDir: {} + - name: nginx-var-run + emptyDir: {} initContainers: - name: bookwyrm-update image: ghcr.io/mtrnord/bookwyrm:v0.8.2 + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + add: + - CHOWN + - FOWNER + - DAC_OVERRIDE imagePullPolicy: Always command: ["bash"] args: @@ -172,8 +187,31 @@ spec: - name: DATA_UPLOAD_MAX_MEMORY_MiB value: "100" containers: + # NOTE: nginx:latest master runs as root for chown; same pattern as connectivity-tester. + # Switch to nginxinc/nginx-unprivileged when updating this image and replace securityContext + # with full non-root settings (runAsUser: 101, runAsNonRoot: true, drop ALL caps). - name: nginx image: nginx:latest + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + capabilities: + drop: + - ALL + add: + - CHOWN + - FOWNER + - SETUID + - SETGID + seccompProfile: + type: RuntimeDefault + resources: + limits: + cpu: "200m" + memory: "128Mi" + requests: + cpu: "50m" + memory: "64Mi" volumeMounts: - name: bookwyrm-data mountPath: /app/static @@ -203,6 +241,12 @@ spec: mountPath: /etc/nginx/conf.d/server_name subPath: server_name readOnly: true + - name: nginx-tmp + mountPath: /tmp + - name: nginx-var-cache + mountPath: /var/cache/nginx + - name: nginx-var-run + mountPath: /var/run env: - name: POD_IP valueFrom: @@ -322,7 +366,21 @@ spec: command: ["gunicorn"] args: - "bookwyrm.wsgi:application" + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: false + runAsNonRoot: true + runAsUser: 1000 + runAsGroup: 1000 + capabilities: + drop: + - ALL + seccompProfile: + type: RuntimeDefault resources: + limits: + cpu: "500m" + memory: "1Gi" requests: cpu: 200m memory: 500Mi @@ -464,7 +522,21 @@ spec: - "info" - "-Q" - "high_priority,medium_priority,low_priority,streams,images,suggested_users,email,connectors,lists,inbox,imports,import_triggered,broadcast,misc" + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: false + runAsNonRoot: true + runAsUser: 1000 + runAsGroup: 1000 + capabilities: + drop: + - ALL + seccompProfile: + type: RuntimeDefault resources: + limits: + cpu: "500m" + memory: "500Mi" requests: cpu: 200m memory: 200Mi @@ -596,7 +668,21 @@ spec: - "INFO" - "--scheduler" - "django_celery_beat.schedulers:DatabaseScheduler" + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: false + runAsNonRoot: true + runAsUser: 1000 + runAsGroup: 1000 + capabilities: + drop: + - ALL + seccompProfile: + type: RuntimeDefault resources: + limits: + cpu: "200m" + memory: "500Mi" requests: cpu: 200m memory: 200Mi @@ -725,7 +811,21 @@ spec: - "celerywyrm" - "flower" - "--url_prefix=flower" + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: false + runAsNonRoot: true + runAsUser: 1000 + runAsGroup: 1000 + capabilities: + drop: + - ALL + seccompProfile: + type: RuntimeDefault resources: + limits: + cpu: "200m" + memory: "500Mi" requests: cpu: 200m memory: 200Mi diff --git a/apps/talos_cluster/bookwyrm/keydb.yaml b/apps/talos_cluster/bookwyrm/keydb.yaml @@ -11,10 +11,10 @@ spec: metadata: labels: app: bookwyrm-keydb + spec: automountServiceAccountToken: false securityContext: fsGroup: 999 - spec: containers: - name: bookwyrm-keydb image: eqalpha/keydb:latest diff --git a/apps/talos_cluster/cgit/deployment.yaml b/apps/talos_cluster/cgit/deployment.yaml @@ -33,9 +33,6 @@ spec: app: cgit app.kubernetes.io/name: cgit spec: - automountServiceAccountToken: false - securityContext: - fsGroup: 1000 containers: - name: anubis image: ghcr.io/techarohq/anubis:latest @@ -76,7 +73,6 @@ spec: runAsGroup: 1000 runAsNonRoot: true allowPrivilegeEscalation: false - readOnlyRootFilesystem: true capabilities: drop: - ALL @@ -85,23 +81,8 @@ spec: - name: cgit image: ghcr.io/mtrnord/cgit-docker:main imagePullPolicy: Always - securityContext: - allowPrivilegeEscalation: false - readOnlyRootFilesystem: true - runAsNonRoot: true - runAsUser: 1000 - runAsGroup: 1000 - capabilities: - drop: - - ALL - add: - - FOWNER # entrypoint does chmod /tmp (root-owned dir) - seccompProfile: - type: RuntimeDefault resources: - limits: - cpu: "500m" - memory: "512Mi" + limits: {} requests: memory: "344Mi" cpu: "252m" diff --git a/apps/talos_cluster/draupnir-synapse/keydb.yaml b/apps/talos_cluster/draupnir-synapse/keydb.yaml @@ -11,10 +11,10 @@ spec: metadata: labels: app: draupnir-synapse-keydb + spec: automountServiceAccountToken: false securityContext: fsGroup: 999 - spec: containers: - name: draupnir-synapse-keydb image: eqalpha/keydb:latest diff --git a/apps/talos_cluster/draupnir4all/deployment.yaml b/apps/talos_cluster/draupnir4all/deployment.yaml @@ -95,10 +95,10 @@ spec: resources: limits: cpu: "1000m" - memory: "512Mi" + memory: "1024Mi" requests: memory: "344Mi" - cpu: "252m" + cpu: "512m" ports: - containerPort: 9001 name: api diff --git a/apps/talos_cluster/freshrss/deployment.yaml b/apps/talos_cluster/freshrss/deployment.yaml @@ -17,31 +17,9 @@ spec: labels: app: freshrss spec: - automountServiceAccountToken: false - securityContext: - fsGroup: 33 containers: - name: freshrss - image: freshrss/freshrss:1.28.1 - securityContext: - allowPrivilegeEscalation: false - readOnlyRootFilesystem: false - # NOTE: FreshRSS entrypoint starts as root to write /etc/localtime, /etc/timezone, - # /etc/php config, set up cron, then seteuid to www-data (uid 33). - # Cannot set runAsNonRoot/runAsUser here — entrypoint breaks without root init. - # Capabilities needed for entrypoint setup: CHOWN, DAC_OVERRIDE (write /etc/ files), - # SETUID/SETGID (seteuid to www-data), FOWNER (chmod operations). - capabilities: - drop: - - ALL - add: - - CHOWN - - DAC_OVERRIDE - - FOWNER - - SETUID - - SETGID - seccompProfile: - type: RuntimeDefault + image: freshrss/freshrss:latest env: - name: TZ value: "Europe/Berlin" @@ -52,9 +30,7 @@ spec: - name: LISTEN value: "0.0.0.0:8080" resources: - limits: - cpu: "500m" - memory: "512Mi" + limits: {} requests: memory: "344Mi" cpu: "252m" @@ -67,10 +43,6 @@ spec: mountPath: "/var/www/FreshRSS/data" - mountPath: /tmp name: tmp - - mountPath: /var/run - name: var-run - - mountPath: /var/log - name: var-log livenessProbe: httpGet: path: / @@ -89,10 +61,6 @@ spec: - name: tmp emptyDir: sizeLimit: 2048Mi - - name: var-run - emptyDir: {} - - name: var-log - emptyDir: {} - name: data persistentVolumeClaim: claimName: freshrss-data diff --git a/apps/talos_cluster/peertube/deployment.yaml b/apps/talos_cluster/peertube/deployment.yaml @@ -14,25 +14,44 @@ spec: labels: app: peertube-redis spec: + automountServiceAccountToken: false + securityContext: + fsGroup: 999 containers: - name: redis image: redis:8-alpine + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + runAsNonRoot: true + runAsUser: 999 + runAsGroup: 999 + capabilities: + drop: + - ALL + seccompProfile: + type: RuntimeDefault ports: - containerPort: 6379 name: redis volumeMounts: - name: redis-data mountPath: /data + - name: tmp + mountPath: /tmp resources: requests: memory: "128Mi" cpu: "100m" limits: memory: "256Mi" + cpu: "200m" volumes: - name: redis-data emptyDir: sizeLimit: 1Gi + - name: tmp + emptyDir: {} --- apiVersion: v1 kind: Service @@ -65,8 +84,14 @@ spec: labels: app: peertube spec: + automountServiceAccountToken: false + securityContext: + fsGroup: 999 containers: # Nginx sidecar for S3 caching and static content + # NOTE: nginx:1.27-alpine master runs as root; same pattern as connectivity-tester UI. + # When/if switched to nginx-unprivileged, remove the added capabilities and add + # runAsNonRoot: true, runAsUser: 101, runAsGroup: 101. - name: nginx image: nginx:1.27-alpine ports: @@ -91,12 +116,30 @@ spec: readOnly: true - name: nginx-cache mountPath: /var/cache/nginx + - name: nginx-tmp + mountPath: /tmp + - name: nginx-run + mountPath: /var/run + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + capabilities: + drop: + - ALL + add: + - CHOWN + - FOWNER + - SETUID + - SETGID + seccompProfile: + type: RuntimeDefault resources: requests: memory: "128Mi" cpu: "100m" limits: memory: "512Mi" + cpu: "200m" livenessProbe: httpGet: path: /api/v1/ping @@ -259,6 +302,17 @@ spec: value: "public-read" - name: PEERTUBE_OBJECT_STORAGE_UPLOAD_ACL_PRIVATE value: "private" + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: false + runAsNonRoot: true + runAsUser: 999 + runAsGroup: 999 + capabilities: + drop: + - ALL + seccompProfile: + type: RuntimeDefault volumeMounts: - name: data mountPath: /data @@ -270,6 +324,7 @@ spec: cpu: "500m" limits: memory: "4Gi" + cpu: "2000m" startupProbe: httpGet: path: /api/v1/ping @@ -291,6 +346,10 @@ spec: - name: nginx-cache emptyDir: sizeLimit: 15Gi + - name: nginx-tmp + emptyDir: {} + - name: nginx-run + emptyDir: {} --- apiVersion: v1 kind: Service