cluster

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

commit 4b6ef240d4e14a223fe671f0f2d4656b07a10927
parent e44ce531d297775c1f6733ea5168d8634dfb3856
Author: MTRNord <MTRNord@users.noreply.github.com>
Date:   Wed,  1 Oct 2025 19:27:46 +0200

Meow

Diffstat:
Mapps/talos_cluster/mailserver/mailman-nginx.conf | 86++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
Mapps/talos_cluster/mailserver/mailman.yaml | 419++++++++++++++++++++++++++++++++++++++++---------------------------------------
2 files changed, 293 insertions(+), 212 deletions(-)

diff --git a/apps/talos_cluster/mailserver/mailman-nginx.conf b/apps/talos_cluster/mailserver/mailman-nginx.conf @@ -1,32 +1,112 @@ worker_processes auto; pid /tmp/nginx.pid; +error_log /dev/stderr warn; + events { - worker_connections 10240; + worker_connections 1024; # Reduced for container environment + use epoll; # Efficient event method for Linux + multi_accept on; # Accept multiple connections at once } + http { + # Temp paths for unprivileged mode client_body_temp_path /tmp/nginx/client_body; fastcgi_temp_path /tmp/nginx/fastcgi; uwsgi_temp_path /tmp/nginx/uwsgi; scgi_temp_path /tmp/nginx/scgi; + proxy_temp_path /tmp/nginx/proxy; + + # Basic optimizations + sendfile on; + tcp_nopush on; + tcp_nodelay on; + keepalive_timeout 65; + keepalive_requests 100; + + # Buffer optimizations + client_body_buffer_size 128k; + client_max_body_size 20m; # For email attachments + client_header_buffer_size 1k; + large_client_header_buffers 4 4k; + + # Gzip compression + gzip on; + gzip_vary on; + gzip_min_length 1000; + gzip_comp_level 6; + gzip_types + text/plain + text/css + text/xml + text/javascript + application/json + application/javascript + application/xml+rss + application/atom+xml + image/svg+xml; + + # Logging (structured for container environments) + log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for" ' + 'rt=$request_time uct="$upstream_connect_time" ' + 'uht="$upstream_header_time" urt="$upstream_response_time"'; + access_log /dev/stdout main; + server_names_hash_bucket_size 64; include /etc/nginx/mime.types; default_type application/octet-stream; server { listen 9090; server_name _; + + # Security headers (behind reverse proxy) + add_header X-Content-Type-Options nosniff; + add_header X-Frame-Options DENY; + add_header X-XSS-Protection "1; mode=block"; + + # Health check endpoint for probes + location /health { + access_log off; + return 200 "healthy\n"; + add_header Content-Type text/plain; + } location /static { alias /opt/mailman-web-data/static; autoindex off; + + # Static file caching + expires 1M; + add_header Cache-Control "public, immutable"; + add_header Vary Accept-Encoding; + + # Efficient static file serving + location ~* \.(css|js|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ { + expires 1y; + add_header Cache-Control "public, immutable"; + } } location / { + # uWSGI connection with optimized settings uwsgi_pass 127.0.0.1:8080; #proxy_pass http://127.0.0.1:8000; include uwsgi_params; + + # Timeout settings uwsgi_read_timeout 300; - #proxy_set_header Host $host; - #proxy_set_header X-Forwarded-For $remote_addr; + uwsgi_connect_timeout 60; + + # Buffer settings for better performance + uwsgi_buffer_size 64k; + uwsgi_buffers 4 64k; + uwsgi_busy_buffers_size 128k; + + # Pass real client info (since behind reverse proxy) + uwsgi_param HTTP_X_FORWARDED_PROTO $scheme; + uwsgi_param HTTP_X_FORWARDED_FOR $proxy_add_x_forwarded_for; + uwsgi_param HTTP_X_REAL_IP $remote_addr; } } } diff --git a/apps/talos_cluster/mailserver/mailman.yaml b/apps/talos_cluster/mailserver/mailman.yaml @@ -7,10 +7,6 @@ metadata: spec: serviceName: mailman replicas: 1 - updateStrategy: - type: RollingUpdate - rollingUpdate: - maxUnavailable: 1 selector: matchLabels: app: mailman @@ -22,259 +18,264 @@ spec: hostAliases: - ip: 0.0.0.0 hostnames: - - mailman.mailserver.svc.cluster.local + - mailman.mailserver.svc.cluster.local - ip: 127.0.0.1 hostnames: - - mailman-web + - mailman-web containers: - name: core image: ghcr.io/mtrnord/mailman-core:rolling imagePullPolicy: Always ports: - - name: api - containerPort: 8001 - - name: lmtp - containerPort: 8024 + - name: api + containerPort: 8001 + - name: lmtp + containerPort: 8024 env: - - name: DATABASE_URL - valueFrom: - secretKeyRef: - name: mailmancore - key: url - - name: DATABASE_TYPE - value: postgres - - name: DATABASE_CLASS - value: mailman.database.postgresql.PostgreSQLDatabase - - name: HYPERKITTY_API_KEY - valueFrom: - secretKeyRef: - name: mailman-passwords - key: apikey - - name: MAILMAN_REST_USER - value: restadm - - name: MAILMAN_REST_PASSWORD - valueFrom: - secretKeyRef: - name: mailman-passwords - key: restpassword - - name: SMTP_HOST - value: mail.midnightthoughts.space - - name: SMTP_PORT - value: "465" - - name: SMTP_USE_SSL - value: "true" - - name: SMTP_SECURE_MODE - value: "smtps" - - name: SMTP_HOST_USER - valueFrom: - secretKeyRef: - name: mailman-passwords - key: smtp_user - - name: SMTP_HOST_PASSWORD - valueFrom: - secretKeyRef: - name: mailman-passwords - key: smtp_password - - name: MTA - value: postfix - - name: MM_HOSTNAME - value: mailman.mailserver.svc.cluster.local - - name: HYPERKITTY_URL - value: http://localhost:8000/hyperkitty + - name: DATABASE_URL + valueFrom: + secretKeyRef: + name: mailmancore + key: url + - name: DATABASE_TYPE + value: postgres + - name: DATABASE_CLASS + value: mailman.database.postgresql.PostgreSQLDatabase + - name: HYPERKITTY_API_KEY + valueFrom: + secretKeyRef: + name: mailman-passwords + key: apikey + - name: MAILMAN_REST_USER + value: restadm + - name: MAILMAN_REST_PASSWORD + valueFrom: + secretKeyRef: + name: mailman-passwords + key: restpassword + - name: SMTP_HOST + value: mail.midnightthoughts.space + - name: SMTP_PORT + value: "465" + - name: SMTP_USE_SSL + value: "true" + - name: SMTP_SECURE_MODE + value: "smtps" + - name: SMTP_HOST_USER + valueFrom: + secretKeyRef: + name: mailman-passwords + key: smtp_user + - name: SMTP_HOST_PASSWORD + valueFrom: + secretKeyRef: + name: mailman-passwords + key: smtp_password + - name: MTA + value: postfix + - name: MM_HOSTNAME + value: mailman.mailserver.svc.cluster.local + - name: HYPERKITTY_URL + value: http://localhost:8000/hyperkitty volumeMounts: - - name: mailman-opt - mountPath: /opt/mailman - - name: mailman-extra - mountPath: /opt/mailman/mailman-extra.cfg - subPath: mailman-extra.cfg - - name: mailman-extra - mountPath: /usr/bin/chown - subPath: chown + - name: mailman-opt + mountPath: /opt/mailman + - name: mailman-extra + mountPath: /opt/mailman/mailman-extra.cfg + subPath: mailman-extra.cfg + - name: mailman-extra + mountPath: /usr/bin/chown + subPath: chown - name: web image: ghcr.io/mtrnord/mailman-web:rolling imagePullPolicy: Always ports: - - name: http - containerPort: 8000 - - name: uwsgi - containerPort: 8080 + - name: http + containerPort: 8000 + - name: uwsgi + containerPort: 8080 #command: # - tail #args: # - -f # - /dev/null env: - - name: DATABASE_URL - valueFrom: - secretKeyRef: - name: mailmanweb - key: url - - name: DATABASE_TYPE - value: postgres - - name: DATABASE_CLASS - value: mailman.database.postgresql.PostgreSQLDatabase - - name: HYPERKITTY_API_KEY - valueFrom: - secretKeyRef: - name: mailman-passwords - key: apikey - - name: MAILMAN_REST_USER - value: restadm - - name: MAILMAN_REST_PASSWORD - valueFrom: - secretKeyRef: - name: mailman-passwords - key: restpassword - - name: SECRET_KEY - valueFrom: - secretKeyRef: - name: mailman-passwords - key: websecretkey - - name: POSTORIUS_TEMPLATE_BASE_URL - value: http://localhost:8000/ - # serving static files by uwsgi - - name: UWSGI_STATIC_MAP - value: /static=/opt/mailman-web-data/static - - name: MAILMAN_ADMIN_USER - value: admin - - name: MAILMAN_ADMIN_EMAIL - value: mtrnord@nordgedanken.dev - - name: MAILMAN_HOST_IP - value: 127.0.0.1 - - name: MAILMAN_HOSTNAME - value: localhost - - name: SERVE_FROM_DOMAIN - value: lists.midnightthoughts.space - - name: MAILMAN_REST_URL # MAILMAN_REST_API_URL is set from this variable in settings. - value: http://127.0.0.1:8001 - - name: MAILMAN_REST_API_USER - value: restadm - - name: MAILMAN_REST_API_PASS - valueFrom: - secretKeyRef: - name: mailman-passwords - key: restpassword - - name: SMTP_HOST - value: mail.midnightthoughts.space - - name: SMTP_PORT - value: "465" - - name: SMTP_USE_SSL - value: "true" - - name: SMTP_HOST_USER - valueFrom: - secretKeyRef: - name: mailman-passwords - key: smtp_user - - name: SMTP_HOST_PASSWORD - valueFrom: - secretKeyRef: - name: mailman-passwords - key: smtp_password + - name: DATABASE_URL + valueFrom: + secretKeyRef: + name: mailmanweb + key: url + - name: DATABASE_TYPE + value: postgres + - name: DATABASE_CLASS + value: mailman.database.postgresql.PostgreSQLDatabase + - name: HYPERKITTY_API_KEY + valueFrom: + secretKeyRef: + name: mailman-passwords + key: apikey + - name: MAILMAN_REST_USER + value: restadm + - name: MAILMAN_REST_PASSWORD + valueFrom: + secretKeyRef: + name: mailman-passwords + key: restpassword + - name: SECRET_KEY + valueFrom: + secretKeyRef: + name: mailman-passwords + key: websecretkey + - name: POSTORIUS_TEMPLATE_BASE_URL + value: http://localhost:8000/ + # serving static files by uwsgi + - name: UWSGI_STATIC_MAP + value: /static=/opt/mailman-web-data/static + - name: MAILMAN_ADMIN_USER + value: admin + - name: MAILMAN_ADMIN_EMAIL + value: mtrnord@nordgedanken.dev + - name: MAILMAN_HOST_IP + value: 127.0.0.1 + - name: MAILMAN_HOSTNAME + value: localhost + - name: SERVE_FROM_DOMAIN + value: lists.midnightthoughts.space + - name: MAILMAN_REST_URL # MAILMAN_REST_API_URL is set from this variable in settings. + value: http://127.0.0.1:8001 + - name: MAILMAN_REST_API_USER + value: restadm + - name: MAILMAN_REST_API_PASS + valueFrom: + secretKeyRef: + name: mailman-passwords + key: restpassword + - name: SMTP_HOST + value: mail.midnightthoughts.space + - name: SMTP_PORT + value: "465" + - name: SMTP_USE_SSL + value: "true" + - name: SMTP_HOST_USER + valueFrom: + secretKeyRef: + name: mailman-passwords + key: smtp_user + - name: SMTP_HOST_PASSWORD + valueFrom: + secretKeyRef: + name: mailman-passwords + key: smtp_password # otherwise django cannot find the mysql driver. #- name: DYLD_LIBRARY_PATH # value: /usr/local/mysql/lib/ volumeMounts: - - name: mailman-web - mountPath: /opt/mailman-web-data - - name: mailman-extra - mountPath: /opt/mailman-web-data/settings_local.py - subPath: settings_local.py - - name: mailman-extra - mountPath: /usr/bin/chown - subPath: chown + - name: mailman-web + mountPath: /opt/mailman-web-data + - name: mailman-extra + mountPath: /opt/mailman-web-data/settings_local.py + subPath: settings_local.py + - name: mailman-extra + mountPath: /usr/bin/chown + subPath: chown - name: nginx image: ghcr.io/nginx/nginx-unprivileged:stable-alpine imagePullPolicy: IfNotPresent ports: - - name: http - containerPort: 9090 + - name: http + containerPort: 9090 startupProbe: - httpGet: - path: / - port: 8000 - host: 127.0.0.1 - initialDelaySeconds: 30 - periodSeconds: 10 - timeoutSeconds: 5 - failureThreshold: 24 + httpGet: + path: / + port: 8000 + host: 127.0.0.1 + initialDelaySeconds: 30 + periodSeconds: 10 + timeoutSeconds: 5 + failureThreshold: 24 livenessProbe: - httpGet: - path: / - port: 8000 - host: 127.0.0.1 - periodSeconds: 30 - timeoutSeconds: 5 - failureThreshold: 3 + httpGet: + path: / + port: 8000 + host: 127.0.0.1 + periodSeconds: 30 + timeoutSeconds: 5 + failureThreshold: 3 readinessProbe: - httpGet: - path: / - port: 9090 - periodSeconds: 10 - timeoutSeconds: 3 - failureThreshold: 3 + httpGet: + path: / + port: 9090 + periodSeconds: 10 + timeoutSeconds: 3 + failureThreshold: 3 volumeMounts: - - name: mailman-web - mountPath: /opt/mailman-web-data - readOnly: true - - name: nginx-config - mountPath: /etc/nginx/nginx.conf - subPath: nginx.conf - readOnly: true - - name: tmp - mountPath: /tmp - readOnly: false - - name: tmp-client-body - mountPath: /tmp/nginx/client_body - readOnly: false - - name: tmp-cgi - mountPath: /tmp/nginx/fastcgi - readOnly: false - - name: tmp-cgi - mountPath: /tmp/nginx/uwsgi - readOnly: false - - name: tmp-cgi - mountPath: /tmp/nginx/scgi - readOnly: false + - name: mailman-web + mountPath: /opt/mailman-web-data + readOnly: true + - name: nginx-config + mountPath: /etc/nginx/nginx.conf + subPath: nginx.conf + readOnly: true + - name: tmp + mountPath: /tmp + readOnly: false + - name: tmp-client-body + mountPath: /tmp/nginx/client_body + readOnly: false + - name: tmp-cgi + mountPath: /tmp/nginx/fastcgi + readOnly: false + - name: tmp-cgi + mountPath: /tmp/nginx/uwsgi + readOnly: false + - name: tmp-cgi + mountPath: /tmp/nginx/scgi + readOnly: false + - name: tmp-proxy + mountPath: /tmp/nginx/proxy + readOnly: false volumes: - name: mailman-extra secret: - secretName: mailman-extra - defaultMode: 0555 + secretName: mailman-extra + defaultMode: 0555 - name: nginx-config configMap: - name: mailman-nginx + name: mailman-nginx - name: tmp emptyDir: {} - name: tmp-client-body emptyDir: {} - name: tmp-cgi emptyDir: {} + - name: tmp-proxy + emptyDir: {} volumeClaimTemplates: - apiVersion: v1 kind: PersistentVolumeClaim metadata: - name: mailman-opt - namespace: mailserver + name: mailman-opt + namespace: mailserver spec: - storageClassName: longhorn - accessModes: - - ReadWriteMany - resources: - requests: - storage: 10Gi + storageClassName: longhorn + accessModes: + - ReadWriteMany + resources: + requests: + storage: 10Gi - apiVersion: v1 kind: PersistentVolumeClaim metadata: - name: mailman-web - namespace: mailserver + name: mailman-web + namespace: mailserver spec: - storageClassName: longhorn - accessModes: - - ReadWriteMany - resources: - requests: - storage: 10Gi + storageClassName: longhorn + accessModes: + - ReadWriteMany + resources: + requests: + storage: 10Gi --- apiVersion: v1 kind: Service @@ -310,8 +311,8 @@ spec: - lists.midnightthoughts.space rules: - backendRefs: - - name: mailman - port: 9090 + - name: mailman + port: 9090 timeouts: - request: 240s - backendRequest: 0s + request: 240s + backendRequest: 0s