Files
argocd-apps/apps/base/mail/stalwart-deployment.yaml
T
unkin-agent 92a29b4ca9
ci/woodpecker/pr/pre-commit Pipeline was successful
ci/woodpecker/pr/kubeconform Pipeline was successful
Deploy Stalwart into the mail namespace
2026-10-12 00:42:54 +11:00

177 lines
5.2 KiB
YAML

---
apiVersion: apps/v1
kind: Deployment
metadata:
name: stalwart
namespace: mail
annotations:
secret.reloader.stakater.com/reload: "stalwart-admin,stalwart-db-app,stalwart-blobs-s3,wildcard-unkin-net-tls,vault-ca-cert"
spec:
# ponytail: single replica, no cluster coordinator; add one before scaling out.
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app.kubernetes.io/name: stalwart
template:
metadata:
labels:
app.kubernetes.io/name: stalwart
spec:
securityContext:
runAsNonRoot: true
runAsUser: 2000
runAsGroup: 2000
fsGroup: 2000
seccompProfile:
type: RuntimeDefault
# rustls loads SSL_CERT_FILE, so public roots + the internal CA (RGW) go in one bundle.
initContainers:
- name: combine-certs
image: docker.io/stalwartlabs/stalwart:v0.16.25
command:
- sh
- -c
- cat /etc/ssl/certs/ca-certificates.crt /custom-ca/ca.crt > /combined-certs/ca-certificates.crt
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
resources:
limits:
cpu: 100m
memory: 64Mi
requests:
cpu: 25m
memory: 32Mi
volumeMounts:
- name: vault-ca-cert
mountPath: /custom-ca
readOnly: true
- name: combined-certs
mountPath: /combined-certs
containers:
- name: stalwart
image: docker.io/stalwartlabs/stalwart:v0.16.25
imagePullPolicy: IfNotPresent
env:
- name: SSL_CERT_FILE
value: /etc/ssl/combined/ca-certificates.crt
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: stalwart-db-app
key: password
- name: AWS_ACCESS_KEY_ID
valueFrom:
secretKeyRef:
name: stalwart-blobs-s3
key: AWS_ACCESS_KEY_ID
- name: AWS_SECRET_ACCESS_KEY
valueFrom:
secretKeyRef:
name: stalwart-blobs-s3
key: AWS_SECRET_ACCESS_KEY
- name: ADMIN_USERNAME
valueFrom:
secretKeyRef:
name: stalwart-admin
key: username
- name: ADMIN_PASSWORD
valueFrom:
secretKeyRef:
name: stalwart-admin
key: password
- name: STALWART_RECOVERY_ADMIN
value: "$(ADMIN_USERNAME):$(ADMIN_PASSWORD)"
ports:
- containerPort: 8080
name: http
protocol: TCP
- containerPort: 443
name: https
protocol: TCP
- containerPort: 24
name: lmtp
protocol: TCP
- containerPort: 465
name: submissions
protocol: TCP
- containerPort: 587
name: submission
protocol: TCP
- containerPort: 993
name: imaps
protocol: TCP
- containerPort: 9090
name: metrics
protocol: TCP
livenessProbe:
httpGet:
path: /healthz/live
port: http
initialDelaySeconds: 30
periodSeconds: 30
timeoutSeconds: 5
readinessProbe:
httpGet:
path: /healthz/ready
port: http
initialDelaySeconds: 10
periodSeconds: 10
timeoutSeconds: 5
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
# the binary carries a cap_net_bind_service file capability; exec fails without it
add:
- NET_BIND_SERVICE
resources:
limits:
cpu: "2"
memory: 2Gi
requests:
cpu: 100m
memory: 512Mi
volumeMounts:
- name: config
mountPath: /etc/stalwart/config.json
subPath: config.json
readOnly: true
- name: tls
mountPath: /etc/stalwart/tls
readOnly: true
- name: combined-certs
mountPath: /etc/ssl/combined
readOnly: true
- name: data
mountPath: /var/lib/stalwart
- name: tmp
mountPath: /tmp
volumes:
- name: config
configMap:
name: stalwart-config
- name: tls
secret:
secretName: wildcard-unkin-net-tls
- name: vault-ca-cert
secret:
secretName: vault-ca-cert
items:
- key: ca.crt
path: ca.crt
- name: combined-certs
emptyDir: {}
# Webui unpack dir only; mail data is in Postgres and S3.
- name: data
emptyDir: {}
- name: tmp
emptyDir: {}