├── .gitignore ├── Docker ├── Dockerfile ├── entrypoint.sh └── etc │ ├── rsyslog.conf │ ├── rsyslog.d │ ├── imux.conf │ ├── maillog.conf │ └── stdout.conf │ └── supervisor.d │ ├── postfix.ini │ └── rsyslog.ini ├── LICENSE.txt ├── README.md └── helm └── postfix ├── .helmignore ├── Chart.yaml ├── templates ├── NOTES.txt ├── _helpers.tpl ├── configmap.yaml ├── deployment.yaml ├── role.yaml ├── rolebinding.yaml ├── secret.yaml ├── service.yaml ├── serviceaccount.yaml └── servicemonitor.yaml └── values.yaml /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | tmp 3 | -------------------------------------------------------------------------------- /Docker/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine:3.17.2 2 | 3 | MAINTAINER Eldad Assis 4 | 5 | # Install postfix and supervisor 6 | RUN apk add --no-cache \ 7 | postfix \ 8 | rsyslog \ 9 | libsasl \ 10 | cyrus-sasl-login \ 11 | ca-certificates \ 12 | supervisor && \ 13 | /usr/bin/newaliases 14 | 15 | # Copy files into container 16 | COPY . / 17 | 18 | # SMTP port 19 | EXPOSE 25 20 | 21 | ENTRYPOINT [ "/entrypoint.sh" ] 22 | -------------------------------------------------------------------------------- /Docker/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | TX_SMTP_RELAY_HOST=${TX_SMTP_RELAY_HOST?Missing env var TX_SMTP_RELAY_HOST} 4 | TX_SMTP_RELAY_MYHOSTNAME=${TX_SMTP_RELAY_MYHOSTNAME?Missing env var TX_SMTP_RELAY_MYHOSTNAME} 5 | TX_SMTP_RELAY_USERNAME=${TX_SMTP_RELAY_USERNAME?Missing env var TX_SMTP_RELAY_USERNAME} 6 | TX_SMTP_RELAY_PASSWORD=${TX_SMTP_RELAY_PASSWORD?Missing env var TX_SMTP_RELAY_PASSWORD} 7 | TX_SMTP_RELAY_NETWORKS=${TX_SMTP_RELAY_NETWORKS:-10.0.0.0/8,127.0.0.0/8,172.17.0.0/16,192.0.0.0/8} 8 | 9 | echo "====================================" 10 | echo "====== Setting configuration =======" 11 | echo "TX_SMTP_RELAY_HOST - ${TX_SMTP_RELAY_HOST}" 12 | echo "TX_SMTP_RELAY_MYHOSTNAME - ${TX_SMTP_RELAY_MYHOSTNAME}" 13 | echo "TX_SMTP_RELAY_USERNAME - ${TX_SMTP_RELAY_USERNAME}" 14 | echo "TX_SMTP_RELAY_PASSWORD - (hidden)" 15 | echo "TX_SMTP_RELAY_NETWORKS - ${TX_SMTP_RELAY_NETWORKS}" 16 | echo "POSTFIX_CUSTOM_CONFIG - ${POSTFIX_CUSTOM_CONFIG}" 17 | echo "====================================" 18 | 19 | # Write SMTP credentials 20 | echo "${TX_SMTP_RELAY_HOST} ${TX_SMTP_RELAY_USERNAME}:${TX_SMTP_RELAY_PASSWORD}" > /etc/postfix/sasl_passwd || exit 1 21 | postmap /etc/postfix/sasl_passwd || exit 1 22 | rm /etc/postfix/sasl_passwd || exit 1 23 | 24 | # Set configurations 25 | postconf 'smtp_sasl_auth_enable = yes' || exit 1 26 | postconf 'smtp_sasl_password_maps = lmdb:/etc/postfix/sasl_passwd' || exit 1 27 | postconf 'smtp_sasl_security_options =' || exit 1 28 | postconf 'smtpd_tls_CAfile = /etc/ssl/certs/ca-certificates.crt' || exit 1 29 | postconf "relayhost = ${TX_SMTP_RELAY_HOST}" || exit 1 30 | postconf "myhostname = ${TX_SMTP_RELAY_MYHOSTNAME}" || exit 1 31 | postconf "mynetworks = ${TX_SMTP_RELAY_NETWORKS}" || exit 1 32 | 33 | # http://www.postfix.org/COMPATIBILITY_README.html#smtputf8_enable 34 | postconf 'smtputf8_enable = no' || exit 1 35 | 36 | # This makes sure the message id is set. If this is set to no dkim=fail will happen. 37 | postconf 'always_add_missing_headers = yes' || exit 1 38 | 39 | # Add extra configuration directly to /etc/postfix/main.cf 40 | if [ -n "${POSTFIX_CUSTOM_CONFIG}" ]; then 41 | echo 42 | echo "====================================" 43 | echo "====== Custom configuration ========" 44 | OLD_IFS=${IFS} 45 | IFS=';' 46 | for f in ${POSTFIX_CUSTOM_CONFIG}; do 47 | f=$(echo "$f" | tr -d ' ') 48 | echo "$f" 49 | postconf "$f" || exit 1 50 | done 51 | IFS=${OLD_IFS} 52 | echo "====================================" 53 | fi 54 | 55 | # Have supervisord run and control postfix (/etc/supervisor.d/postfix.ini) 56 | echo 57 | echo "====================================" 58 | echo "=== Starting the postfix service ===" 59 | echo "====================================" 60 | /usr/bin/supervisord -n 61 | -------------------------------------------------------------------------------- /Docker/etc/rsyslog.conf: -------------------------------------------------------------------------------- 1 | # http://www.rsyslog.com/doc/ 2 | $ModLoad immark.so # provide --MARK-- message capability 3 | 4 | $IncludeConfig /etc/rsyslog.d/*.conf 5 | -------------------------------------------------------------------------------- /Docker/etc/rsyslog.d/imux.conf: -------------------------------------------------------------------------------- 1 | # Input modules 2 | module(load="imuxsock") 3 | input(type="imuxsock" Socket="/var/run/rsyslog/dev/log" CreatePath="on") 4 | -------------------------------------------------------------------------------- /Docker/etc/rsyslog.d/maillog.conf: -------------------------------------------------------------------------------- 1 | mail.* -/data/log/maillog 2 | -------------------------------------------------------------------------------- /Docker/etc/rsyslog.d/stdout.conf: -------------------------------------------------------------------------------- 1 | $ModLoad omstdout.so # provide messages to stdout 2 | 3 | *.* :omstdout: # send everything to stdout 4 | -------------------------------------------------------------------------------- /Docker/etc/supervisor.d/postfix.ini: -------------------------------------------------------------------------------- 1 | [program:postfix] 2 | process_name = master 3 | directory = /etc/postfix 4 | command = /usr/sbin/postfix -c /etc/postfix start 5 | startsecs = 0 6 | autorestart = false 7 | -------------------------------------------------------------------------------- /Docker/etc/supervisor.d/rsyslog.ini: -------------------------------------------------------------------------------- 1 | [program:rsyslog] 2 | command=/usr/sbin/rsyslogd -n 3 | numprocs=1 4 | autostart=true 5 | autorestart=true 6 | stdout_logfile=/dev/stdout 7 | stdout_logfile_maxbytes=0 8 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Eldad Assis 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Postfix relay running in Kubernetes 2 | This repository has an example of a postfix relay running in Kubernetes using a helm chart. 3 | 4 | ## Build Docker image 5 | You can build the Docker image locally 6 | ```bash 7 | # For local build 8 | docker build -t eldada.jfrog.io/docker/postfix-relay:0.9 Docker/ 9 | 10 | # Multi arch build and push 11 | docker buildx build --platform linux/amd64,linux/arm64 -t eldada.jfrog.io/docker/postfix-relay:0.9 Docker/p --push 12 | ``` 13 | 14 | ## Run locally with Docker 15 | Run the postfix relay locally for testing 16 | ```bash 17 | # Need to set SMTP connection details 18 | export SMTP="[smtp.mailgun.org]:587" 19 | export USERNAME_TEST= 20 | export PASSWORD_TEST= 21 | 22 | # Optional custom configuration to add/override in /etc/postfix/main.cf (delimited by a ";") 23 | export POSTFIX_CUSTOM_CONFIG="key1 = value1;key2 = value2;key3 = value3" 24 | 25 | # Set list of allowed networks 26 | export TX_SMTP_RELAY_NETWORKS='10.0.0.0/8,127.0.0.0/8,172.17.0.0/16,192.0.0.0/8' 27 | 28 | docker run --rm -d --name postfix-relay -p 2525:25 \ 29 | -e TX_SMTP_RELAY_HOST="${SMTP}" \ 30 | -e TX_SMTP_RELAY_MYHOSTNAME=my.local \ 31 | -e TX_SMTP_RELAY_USERNAME=${USERNAME_TEST} \ 32 | -e TX_SMTP_RELAY_PASSWORD=${PASSWORD_TEST} \ 33 | -e TX_SMTP_RELAY_NETWORKS=${TX_SMTP_RELAY_NETWORKS} \ 34 | -e POSTFIX_CUSTOM_CONFIG="${POSTFIX_CUSTOM_CONFIG}" \ 35 | eldada.jfrog.io/docker/postfix-relay:0.9 36 | ``` 37 | 38 | ### Test sending mail 39 | 1. Connect to running container on port 2525 40 | ```bash 41 | telnet localhost 2525 42 | ``` 43 | 44 | 2. Edit the following with your details and paste in your terminal 45 | ```bash 46 | helo localhost 47 | mail from: noreply@yourhost.com 48 | rcpt to: you@your.co 49 | data 50 | Subject: Subject here... 51 | The true story of swans singing Pink Floyd. 52 | . 53 | quit 54 | ``` 55 | 56 | 3. You should see the following 57 | ```bash 58 | 220 tx-smtp-relay.yourhost.com ESMTP Postfix 59 | helo localhost 60 | 250 tx-smtp-relay.yourhost.com 61 | mail from: noreply@yourhost.com 62 | 250 2.1.0 Ok 63 | rcpt to: you@your.co 64 | 250 2.1.5 Ok 65 | data 66 | 354 End data with . 67 | Subject: Subject here... 68 | The true story of swans singing Pink Floyd. 69 | . 70 | 250 2.0.0 Ok: queued as 982FF53C 71 | quit 72 | 221 2.0.0 Bye 73 | Connection closed by foreign host 74 | ``` 75 | 76 | 4. Check the inbox of `you@your.co` and see you got the email. 77 | 78 | 79 | ## Deploy Helm Chart 80 | The Helm Chart in [helm/postfix](helm/postfix) directory can be used to deploy the postfix-relay into your Kubernetes cluster. 81 | 82 | Create a `custom-values.yaml` with the configuration details 83 | ```yaml 84 | smtp: 85 | relayHost: "[smtp.mailgun.org]:587" 86 | relayMyhostname: 87 | relayUsername: 88 | relayPassword: 89 | relayNetworks: '10.0.0.0/8,127.0.0.0/8,172.17.0.0/16,192.0.0.0/8' 90 | ``` 91 | 92 | Deploy postfix 93 | ```bash 94 | helm upgrade --install postfix-relay helm/postfix -f custom-values.yaml 95 | ``` 96 | 97 | ### Postfix Metrics exporter 98 | An optional postfix-exporter sidecar can be deployed for exposing postfix metrics. This is using the work from https://github.com/kumina/postfix_exporter. 99 | 100 | To enable the exporter sidecar, update your `custom-values.yaml` file and **add** 101 | ```yaml 102 | # Enable the postfix-exporter sidecar 103 | exporter: 104 | enabled: true 105 | 106 | # Enable a ServiceMonitor object for Prometheus scraping 107 | serviceMonitor: 108 | enabled: true 109 | ``` 110 | 111 | Deploy postfix 112 | ```bash 113 | helm upgrade --install postfix-relay helm/postfix -f custom-values.yaml 114 | ``` 115 | 116 | ## Thanks 117 | The work in this repository is based on 118 | - https://github.com/applariat/kubernetes-postfix-relay-host 119 | - https://github.com/kumina/postfix_exporter 120 | - My pains 121 | -------------------------------------------------------------------------------- /helm/postfix/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *~ 18 | # Various IDEs 19 | .project 20 | .idea/ 21 | *.tmproj 22 | -------------------------------------------------------------------------------- /helm/postfix/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | version: 0.1.9 3 | appVersion: "0.9" 4 | description: A Helm chart for a highly available postfix relay in Kubernetes 5 | name: postfix 6 | keywords: 7 | - postfix 8 | sources: 9 | - https://github.com/eldada/postfix-relay-kubernetes 10 | maintainers: 11 | - name: eldada 12 | email: eldada@jfrog.com 13 | -------------------------------------------------------------------------------- /helm/postfix/templates/NOTES.txt: -------------------------------------------------------------------------------- 1 | Postfix relay Deployed! 2 | -------------------------------------------------------------------------------- /helm/postfix/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | {{/* 3 | Expand the name of the chart. 4 | */}} 5 | {{- define "postfix.name" -}} 6 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} 7 | {{- end -}} 8 | 9 | {{/* 10 | Create a default fully qualified app name. 11 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 12 | If release name contains chart name it will be used as a full name. 13 | */}} 14 | {{- define "postfix.fullname" -}} 15 | {{- if .Values.fullnameOverride -}} 16 | {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} 17 | {{- else -}} 18 | {{- $name := default .Chart.Name .Values.nameOverride -}} 19 | {{- if contains $name .Release.Name -}} 20 | {{- .Release.Name | trunc 63 | trimSuffix "-" -}} 21 | {{- else -}} 22 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} 23 | {{- end -}} 24 | {{- end -}} 25 | {{- end -}} 26 | 27 | {{/* 28 | Create chart name and version as used by the chart label. 29 | */}} 30 | {{- define "postfix.chart" -}} 31 | {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} 32 | {{- end -}} 33 | 34 | {{/* 35 | Create the name of the service account to use 36 | */}} 37 | {{- define "postfix.serviceAccountName" -}} 38 | {{- if .Values.serviceAccount.create -}} 39 | {{ default (include "postfix.fullname" .) .Values.serviceAccount.name }} 40 | {{- else -}} 41 | {{ default "default" .Values.serviceAccount.name }} 42 | {{- end -}} 43 | {{- end -}} 44 | -------------------------------------------------------------------------------- /helm/postfix/templates/configmap.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: {{ template "postfix.fullname" . }} 5 | labels: 6 | app: {{ template "postfix.name" . }} 7 | chart: {{ template "postfix.chart" . }} 8 | release: {{ .Release.Name }} 9 | heritage: {{ .Release.Service }} 10 | data: 11 | tx-smtp-relay-host: '{{ .Values.smtp.relayHost }}' 12 | tx-smtp-relay-myhostname: '{{ .Values.smtp.relayMyhostname }}' 13 | tx-smtp-relay-username: '{{ .Values.smtp.relayUsername }}' 14 | tx-smtp-relay-networks: '{{ .Values.smtp.relayNetworks }}' 15 | postfix-custom-config: '{{ .Values.postfixCustomConfig }}' 16 | -------------------------------------------------------------------------------- /helm/postfix/templates/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: {{ template "postfix.fullname" . }} 5 | labels: 6 | app: {{ template "postfix.name" . }} 7 | chart: {{ template "postfix.chart" . }} 8 | release: {{ .Release.Name }} 9 | heritage: {{ .Release.Service }} 10 | spec: 11 | replicas: {{ .Values.replicaCount }} 12 | selector: 13 | matchLabels: 14 | app: {{ template "postfix.name" . }} 15 | release: {{ .Release.Name }} 16 | template: 17 | metadata: 18 | labels: 19 | app: {{ template "postfix.name" . }} 20 | release: {{ .Release.Name }} 21 | spec: 22 | serviceAccountName: {{ template "postfix.serviceAccountName" . }} 23 | containers: 24 | - name: {{ template "postfix.name" . }} 25 | image: '{{ .Values.image.repository }}:{{ default .Chart.AppVersion .Values.image.tag }}' 26 | imagePullPolicy: {{ .Values.image.pullPolicy }} 27 | env: 28 | - name: TX_SMTP_RELAY_HOST 29 | valueFrom: 30 | configMapKeyRef: 31 | name: {{ template "postfix.fullname" . }} 32 | key: tx-smtp-relay-host 33 | - name: TX_SMTP_RELAY_MYHOSTNAME 34 | valueFrom: 35 | configMapKeyRef: 36 | name: {{ template "postfix.fullname" . }} 37 | key: tx-smtp-relay-myhostname 38 | - name: TX_SMTP_RELAY_NETWORKS 39 | valueFrom: 40 | configMapKeyRef: 41 | name: {{ template "postfix.fullname" . }} 42 | key: tx-smtp-relay-networks 43 | - name: TX_SMTP_RELAY_USERNAME 44 | valueFrom: 45 | configMapKeyRef: 46 | name: {{ template "postfix.fullname" . }} 47 | key: tx-smtp-relay-username 48 | - name: TX_SMTP_RELAY_PASSWORD 49 | valueFrom: 50 | secretKeyRef: 51 | name: {{ template "postfix.fullname" . }} 52 | key: tx-smtp-relay-password 53 | - name: POSTFIX_CUSTOM_CONFIG 54 | valueFrom: 55 | configMapKeyRef: 56 | name: {{ template "postfix.fullname" . }} 57 | key: postfix-custom-config 58 | ports: 59 | - name: smtp 60 | containerPort: {{ .Values.service.port }} 61 | volumeMounts: 62 | - mountPath: /var/spool/postfix/ 63 | name: metrics 64 | - mountPath: /data/log/ 65 | name: logs 66 | resources: 67 | {{ toYaml .Values.resources | indent 10 }} 68 | {{- if .Values.exporter.enabled }} 69 | - name: {{ template "postfix.name" . }}-exporter 70 | image: '{{ .Values.exporter.image.repository }}:{{ .Values.exporter.image.tag }}' 71 | imagePullPolicy: {{ .Values.exporter.image.pullPolicy }} 72 | args: 73 | - --postfix.logfile_path=/data/log/maillog 74 | - --postfix.showq_path=/var/spool/postfix/public/showq 75 | ports: 76 | - name: exporter 77 | containerPort: {{ .Values.service.exporterPort }} 78 | volumeMounts: 79 | - mountPath: /var/spool/postfix/ 80 | name: metrics 81 | - mountPath: /data/log/ 82 | name: logs 83 | resources: 84 | {{ toYaml .Values.exporter.resources | indent 10 }} 85 | {{ end }} 86 | volumes: 87 | - name: metrics 88 | emptyDir: {} 89 | - name: logs 90 | emptyDir: {} 91 | {{- with .Values.nodeSelector }} 92 | nodeSelector: 93 | {{ toYaml . | indent 8 }} 94 | {{- end }} 95 | {{- with .Values.affinity }} 96 | affinity: 97 | {{ toYaml . | indent 8 }} 98 | {{- end }} 99 | {{- with .Values.tolerations }} 100 | tolerations: 101 | {{ toYaml . | indent 8 }} 102 | {{- end }} 103 | -------------------------------------------------------------------------------- /helm/postfix/templates/role.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.rbac.create }} 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: Role 4 | metadata: 5 | name: {{ template "postfix.fullname" . }} 6 | labels: 7 | app: {{ template "postfix.name" . }} 8 | chart: {{ template "postfix.chart" . }} 9 | release: {{ .Release.Name }} 10 | heritage: {{ .Release.Service }} 11 | rules: 12 | {{ toYaml .Values.rbac.role.rules }} 13 | {{- end }} 14 | -------------------------------------------------------------------------------- /helm/postfix/templates/rolebinding.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.rbac.create }} 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: RoleBinding 4 | metadata: 5 | name: {{ template "postfix.fullname" . }} 6 | labels: 7 | app: {{ template "postfix.name" . }} 8 | chart: {{ template "postfix.chart" . }} 9 | release: {{ .Release.Name }} 10 | heritage: {{ .Release.Service }} 11 | subjects: 12 | - kind: ServiceAccount 13 | name: {{ template "postfix.serviceAccountName" . }} 14 | roleRef: 15 | kind: Role 16 | apiGroup: rbac.authorization.k8s.io 17 | name: {{ template "postfix.fullname" . }} 18 | {{- end }} 19 | -------------------------------------------------------------------------------- /helm/postfix/templates/secret.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: {{ template "postfix.fullname" . }} 5 | labels: 6 | app: {{ template "postfix.name" . }} 7 | chart: {{ template "postfix.chart" . }} 8 | release: {{ .Release.Name }} 9 | heritage: {{ .Release.Service }} 10 | type: Opaque 11 | data: 12 | tx-smtp-relay-password: {{ .Values.smtp.relayPassword | b64enc }} 13 | -------------------------------------------------------------------------------- /helm/postfix/templates/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ template "postfix.fullname" . }} 5 | labels: 6 | app: {{ template "postfix.name" . }} 7 | chart: {{ template "postfix.chart" . }} 8 | release: {{ .Release.Name }} 9 | heritage: {{ .Release.Service }} 10 | spec: 11 | type: {{ .Values.service.type }} 12 | {{- if .Values.service.loadBalancerIP }} 13 | loadBalancerIP: {{ .Values.service.loadBalancerIP }} 14 | {{- end }} 15 | ports: 16 | - port: {{ .Values.service.port }} 17 | targetPort: smtp 18 | name: smtp 19 | {{- if .Values.exporter.enabled }} 20 | - port: {{ .Values.service.exporterPort }} 21 | name: exporter 22 | {{ end }} 23 | selector: 24 | app: {{ template "postfix.name" . }} 25 | release: {{ .Release.Name }} 26 | -------------------------------------------------------------------------------- /helm/postfix/templates/serviceaccount.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.serviceAccount.create }} 2 | apiVersion: v1 3 | kind: ServiceAccount 4 | metadata: 5 | name: {{ template "postfix.fullname" . }} 6 | labels: 7 | app: {{ template "postfix.name" . }} 8 | chart: {{ template "postfix.chart" . }} 9 | release: {{ .Release.Name }} 10 | heritage: {{ .Release.Service }} 11 | {{- end }} 12 | -------------------------------------------------------------------------------- /helm/postfix/templates/servicemonitor.yaml: -------------------------------------------------------------------------------- 1 | {{- if and .Values.exporter.enabled .Values.serviceMonitor.enabled }} 2 | apiVersion: monitoring.coreos.com/v1 3 | kind: ServiceMonitor 4 | metadata: 5 | name: {{ template "postfix.name" . }}-exporter 6 | labels: 7 | app: {{ template "postfix.name" . }} 8 | release: {{ .Release.Name }} 9 | spec: 10 | selector: 11 | matchLabels: 12 | app: {{ template "postfix.name" . }} 13 | namespaceSelector: 14 | any: true 15 | endpoints: 16 | - port: exporter 17 | path: /metrics 18 | interval: "30s" 19 | {{ end }} 20 | -------------------------------------------------------------------------------- /helm/postfix/values.yaml: -------------------------------------------------------------------------------- 1 | # Default values for postfix. 2 | # This is a YAML-formatted file. 3 | # Declare variables to be passed into your templates. 4 | 5 | # High availability 6 | replicaCount: 2 7 | 8 | # Role Based Access Control 9 | # Ref: https://kubernetes.io/docs/admin/authorization/rbac/ 10 | rbac: 11 | create: true 12 | role: 13 | ## Rules to create. It follows the role specification 14 | rules: 15 | - apiGroups: 16 | - '' 17 | resources: 18 | - services 19 | - endpoints 20 | - pods 21 | verbs: 22 | - get 23 | - watch 24 | - list 25 | 26 | # Service Account 27 | # Ref: https://kubernetes.io/docs/admin/service-accounts-admin/ 28 | serviceAccount: 29 | create: true 30 | ## The name of the ServiceAccount to use. 31 | ## If not set and create is true, a name is generated using the fullname template 32 | name: 33 | 34 | # Docker image 35 | image: 36 | repository: eldada.jfrog.io/docker/postfix-relay 37 | # tag: 0.8 38 | pullPolicy: IfNotPresent 39 | 40 | # Exporter Docker image 41 | # https://github.com/kumina/postfix_exporter 42 | exporter: 43 | enabled: false 44 | image: 45 | repository: eldada.jfrog.io/docker/postfix-exporter 46 | tag: 0.2 47 | pullPolicy: IfNotPresent 48 | # Resources needed for the postfix-exporter container 49 | resources: 50 | requests: 51 | cpu: 10m 52 | memory: 40Mi 53 | limits: 54 | cpu: 100m 55 | memory: 100Mi 56 | 57 | # Add a ServiceMonitor object for scraping metrics by Prometheus 58 | # Must have exporter.enabled=true 59 | serviceMonitor: 60 | # Enable only if you have support for ServiceMonitor object with version monitoring.coreos.com/v1 (Prometheus) 61 | enabled: false 62 | 63 | # Expose pods with service on port 25 64 | service: 65 | type: ClusterIP 66 | port: 25 67 | exporterPort: 9154 68 | loadBalancerIP: 69 | 70 | # SMTP server details 71 | # Used by postfix to connect to SMTP server 72 | smtp: 73 | # Example with mailgun 74 | relayHost: "[smtp.mailgun.org]:587" 75 | relayMyhostname: my.host.local 76 | relayUsername: relayuser 77 | relayPassword: relaypassword 78 | relayNetworks: '10.0.0.0/8,127.0.0.0/8,172.17.0.0/16,192.0.0.0/8' 79 | 80 | # Optional extra configuration to add or edit in /etc/postfix/main.cf 81 | # A single string with key=value separated by a semicolon char (;) 82 | # Example: postfixCustomConfig: "key1 = value1; key2 = value2; key3 = value3" 83 | postfixCustomConfig: 84 | 85 | # Resources needed for the postfix container 86 | resources: 87 | requests: 88 | cpu: 40m 89 | memory: 40Mi 90 | limits: 91 | cpu: 100m 92 | memory: 100Mi 93 | 94 | nodeSelector: {} 95 | 96 | tolerations: [] 97 | 98 | affinity: {} 99 | --------------------------------------------------------------------------------