commit 4b6ef240d4e14a223fe671f0f2d4656b07a10927
parent e44ce531d297775c1f6733ea5168d8634dfb3856
Author: MTRNord <MTRNord@users.noreply.github.com>
Date: Wed, 1 Oct 2025 19:27:46 +0200
Meow
Diffstat:
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