cluster

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

release.yaml (9767B)


      1 apiVersion: helm.toolkit.fluxcd.io/v2
      2 kind: HelmRelease
      3 metadata:
      4   name: stalwart-mail
      5   namespace: stalwart
      6 spec:
      7   interval: 5m
      8   chart:
      9     spec:
     10       chart: stalwart-mail
     11       version: "1.0.x"
     12       sourceRef:
     13         kind: HelmRepository
     14         name: wrenix
     15         namespace: stalwart
     16       interval: 60m
     17   install:
     18     crds: CreateReplace
     19   upgrade:
     20     crds: CreateReplace
     21   postRenderers:
     22     - kustomize:
     23         patches:
     24           - target:
     25               version: v1
     26               kind: Service
     27               name: stalwart-mail
     28             patch: |
     29               - op: add
     30                 path: /spec/ports/-
     31                 value:
     32                   name: submission-internal
     33                   port: 2587
     34                   protocol: TCP
     35                   targetPort: 2587
     36           - target:
     37               group: monitoring.coreos.com
     38               version: v1
     39               kind: ServiceMonitor
     40               name: stalwart-mail
     41             patch: |
     42               - op: replace
     43                 path: /spec/endpoints/0/basicAuth/password
     44                 value:
     45                   key: metrics-password
     46                   name: stalwart-secret
     47               - op: replace
     48                 path: /spec/endpoints/0/basicAuth/username
     49                 value:
     50                   key: metrics-username
     51                   name: stalwart-secret
     52               - op: add
     53                 path: /spec/endpoints/0/metricRelabelings
     54                 value:
     55                   - sourceLabels: [__name__]
     56                     regex: (.+)
     57                     targetLabel: __name__
     58                     replacement: stalwart_$1
     59   values:
     60     replicaCount: 1
     61 
     62     backup:
     63       enabled: true
     64 
     65     image:
     66       registry: ghcr.io
     67       repository: stalwartlabs/stalwart
     68       pullPolicy: IfNotPresent
     69 
     70     # Don't use the chart's built-in secret — we manage our own stalwart-secret
     71     secrets:
     72       create: false
     73 
     74     # Env vars from stalwart-secret (S3, DB, admin password, LDAP)
     75     env:
     76       - name: PG_PASSWORD
     77         valueFrom:
     78           secretKeyRef:
     79             name: stalwart-secret
     80             key: pg-password
     81       - name: S3_ACCESS_KEY
     82         valueFrom:
     83           secretKeyRef:
     84             name: stalwart-secret
     85             key: s3-access-key
     86       - name: S3_SECRET_KEY
     87         valueFrom:
     88           secretKeyRef:
     89             name: stalwart-secret
     90             key: s3-secret-key
     91       - name: FALLBACK_ADMIN_SECRET
     92         valueFrom:
     93           secretKeyRef:
     94             name: stalwart-secret
     95             key: admin-password
     96       - name: METRICS_USERNAME
     97         value: prometheus
     98       - name: METRICS_SECRET
     99         valueFrom:
    100           secretKeyRef:
    101             name: stalwart-secret
    102             key: metrics-password
    103       - name: LDAP_BIND_SECRET
    104         valueFrom:
    105           secretKeyRef:
    106             name: stalwart-secret
    107             key: ldap-bind-password
    108 
    109     persistence:
    110       enabled: true
    111       storageClass: longhorn
    112       size: 10Gi
    113       accessMode: ReadWriteMany
    114 
    115     # cert-manager issues the TLS cert used by SMTP/IMAP TLS listeners
    116     certificate:
    117       certmanager:
    118         enabled: true
    119         issuerRef:
    120           group: cert-manager.io
    121           kind: ClusterIssuer
    122           name: letsencrypt-dns
    123         dnsNames:
    124           - mail.midnightthoughts.space
    125           - mail.nordgedanken.dev
    126 
    127     prometheus:
    128       servicemonitor:
    129         enabled: true
    130         labels:
    131           release: kube-prometheus-stack
    132 
    133     config:
    134       # Keys stored in the local config file (not the DB)
    135       config:
    136         local-keys:
    137           - "store.*"
    138           - "directory.*"
    139           - "tracer.*"
    140           - "!server.blocked-ip.*"
    141           - "server.*"
    142           - "authentication.fallback-admin.*"
    143           - "cluster.*"
    144           - "config.local-keys.*"
    145           - "storage.data"
    146           - "storage.blob"
    147           - "storage.lookup"
    148           - "storage.fts"
    149           - "storage.directory"
    150           - "certificate.*"
    151           - "server.allowed-ip.*"
    152           - "metrics.prometheus.*"
    153           - "auth.dkim.sign.*"
    154           - "auth.dkim.verify"
    155           - "http.use-x-forwarded"
    156           - "report.domain"
    157           - "queue.*"
    158           - "session.auth.*"
    159           - "session.rcpt.*"
    160           - "calendar.*"
    161 
    162       authentication:
    163         fallback-admin:
    164           user: admin
    165           secret: "%{env:FALLBACK_ADMIN_SECRET}%"
    166 
    167       metrics:
    168         prometheus:
    169           enable: true
    170           auth:
    171             username: "%{env:METRICS_USERNAME}%"
    172             secret: "%{env:METRICS_SECRET}%"
    173 
    174       http:
    175         use-x-forwarded: true
    176 
    177       calendar:
    178         scheduling:
    179           http-rsvp:
    180             url: https://webmail.midnightthoughts.space/calendar/rsvp
    181 
    182       # ── Storage ─────────────────────────────────────────────────────────
    183       storage:
    184         data: db
    185         blob: s3blob
    186         fts: db
    187         lookup: db
    188         directory: default
    189 
    190       store:
    191         db:
    192           type: postgresql
    193           host: pg-cluster-v2-rw.postgres-cluster.svc.cluster.local
    194           port: 5432
    195           database: stalwart
    196           user: stalwart
    197           password: "%{env:PG_PASSWORD}%"
    198         s3blob:
    199           type: s3
    200           bucket: midnightthoughts-stalwart
    201           region: hel1
    202           endpoint: https://hel1.your-objectstorage.com
    203           access-key: "%{env:S3_ACCESS_KEY}%"
    204           secret-key: "%{env:S3_SECRET_KEY}%"
    205 
    206       # ── Directory (Authentik LDAP) ───────────────────────────────────────
    207       directory:
    208         default:
    209           type: internal
    210           store: db
    211 
    212       # ── Listeners (proxy-protocol from Envoy Gateway) ────────────────────
    213       server:
    214         hostname: mail.midnightthoughts.space
    215         listener:
    216           smtp:
    217             bind: ["[::]:25"]
    218             protocol: smtp
    219             proxy:
    220               trusted-networks:
    221                 - 10.0.0.0/8
    222                 - fd00::/8
    223           submission:
    224             bind: ["[::]:587"]
    225             protocol: smtp
    226             proxy:
    227               trusted-networks:
    228                 - 10.0.0.0/8
    229                 - fd00::/8
    230           submission-internal:
    231             bind: ["[::]:2587"]
    232             protocol: smtp
    233           submissions:
    234             bind: ["[::]:465"]
    235             protocol: smtp
    236             tls:
    237               implicit: true
    238             proxy:
    239               trusted-networks:
    240                 - 10.0.0.0/8
    241                 - fd00::/8
    242           imap:
    243             bind: ["[::]:143"]
    244             protocol: imap
    245             proxy:
    246               trusted-networks:
    247                 - 10.0.0.0/8
    248                 - fd00::/8
    249           imaptls:
    250             bind: ["[::]:993"]
    251             protocol: imap
    252             tls:
    253               implicit: true
    254             proxy:
    255               trusted-networks:
    256                 - 10.0.0.0/8
    257                 - fd00::/8
    258           http:
    259             bind: ["[::]:80"]
    260             protocol: http
    261 
    262       # ── TLS certificate (cert-manager) ────────────────────────────────────
    263       certificate:
    264         default:
    265           default: true
    266           cert: "%{file:/opt/stalwart/etc/certs/tls.crt}%"
    267           private-key: "%{file:/opt/stalwart/etc/certs/tls.key}%"
    268 
    269       # ── DKIM signing ──────────────────────────────────────────────────────
    270       auth:
    271         dkim:
    272           sign:
    273             - if: "listener != 'smtp' && is_local_domain('', sender_domain)"
    274               then: "['rsa-' + sender_domain, 'ed25519-' + sender_domain]"
    275             - else: false
    276           verify: relaxed
    277 
    278       # ── SMTP session: relay lists domain without directory lookup ─────────
    279       session:
    280         auth:
    281           must-match-sender:
    282             - if: "sender_domain == 'lists.midnightthoughts.space' && authenticated_as == 'support@midnightthoughts.space'"
    283               then: false
    284             - else: true
    285         rcpt:
    286           directory:
    287             - if: "rcpt_domain == 'lists.midnightthoughts.space' || rcpt_domain == 'phorge.mtrnord.blog'"
    288               then: "'*'"
    289             - else: "'default'"
    290 
    291       # ── Routing ───────────────────────────────────────────────────────────
    292       queue:
    293         route:
    294           local:
    295             type: local
    296           phorge-relay:
    297             type: relay
    298             address: 10.0.64.129
    299             port: 25
    300             protocol: smtp
    301             tls:
    302               implicit: false
    303               allow-invalid-certs: true
    304           mailman-lmtp:
    305             type: relay
    306             address: mailman.mailserver.svc.cluster.local
    307             port: 8024
    308             protocol: lmtp
    309             tls:
    310               implicit: false
    311               enable: false
    312         strategy:
    313           route:
    314             # TODO: remove once nordgedanken.dev is migrated to Stalwart
    315             - if: "rcpt_domain == 'nordgedanken.dev'"
    316               then: "'mx'"
    317             - if: "rcpt_domain == 'lists.midnightthoughts.space'"
    318               then: "'mailman-lmtp'"
    319             - if: "rcpt_domain == 'phorge.mtrnord.blog'"
    320               then: "'phorge-relay'"
    321             - if: "is_local_domain('', rcpt_domain)"
    322               then: "'local'"
    323             - else: "'mx'"
    324 
    325       tracer:
    326         stdout:
    327           enable: true
    328           type: stdout
    329           level: info
    330           ansi: false