# SMTP -> Gotify relay for ZITADEL notifications. # # ZITADEL sends verification codes, password resets and one-time passwords by # SMTP only, and this cluster has no working mail path: no SMTP credentials are # configured for ZITADEL, and the notification table shows # verified_email empty for every user. Without a delivery path nobody can finish # a first login, at ZITADEL or at any relying party such as Forgejo. # # This relay accepts plain SMTP on :2525 and forwards every message to Gotify, # so codes arrive on the phone through the existing gotify/igotify setup instead # of email. ZITADEL then points DefaultInstance.SMTPConfiguration at this # Service (see k8s/infra/iam/zitadel-values.yaml). # # The Gotify token is a Secret, never a literal here. apiVersion: apps/v1 kind: Deployment metadata: name: smtp-gotify namespace: iam labels: app: smtp-gotify spec: replicas: 1 revisionHistoryLimit: 2 selector: matchLabels: app: smtp-gotify template: metadata: labels: app: smtp-gotify spec: securityContext: runAsNonRoot: true runAsUser: 65534 runAsGroup: 65534 seccompProfile: type: RuntimeDefault volumes: - name: tmp emptyDir: {} containers: - name: smtp-gotify image: quay.io/reiml/smtp-gotify:latest imagePullPolicy: IfNotPresent env: - name: GOTIFY_URL value: "http://gotify.notifications.svc.cluster.local/" - name: GOTIFY_TOKEN valueFrom: secretKeyRef: name: smtp-gotify key: token - name: GOTIFY_PRIORITY value: "5" # No title template: the relay's default title already carries # the mail subject, and a wrong template field fails the push # silently (the SMTP side still answers 250, so the sender thinks # the message was delivered). ports: - name: smtp containerPort: 2525 protocol: TCP volumeMounts: # The relay stages each message in /tmp before the Gotify push. # With readOnlyRootFilesystem it accepted SMTP (250 queued) and # then silently dropped the message: no push, no error. - name: tmp mountPath: /tmp securityContext: allowPrivilegeEscalation: false readOnlyRootFilesystem: true capabilities: drop: ["ALL"] resources: requests: cpu: 10m memory: 32Mi limits: cpu: 200m memory: 128Mi readinessProbe: tcpSocket: port: smtp initialDelaySeconds: 3 periodSeconds: 10 livenessProbe: tcpSocket: port: smtp initialDelaySeconds: 10 periodSeconds: 20 --- apiVersion: v1 kind: Service metadata: name: smtp-gotify namespace: iam labels: app: smtp-gotify spec: type: ClusterIP selector: app: smtp-gotify ports: - name: smtp port: 2525 targetPort: smtp protocol: TCP