--- apiVersion: v1 kind: Namespace metadata: name: mail --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: stalwart-data namespace: mail spec: accessModes: - ReadWriteOnce storageClassName: hcloud-volumes-encrypted resources: requests: storage: 20Gi --- # Secret managed via SealedSecrets # See: stalwart-admin-credentials-sealed.yaml --- apiVersion: v1 kind: Service metadata: name: stalwart namespace: mail spec: type: ClusterIP clusterIP: None selector: app: stalwart ports: - name: smtp port: 25 targetPort: 25 protocol: TCP - name: submission port: 587 targetPort: 587 protocol: TCP - name: submissions port: 465 targetPort: 465 protocol: TCP - name: imap port: 143 targetPort: 143 protocol: TCP - name: imaps port: 993 targetPort: 993 protocol: TCP - name: http port: 8080 targetPort: 8080 protocol: TCP - name: sieve port: 4190 targetPort: 4190 protocol: TCP --- apiVersion: v1 kind: Service metadata: name: stalwart-smtp namespace: mail spec: type: LoadBalancer selector: app: stalwart ports: - name: smtp port: 25 targetPort: 25 protocol: TCP - name: submission port: 587 targetPort: 587 protocol: TCP - name: submissions port: 465 targetPort: 465 protocol: TCP --- apiVersion: v1 kind: Service metadata: name: stalwart-imap namespace: mail spec: type: LoadBalancer selector: app: stalwart ports: - name: imap port: 143 targetPort: 143 protocol: TCP - name: imaps port: 993 targetPort: 993 protocol: TCP --- apiVersion: v1 kind: Service metadata: name: stalwart-http namespace: mail spec: type: ClusterIP selector: app: stalwart ports: - name: http port: 8080 targetPort: 8080 protocol: TCP --- apiVersion: apps/v1 kind: StatefulSet metadata: name: stalwart namespace: mail spec: serviceName: stalwart replicas: 1 selector: matchLabels: app: stalwart template: metadata: labels: app: stalwart spec: securityContext: fsGroup: 2000 runAsUser: 2000 runAsGroup: 2000 initContainers: - name: fix-permissions image: busybox command: ["sh", "-c", "chown -R 2000:2000 /opt/stalwart && chmod -R 755 /opt/stalwart"] volumeMounts: - name: data mountPath: /opt/stalwart containers: - name: stalwart image: stalwartlabs/stalwart:latest ports: - containerPort: 25 name: smtp - containerPort: 587 name: submission - containerPort: 465 name: submissions - containerPort: 143 name: imap - containerPort: 993 name: imaps - containerPort: 8080 name: http - containerPort: 4190 name: sieve volumeMounts: - name: data mountPath: /opt/stalwart - name: data mountPath: /etc/stalwart subPath: etc livenessProbe: httpGet: path: /healthz/live port: 8080 initialDelaySeconds: 30 periodSeconds: 10 timeoutSeconds: 5 failureThreshold: 3 readinessProbe: httpGet: path: /healthz/ready port: 8080 initialDelaySeconds: 10 periodSeconds: 5 timeoutSeconds: 3 failureThreshold: 3 resources: requests: memory: "512Mi" cpu: "250m" limits: memory: "2Gi" cpu: "2000m" securityContext: runAsNonRoot: true allowPrivilegeEscalation: false capabilities: drop: [ALL] add: [NET_BIND_SERVICE] seccompProfile: type: RuntimeDefault volumes: - name: data persistentVolumeClaim: claimName: stalwart-data --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: stalwart-web namespace: mail annotations: cert-manager.io/cluster-issuer: "letsencrypt-prod" traefik.ingress.kubernetes.io/router.entrypoints: websecure spec: ingressClassName: traefik tls: - hosts: - mail.basicstack.de secretName: stalwart-tls rules: - host: mail.basicstack.de http: paths: - path: / pathType: Prefix backend: service: name: stalwart-http port: number: 8080