diff --git a/helm/postal/.helmignore b/helm/postal/.helmignore new file mode 100644 index 0000000..f0c1319 --- /dev/null +++ b/helm/postal/.helmignore @@ -0,0 +1,21 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*~ +# Various IDEs +.project +.idea/ +*.tmproj diff --git a/helm/postal/Chart.yaml b/helm/postal/Chart.yaml new file mode 100644 index 0000000..6ed3a36 --- /dev/null +++ b/helm/postal/Chart.yaml @@ -0,0 +1,11 @@ +apiVersion: v2 +name: postal +version: 1.0.0 +appVersion: 3.3.4 +home: https://github.com/postalserver/postal +description: A complete and fully featured mail server +keywords: + - postal +sources: + - https://github.com/postalserver/install +engine: gotpl diff --git a/helm/postal/templates/_helpers.tpl b/helm/postal/templates/_helpers.tpl new file mode 100644 index 0000000..c14b11e --- /dev/null +++ b/helm/postal/templates/_helpers.tpl @@ -0,0 +1,19 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "postal.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +*/}} +{{- define "postal.fullname" -}} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- if contains $name .Release.Name -}} +{{- .Release.Name | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} \ No newline at end of file diff --git a/helm/postal/templates/secret.yaml b/helm/postal/templates/secret.yaml new file mode 100644 index 0000000..d88fe7d --- /dev/null +++ b/helm/postal/templates/secret.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: Secret +metadata: + labels: + app: {{ template "postal.name" . }} + chart: {{ .Chart.Name }}-{{ .Chart.Version }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + name: {{ template "postal.fullname" . }} +data: + postal.yml: {{ toYaml .Values.config | b64enc | quote }} + signing.key: {{ .Values.signingKey | b64enc | quote }} diff --git a/helm/postal/templates/smtp/deployment.yaml b/helm/postal/templates/smtp/deployment.yaml new file mode 100644 index 0000000..a9c5055 --- /dev/null +++ b/helm/postal/templates/smtp/deployment.yaml @@ -0,0 +1,45 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "postal.fullname" . }}-smtp + labels: + app: {{ template "postal.name" . }} + chart: {{ .Chart.Name }}-{{ .Chart.Version }} + component: smtp + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} +spec: + selector: + matchLabels: + app: {{ template "postal.name" . }} + component: smtp + # at the moment, we only support one replica + replicas: {{ .Values.smtp.replicas }} + strategy: + type: Recreate + template: + metadata: + labels: + app: {{ template "postal.name" . }} + component: smtp + annotations: + checksum/secret: {{ include (print .Template.BasePath "/secret.yaml") . | sha256sum }} # Checksum annotation + spec: + containers: + - name: smtp + image: "{{ .Values.image }}:{{ .Values.imageTag }}" + imagePullPolicy: "{{ .Values.imagePullPolicy }}" + command: ["postal", "smtp-server"] + resources: +{{ toYaml .Values.resources | indent 10 }} + ports: + - name: smtp + containerPort: 25 + volumeMounts: + - name: config + mountPath: /config/ + readOnly: true + volumes: + - name: config + secret: + secretName: {{ template "postal.fullname" . }} \ No newline at end of file diff --git a/helm/postal/templates/smtp/service.yaml b/helm/postal/templates/smtp/service.yaml new file mode 100644 index 0000000..c85f869 --- /dev/null +++ b/helm/postal/templates/smtp/service.yaml @@ -0,0 +1,20 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ template "postal.fullname" . }}-smtp + labels: + app: {{ template "postal.name" . }} + chart: {{ .Chart.Name }}-{{ .Chart.Version }} + component: postal + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} +spec: + selector: + app: {{ template "postal.name" . }} + component: smtp + loadBalancerIP: {{ .Values.smtp.service.loadBalancerIP }} + ports: + - name: smtp + port: 25 + targetPort: smtp + type: {{ .Values.smtp.service.type }} diff --git a/helm/postal/templates/web/deployment.yaml b/helm/postal/templates/web/deployment.yaml new file mode 100644 index 0000000..aadb40b --- /dev/null +++ b/helm/postal/templates/web/deployment.yaml @@ -0,0 +1,45 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "postal.fullname" . }}-web + labels: + app: {{ template "postal.name" . }} + chart: {{ .Chart.Name }}-{{ .Chart.Version }} + component: web + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} +spec: + selector: + matchLabels: + app: {{ template "postal.name" . }} + component: web + # at the moment, we only support one replica + replicas: {{ .Values.web.replicas }} + strategy: + type: Recreate + template: + metadata: + labels: + app: {{ template "postal.name" . }} + component: web + annotations: + checksum/secret: {{ include (print .Template.BasePath "/secret.yaml") . | sha256sum }} # Checksum annotation + spec: + containers: + - name: web + image: "{{ .Values.image }}:{{ .Values.imageTag }}" + imagePullPolicy: "{{ .Values.imagePullPolicy }}" + command: ["postal", "web-server"] + resources: +{{ toYaml .Values.resources | indent 10 }} + ports: + - name: web + containerPort: 5000 + volumeMounts: + - name: config + mountPath: /config/ + readOnly: true + volumes: + - name: config + secret: + secretName: {{ template "postal.fullname" . }} \ No newline at end of file diff --git a/helm/postal/templates/web/ingress.yaml b/helm/postal/templates/web/ingress.yaml new file mode 100644 index 0000000..a1c93d3 --- /dev/null +++ b/helm/postal/templates/web/ingress.yaml @@ -0,0 +1,47 @@ + +{{- if .Values.web.ingress.enabled -}} +{{- $fullName := include "postal.fullname" . -}} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: {{ $fullName }} + labels: + app: {{ template "postal.name" . }} + chart: {{ .Chart.Name }}-{{ .Chart.Version }} + component: postal + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + {{- with .Values.web.ingress.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- if .Values.web.ingress.className }} + ingressClassName: {{ .Values.web.ingress.className }} + {{- end }} + {{- if .Values.web.ingress.tls }} + tls: + {{- range .Values.web.ingress.tls }} + - hosts: + {{- range .hosts }} + - {{ . | quote }} + {{- end }} + secretName: {{ .secretName }} + {{- end }} + {{- end }} + rules: + {{- range .Values.web.ingress.hosts }} + - host: {{ .host | quote }} + http: + paths: + {{- range .paths }} + - path: {{ .path }} + pathType: {{ .pathType }} + backend: + service: + name: {{ $fullName }}-web + port: + number: 5000 + {{- end }} + {{- end }} +{{- end }} \ No newline at end of file diff --git a/helm/postal/templates/web/service.yaml b/helm/postal/templates/web/service.yaml new file mode 100644 index 0000000..7fdbdda --- /dev/null +++ b/helm/postal/templates/web/service.yaml @@ -0,0 +1,18 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ template "postal.fullname" . }}-web + labels: + app: {{ template "postal.name" . }} + chart: {{ .Chart.Name }}-{{ .Chart.Version }} + component: postal + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} +spec: + selector: + app: {{ template "postal.name" . }} + component: web + ports: + - name: web + port: 5000 + targetPort: web diff --git a/helm/postal/templates/worker/deployment.yaml b/helm/postal/templates/worker/deployment.yaml new file mode 100644 index 0000000..67fce3f --- /dev/null +++ b/helm/postal/templates/worker/deployment.yaml @@ -0,0 +1,41 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "postal.fullname" . }}-worker + labels: + app: {{ template "postal.name" . }} + chart: {{ .Chart.Name }}-{{ .Chart.Version }} + component: worker + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} +spec: + selector: + matchLabels: + app: {{ template "postal.name" . }} + component: worker + replicas: {{ .Values.worker.replicas }} + strategy: + type: Recreate + template: + metadata: + labels: + app: {{ template "postal.name" . }} + component: worker + annotations: + checksum/secret: {{ include (print .Template.BasePath "/secret.yaml") . | sha256sum }} # Checksum annotation + spec: + containers: + - name: worker + image: "{{ .Values.image }}:{{ .Values.imageTag }}" + imagePullPolicy: "{{ .Values.imagePullPolicy }}" + command: ["postal", "worker"] + resources: +{{ toYaml .Values.resources | indent 10 }} + volumeMounts: + - name: config + mountPath: /config/ + readOnly: true + volumes: + - name: config + secret: + secretName: {{ template "postal.fullname" . }} \ No newline at end of file diff --git a/helm/postal/values.yaml b/helm/postal/values.yaml new file mode 100644 index 0000000..43f6d3d --- /dev/null +++ b/helm/postal/values.yaml @@ -0,0 +1,89 @@ +image: ghcr.io/postalserver/postal +imageTag: "3.3.4" +imagePullPolicy: Always + +resources: {} + +config: + version: 2 + + postal: + web_hostname: example.com + web_protocol: https + smtp_hostname: example.com + + main_db: + host: mariadb.default.svc.cluster.local + username: root + password: + database: postal + + message_db: + host: mariadb.default.svc.cluster.local + username: root + password: + database: postal_messages + + smtp_server: + default_bind_address: "::" + + dns: + # Specify the DNS records that you have configured. Refer to the documentation at + # https://github.com/atech/postal/wiki/Domains-&-DNS-Configuration for further + # information about these. + mx_records: + - mx.example.com + spf_include: spf.example.com + return_path_domain: rp.example.com + route_domain: routes.example.com + track_domain: track.example.com + + smtp: + # Specify an SMTP server that can be used to send messages from the Postal management + # system to users. You can configure this to use a Postal mail server once the + # your installation has been set up. + host: 127.0.0.1 + port: 2525 + username: # Complete when Postal is running and you can + password: # generate the credentials within the interface. + from_name: Postal + from_address: example.com + + rails: + # This is generated automatically by the config initialization. It should be a random + # string unique to your installation. + secret_key: f1e4a061c0f3894a65d0335ce9d56ffa16c8b4d8dd2a101d875f703358790fc69b5a27f854dfff895b6d86cb9994ed8506e0cdec1a2cd5a1c840bf98b47431cd08de05e33a12f53219dcb795e4d72685647b40eb707555c242a1facc40b19c4cd3a35b0ca91507a672d3f7bce48a0dad81c930320001b22ba6fdc468f9a8ce08 + + web_server: + default_bind_address: 0.0.0.0 + +# openssl genrsa -out path/to/signing.key 2018 +signingKey: | + # paste key here + +web: + replicas: 1 + ingress: + enabled: true + className: nginx + annotations: + kubernetes.io/tls-acme: "true" + labels: {} + hosts: + - host: example.com + paths: + - path: / + pathType: ImplementationSpecific + tls: + - secretName: postal-web-tls + hosts: + - example.com + +smtp: + replicas: 1 + service: + type: LoadBalancer + loadBalancerIP: + +worker: + replicas: 1 \ No newline at end of file