feat: redo chart

This commit is contained in:
Loïc Kalbermatter 2024-06-10 11:33:33 +02:00
parent 4c412899b1
commit e83b2d87f4
Signed by: PulseDev
GPG Key ID: 0516267FEC58F5F3
15 changed files with 68 additions and 762 deletions

View File

@ -3,7 +3,7 @@ name: stalwart-mail
description: Helm Chart for Stalwart Mail Server - Secure & Modern All-in-One Mail Server (IMAP, JMAP, SMTP) description: Helm Chart for Stalwart Mail Server - Secure & Modern All-in-One Mail Server (IMAP, JMAP, SMTP)
icon: https://stalw.art/home/apple-touch-icon.png icon: https://stalw.art/home/apple-touch-icon.png
type: application type: application
version: 0.0.2 version: 0.0.3
# renovate: image=docker.io/stalwartlabs/mail-server # renovate: image=docker.io/stalwartlabs/mail-server
appVersion: '0.8.1' appVersion: '0.8.1'
maintainers: maintainers:

124
README.md
View File

@ -1,6 +1,6 @@
# stalwart-mail # stalwart-mail
![Version: 0.0.2](https://img.shields.io/badge/Version-0.0.2-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.8.1](https://img.shields.io/badge/AppVersion-0.8.1-informational?style=flat-square) ![Version: 0.0.3](https://img.shields.io/badge/Version-0.0.3-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.8.1](https://img.shields.io/badge/AppVersion-0.8.1-informational?style=flat-square)
Helm Chart for Stalwart Mail Server - Secure & Modern All-in-One Mail Server (IMAP, JMAP, SMTP) Helm Chart for Stalwart Mail Server - Secure & Modern All-in-One Mail Server (IMAP, JMAP, SMTP)
@ -12,128 +12,26 @@ Helm Chart for Stalwart Mail Server - Secure & Modern All-in-One Mail Server (IM
## Values ## Values
### DKIM
| Key | Type | Default | Description | | Key | Type | Default | Description |
|-----|------|---------|-------------| |-----|------|---------|-------------|
| config.auth.dkim.sign | list | `[{"if":"listener != 'smtp'","then":"['rsa', 'ed25519']"},{"else":false}]` | auth rule for signing with dkim |
| config.auth.dkim.verify | string | `"relaxed"` | verify of dkim signature (relaxed, strict, disable) |
### Authentification
| Key | Type | Default | Description |
|-----|------|---------|-------------|
| config.authentication.fallback-admin.secret | string | `"%{env:FALLBACK_ADMIN_SECRET}%"` | password for fallback authentfication (use env for store in secrets of kubernetes) |
| config.authentication.fallback-admin.user | string | `"admin"` | username for fallback authentfication |
| secrets.env.FALLBACK_ADMIN_SECRET | string | `"supersecret"` | password for fallback authentfication (env) |
### Other Values
| Key | Type | Default | Description |
|-----|------|---------|-------------|
| affinity | object | `{}` | |
| autoscaling.enabled | bool | `false` | |
| autoscaling.maxReplicas | int | `100` | |
| autoscaling.minReplicas | int | `1` | |
| autoscaling.targetCPUUtilizationPercentage | int | `80` | |
| certificate.certmanager.dnsNames[0] | string | `"chart-example.local"` | |
| certificate.certmanager.enabled | bool | `true` | |
| certificate.certmanager.issuerRef.group | string | `"cert-manager.io"` | |
| certificate.certmanager.issuerRef.kind | string | `"ClusterIssuer"` | |
| certificate.certmanager.issuerRef.name | string | `"letsencrypt-prod"` | |
| certificate.secretName | string | `nil` | not needed if certmanager is used |
| config.directory.internal.store | string | `"rocksdb"` | |
| config.directory.internal.type | string | `"internal"` | |
| config.server.listener.https.bind[0] | string | `"[::]:80"` | |
| config.server.listener.https.protocol | string | `"http"` | |
| config.server.listener.https.tls.implicit | bool | `true` | |
| config.server.listener.imap.bind[0] | string | `"[::]:143"` | |
| config.server.listener.imap.protocol | string | `"imap"` | |
| config.server.listener.imaptls.bind[0] | string | `"[::]:993"` | |
| config.server.listener.imaptls.protocol | string | `"imap"` | |
| config.server.listener.imaptls.tls.implicit | bool | `true` | |
| config.server.listener.sieve.bind[0] | string | `"[::]:4190"` | |
| config.server.listener.sieve.protocol | string | `"managesieve"` | |
| config.server.listener.smtp.bind[0] | string | `"[::]:25"` | |
| config.server.listener.smtp.protocol | string | `"smtp"` | |
| config.server.listener.submission.bind[0] | string | `"[::]:587"` | |
| config.server.listener.submission.protocol | string | `"smtp"` | |
| config.server.listener.submissions.bind[0] | string | `"[::]:465"` | |
| config.server.listener.submissions.protocol | string | `"smtp"` | |
| config.server.listener.submissions.tls.implicit | bool | `true` | |
| config.server.run-as.group | string | `"stalwart-mail"` | server run-as group |
| config.server.run-as.user | string | `"stalwart-mail"` | server run-as user |
| config.storage.blob | string | `"rocksdb"` | |
| config.storage.data | string | `"rocksdb"` | |
| config.storage.directory | string | `"internal"` | |
| config.storage.fts | string | `"rocksdb"` | |
| config.storage.lookup | string | `"rocksdb"` | |
| config.store.rocksdb.compression | string | `"lz4"` | |
| config.store.rocksdb.path | string | `"/data"` | |
| config.store.rocksdb.type | string | `"rocksdb"` | |
| config.tracer.otel.enable | bool | `false` | |
| config.tracer.otel.endpoint | string | `"https://127.0.0.1/otel"` | |
| config.tracer.otel.headers | list | `[]` | headers for usage with http (e.g. 'Authorization: <place_auth_here>') |
| config.tracer.otel.level | string | `"info"` | |
| config.tracer.otel.transport | string | `"grpc"` | grpc or http |
| config.tracer.otel.type | string | `"open-telemetry"` | |
| config.tracer.stdout.ansi | bool | `false` | |
| config.tracer.stdout.enable | bool | `true` | |
| config.tracer.stdout.level | string | `"info"` | |
| config.tracer.stdout.type | string | `"stdout"` | |
| env | list | `[]` | |
| fullnameOverride | string | `""` | |
| global.image.pullPolicy | string | `nil` | if set it will overwrite all pullPolicy |
| global.image.registry | string | `nil` | if set it will overwrite all registry entries |
| image.pullPolicy | string | `"IfNotPresent"` | | | image.pullPolicy | string | `"IfNotPresent"` | |
| image.registry | string | `"docker.io"` | |
| image.repository | string | `"stalwartlabs/mail-server"` | | | image.repository | string | `"stalwartlabs/mail-server"` | |
| image.tag | string | `""` | Overrides the image tag whose default is the chart appVersion. | | image.tag | string | `""` | |
| imagePullSecrets | list | `[]` | | | persistence.accessMode | string | `"ReadWriteOnce"` | |
| ingress.annotations | object | `{}` | | | persistence.enabled | bool | `true` | |
| ingress.className | string | `""` | | | persistence.mountPath | string | `"/opt/stalwart-mail"` | |
| ingress.enabled | bool | `false` | | | persistence.size | string | `"10Gi"` | |
| ingress.hosts[0].host | string | `"chart-example.local"` | | | persistence.storageClass | string | `"standard"` | |
| ingress.hosts[0].paths[0].path | string | `"/"` | |
| ingress.hosts[0].paths[0].pathType | string | `"ImplementationSpecific"` | |
| ingress.tls | list | `[]` | |
| nameOverride | string | `""` | |
| nodeSelector | object | `{}` | |
| persistence.accessMode | string | `"ReadWriteOnce"` | accessMode |
| persistence.annotations | object | `{}` | |
| persistence.enabled | bool | `true` | Enable persistence using Persistent Volume Claims ref: http://kubernetes.io/docs/user-guide/persistent-volumes/ |
| persistence.existingClaim | string | `nil` | A manually managed Persistent Volume and Claim Requires persistence.enabled: true If defined, PVC must be created manually before volume will be bound |
| persistence.hostPath | string | `nil` | Do not create an PVC, direct use hostPath in Pod |
| persistence.size | string | `"10Gi"` | size |
| persistence.storageClass | string | `nil` | Persistent Volume Storage Class If defined, storageClassName: <storageClass> If set to "-", storageClassName: "", which disables dynamic provisioning If undefined (the default) or set to null, no storageClassName spec is set, choosing the default provisioner. (gp2 on AWS, standard on GKE, AWS & OpenStack) |
| podAnnotations | object | `{}` | |
| podLabels | object | `{}` | |
| podSecurityContext | object | `{}` | |
| replicaCount | int | `1` | | | replicaCount | int | `1` | |
| resources | object | `{}` | | | service.ports.http | int | `8080` | |
| securityContext | object | `{}` | | | service.ports.https | int | `443` | |
| service.annotations | object | `{}` | |
| service.ipFamilies[0] | string | `"IPv4"` | |
| service.ipFamilyPolicy | string | `"SingleStack"` | other option is RequireDualStack |
| service.ports.http | int | `80` | |
| service.ports.imap | int | `143` | | | service.ports.imap | int | `143` | |
| service.ports.imaps | int | `993` | | | service.ports.imaps | int | `993` | |
| service.ports.sieve | int | `4190` | | | service.ports.sieve | int | `4190` | |
| service.ports.smtp | int | `25` | | | service.ports.smtp | int | `25` | |
| service.ports.smtp-submission | int | `587` | |
| service.ports.smtps | int | `465` | | | service.ports.smtps | int | `465` | |
| service.type | string | `"ClusterIP"` | | | service.ports.submission | int | `587` | |
| serviceAccount.annotations | object | `{}` | | | service.type | string | `"NodePort"` | |
| serviceAccount.automount | bool | `true` | |
| serviceAccount.create | bool | `false` | |
| serviceAccount.name | string | `""` | |
| tolerations | list | `[]` | |
| traefik.enabled | bool | `false` | |
| traefik.ports.http | string | `"websecure"` | |
| traefik.ports.imaps | string | `"imaps"` | |
| traefik.ports.smtps | string | `"smtps"` | |
| volumeMounts | list | `[]` | |
| volumes | list | `[]` | |
---------------------------------------------- ----------------------------------------------
Autogenerated from chart metadata using [helm-docs v1.13.1](https://github.com/norwoodj/helm-docs/releases/v1.13.1) Autogenerated from chart metadata using [helm-docs v1.13.1](https://github.com/norwoodj/helm-docs/releases/v1.13.1)

View File

@ -1,22 +0,0 @@
1. Get the application URL by running these commands:
{{- if .Values.ingress.enabled }}
{{- range $host := .Values.ingress.hosts }}
{{- range .paths }}
http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ .path }}
{{- end }}
{{- end }}
{{- else if contains "NodePort" .Values.service.type }}
export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "stalwart-mail.fullname" . }})
export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
echo http://$NODE_IP:$NODE_PORT
{{- else if contains "LoadBalancer" .Values.service.type }}
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "stalwart-mail.fullname" . }}'
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "stalwart-mail.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
echo http://$SERVICE_IP:{{ .Values.service.port }}
{{- else if contains "ClusterIP" .Values.service.type }}
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "stalwart-mail.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}")
echo "Visit http://127.0.0.1:8080 to use your application"
kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT
{{- end }}

View File

@ -1,62 +0,0 @@
{{/*
Expand the name of the chart.
*/}}
{{- define "stalwart-mail.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).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "stalwart-mail.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $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 }}
{{- end }}
{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "stalwart-mail.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Common labels
*/}}
{{- define "stalwart-mail.labels" -}}
helm.sh/chart: {{ include "stalwart-mail.chart" . }}
{{ include "stalwart-mail.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}
{{/*
Selector labels
*/}}
{{- define "stalwart-mail.selectorLabels" -}}
app.kubernetes.io/name: {{ include "stalwart-mail.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}
{{/*
Create the name of the service account to use
*/}}
{{- define "stalwart-mail.serviceAccountName" -}}
{{- if .Values.serviceAccount.create }}
{{- default (include "stalwart-mail.fullname" .) .Values.serviceAccount.name }}
{{- else }}
{{- default "default" .Values.serviceAccount.name }}
{{- end }}
{{- end }}

View File

@ -1,15 +0,0 @@
{{- with .Values.certificate.certmanager }}
{{- if and .enabled (not $.Values.certificate.secretName) ($.Capabilities.APIVersions.Has "cert-manager.io/v1/Certificate") }}
---
apiVersion: "cert-manager.io/v1"
kind: Certificate
metadata:
name: {{ include "stalwart-mail.fullname" $ }}
spec:
secretName: {{ include "stalwart-mail.fullname" $ }}-cert
issuerRef:
{{- toYaml .issuerRef | nindent 4 }}
dnsNames:
{{- toYaml .dnsNames | nindent 4 }}
{{- end }}{{/* end-if .enabled */}}
{{- end }}{{/* end-with .certificates */}}

View File

@ -1,9 +0,0 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ include "stalwart-mail.fullname" . }}
labels:
{{ include "stalwart-mail.labels" . | nindent 4 }}
data:
config.toml: |
{{ toToml .Values.config | replace ".0\n" "\n" | nindent 4 }}

View File

@ -1,117 +1,33 @@
apiVersion: apps/v1 apiVersion: apps/v1
kind: Deployment kind: Deployment
metadata: metadata:
name: {{ include "stalwart-mail.fullname" . }} name: { { include "stalwart-mail.fullname" . } }
labels: labels: { { - include "stalwart-mail.labels" . | nindent 4 } }
{{- include "stalwart-mail.labels" . | nindent 4 }}
spec: spec:
{{- if not .Values.autoscaling.enabled }} replicas: { { .Values.replicaCount } }
replicas: {{ .Values.replicaCount }}
{{- end }}
selector: selector:
matchLabels: matchLabels: { { - include "stalwart-mail.selectorLabels" . | nindent 6 } }
{{- include "stalwart-mail.selectorLabels" . | nindent 6 }}
template: template:
metadata: metadata:
annotations: labels: { { - include "stalwart-mail.selectorLabels" . | nindent 8 } }
config-hash: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}
secret-env-hash: {{ include (print $.Template.BasePath "/secrets-env.yaml") . | sha256sum }}
{{- with .Values.podAnnotations }}
{{- toYaml . | nindent 8 }}
{{- end }}
labels:
{{- include "stalwart-mail.labels" . | nindent 8 }}
{{- with .Values.podLabels }}
{{- toYaml . | nindent 8 }}
{{- end }}
spec: spec:
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
serviceAccountName: {{ include "stalwart-mail.serviceAccountName" . }}
securityContext:
{{- toYaml .Values.podSecurityContext | nindent 8 }}
containers: containers:
- name: {{ .Chart.Name }} - name: stalwart-mail
securityContext: image: '{{ .Values.image.repository }}:{{ .Values.image.tag }}'
{{- toYaml .Values.securityContext | nindent 12 }} imagePullPolicy: { { .Values.image.pullPolicy } }
{{- with .Values.image}}
image: "{{ coalesce $.Values.global.image.registry .registry }}/{{ .repository }}:{{ .tag | default (printf "v%s" $.Chart.AppVersion) }}"
imagePullPolicy: {{ coalesce $.Values.global.image.pullPolicy .pullPolicy }}
{{- end }}
{{- with .Values.env }}
env:
{{- toYaml . | nindent 12 }}
{{- end }}
envFrom:
- secretRef:
name: {{ include "stalwart-mail.fullname" . }}-env
ports: ports:
{{- range $name, $port := .Values.service.ports }} - containerPort: 8080
- name: {{ $name }} - containerPort: 443
containerPort: {{ $port }} - containerPort: 25
protocol: TCP - containerPort: 587
{{- end }} - containerPort: 465
resources: - containerPort: 143
{{- toYaml .Values.resources | nindent 12 }} - containerPort: 993
- containerPort: 4190
volumeMounts: volumeMounts:
- name: data - name: stalwart-volume
mountPath: "/data" mountPath: { { .Values.persistence.mountPath } }
- name: data
mountPath: "/data/blobs"
subPath: "blobs"
- name: data
mountPath: "/data/queue"
subPath: "queue"
- name: data
mountPath: "/data/reports"
subPath: reports
- name: config
mountPath: "/opt/stalwart-mail/etc/config.toml"
subPath: "config.toml"
readOnly: false
{{- if or .Values.certificate.secretName .Values.certificate.certmanager.enabled }}
- name: certificate
mountPath: "/opt/stalwart-mail/etc/certs"
{{- end }}
{{- with .Values.volumeMounts }}
{{- toYaml . | nindent 12 }}
{{- end }}
volumes: volumes:
- name: "config" - name: stalwart-volume
configMap:
name: {{ include "stalwart-mail.fullname" . }}
{{- if or .Values.certificate.secretName .Values.certificate.certmanager.enabled }}
- name: certificate
secret:
secretName: {{ .Values.certificate.secretName | default (printf "%s-cert" (include "stalwart-mail.fullname" .)) }}
{{- end }}
- name: "data"
{{- if .Values.persistence.enabled }}
{{- if .Values.persistence.hostPath }}
hostPath:
type: Directory
path: {{ .Values.persistence.hostPath | quote }}
{{- else }}{{/* else .persistence.hostPath */}}
persistentVolumeClaim: persistentVolumeClaim:
claimName: {{ coalesce .Values.persistence.existingClaim (include "stalwart-mail.fullname" .) }} claimName: { { include "stalwart-mail.fullname" . } }
{{- end }}{{/* end-else .persistence.hostPath */}}
{{- else }}{{/* else .persistence.enabled */}}
emptyDir: {}
{{- end }}{{/* end-else .persistence.enabled */}}
{{- with .Values.volumes }}
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.affinity }}
affinity:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.tolerations }}
tolerations:
{{- toYaml . | nindent 8 }}
{{- end }}

View File

@ -1,32 +0,0 @@
{{- if .Values.autoscaling.enabled }}
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: {{ include "stalwart-mail.fullname" . }}
labels:
{{- include "stalwart-mail.labels" . | nindent 4 }}
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: {{ include "stalwart-mail.fullname" . }}
minReplicas: {{ .Values.autoscaling.minReplicas }}
maxReplicas: {{ .Values.autoscaling.maxReplicas }}
metrics:
{{- if .Values.autoscaling.targetCPUUtilizationPercentage }}
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }}
{{- end }}
{{- if .Values.autoscaling.targetMemoryUtilizationPercentage }}
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }}
{{- end }}
{{- end }}

View File

@ -1,61 +0,0 @@
{{- if .Values.ingress.enabled -}}
{{- $fullName := include "stalwart-mail.fullname" . -}}
{{- $svcPort := .Values.service.ports.http -}}
{{- if and .Values.ingress.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }}
{{- if not (hasKey .Values.ingress.annotations "kubernetes.io/ingress.class") }}
{{- $_ := set .Values.ingress.annotations "kubernetes.io/ingress.class" .Values.ingress.className}}
{{- end }}
{{- end }}
{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion -}}
apiVersion: networking.k8s.io/v1
{{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}}
apiVersion: networking.k8s.io/v1beta1
{{- else -}}
apiVersion: extensions/v1beta1
{{- end }}
kind: Ingress
metadata:
name: {{ $fullName }}
labels:
{{- include "stalwart-mail.labels" . | nindent 4 }}
{{- with .Values.ingress.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{- if and .Values.ingress.className (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }}
ingressClassName: {{ .Values.ingress.className }}
{{- end }}
{{- if .Values.ingress.tls }}
tls:
{{- range .Values.ingress.tls }}
- hosts:
{{- range .hosts }}
- {{ . | quote }}
{{- end }}
secretName: {{ .secretName }}
{{- end }}
{{- end }}
rules:
{{- range .Values.ingress.hosts }}
- host: {{ .host | quote }}
http:
paths:
{{- range .paths }}
- path: {{ .path }}
{{- if and .pathType (semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion) }}
pathType: {{ .pathType }}
{{- end }}
backend:
{{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }}
service:
name: {{ $fullName }}
port:
number: {{ $svcPort }}
{{- else }}
serviceName: {{ $fullName }}
servicePort: {{ $svcPort }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}

View File

@ -1,28 +0,0 @@
{{- with .Values.persistence }}
{{- if and .enabled (not .existingClaim) }}
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: {{ template "stalwart-mail.fullname" $ }}
labels:
{{- include "stalwart-mail.labels" $ | nindent 4 }}
{{- with .annotations }}
annotations:
{{ toYaml . | indent 4 }}
{{- end }}
spec:
accessModes:
- {{ .accessMode | quote }}
resources:
requests:
storage: {{ .size | quote }}
{{- with .storageClass }}
{{- if (eq "-" .) }}
storageClassName: ""
{{- else }}
storageClassName: {{ . | quote }}
{{- end }}
{{- end }}
{{- end }}{{/* end-if .enabled */}}
{{- end }}{{/* end-with .persistence */}}

View File

@ -1,11 +0,0 @@
---
apiVersion: v1
kind: Secret
metadata:
name: {{ include "stalwart-mail.fullname" . }}-env
labels:
{{- include "stalwart-mail.labels" . | nindent 4 }}
data:
{{- range $key, $value := .Values.secrets.env }}
{{ $key }}: {{ $value | b64enc }}
{{- end }}

View File

@ -1,26 +1,33 @@
apiVersion: v1 apiVersion: v1
kind: Service kind: Service
metadata: metadata:
name: {{ include "stalwart-mail.fullname" . }} name: { { include "stalwart-mail.fullname" . } }
labels: labels: { { - include "stalwart-mail.labels" . | nindent 4 } }
{{- include "stalwart-mail.labels" . | nindent 4 }}
{{- with .Values.service.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec: spec:
{{- with .Values.service }} type: { { .Values.service.type } }
type: {{ .type }}
ipFamilyPolicy: {{ .ipFamilyPolicy }}
ipFamilies:
{{- toYaml .ipFamilies | nindent 4 }}
ports: ports:
{{- range $name, $port := .ports }} - name: http
- port: {{ $port }} port: 8080
targetPort: {{ $name }} targetPort: 8080
protocol: TCP - name: https
name: {{ $name }} port: 443
{{- end }} targetPort: 443
{{- end }}{{/* end-with .service */}} - name: smtp
selector: port: 25
{{- include "stalwart-mail.selectorLabels" . | nindent 4 }} targetPort: 25
- name: submission
port: 587
targetPort: 587
- name: smtps
port: 465
targetPort: 465
- name: imap
port: 143
targetPort: 143
- name: imaps
port: 993
targetPort: 993
- name: sieve
port: 4190
targetPort: 4190
selector: { { - include "stalwart-mail.selectorLabels" . | nindent 4 } }

View File

@ -1,13 +0,0 @@
{{- if .Values.serviceAccount.create -}}
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ include "stalwart-mail.serviceAccountName" . }}
labels:
{{- include "stalwart-mail.labels" . | nindent 4 }}
{{- with .Values.serviceAccount.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
automountServiceAccountToken: {{ .Values.serviceAccount.automount }}
{{- end }}

View File

@ -1,21 +0,0 @@
{{- if .Values.traefik.enabled }}
{{- range $port,$entryport := .Values.traefik.ports }}
---
apiVersion: traefik.io/v1alpha1
kind: IngressRouteTCP
metadata:
name: {{ include "stalwart-mail.fullname" $ }}-{{ $port }}
spec:
entryPoints:
- {{ $entryport }}
routes:
- match: HostSNI(`{{ $.Values.traefik.host }}`)
services:
- name: {{ include "stalwart-mail.fullname" $ }}
port: {{ $port }}
proxyProtocol:
version: 2
tls:
passthrough: true
{{- end }}
{{- end }}{{/* end-if .enabled */}}

View File

@ -1,266 +1,25 @@
# Default values for stalwart.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
global:
image:
# -- if set it will overwrite all registry entries
registry:
# -- if set it will overwrite all pullPolicy
pullPolicy:
replicaCount: 1
image: image:
registry: docker.io
repository: stalwartlabs/mail-server repository: stalwartlabs/mail-server
pullPolicy: IfNotPresent pullPolicy: IfNotPresent
# -- Overrides the image tag whose default is the chart appVersion.
tag: '' tag: ''
imagePullSecrets: []
nameOverride: ''
fullnameOverride: ''
config:
server:
listener:
smtp:
bind: ['[::]:25']
protocol: 'smtp'
submission:
bind: ['[::]:587']
protocol: 'smtp'
submissions:
bind: ['[::]:465']
protocol: 'smtp'
tls:
implicit: true
imap:
bind: ['[::]:143']
protocol: 'imap'
imaptls:
bind: ['[::]:993']
protocol: 'imap'
tls:
implicit: true
sieve:
bind: ['[::]:4190']
protocol: 'managesieve'
https:
protocol: 'http'
bind: ['[::]:80']
tls:
implicit: true
run-as:
# -- server run-as user
user: 'stalwart-mail'
# -- server run-as group
group: 'stalwart-mail'
storage:
data: 'rocksdb'
fts: 'rocksdb'
blob: 'rocksdb'
lookup: 'rocksdb'
directory: 'internal'
store:
rocksdb:
type: rocksdb
path: '/data'
compression: 'lz4'
directory:
internal:
type: 'internal'
store: 'rocksdb'
tracer:
otel:
enable: false
type: 'open-telemetry'
level: 'info'
# -- grpc or http
transport: 'grpc'
endpoint: 'https://127.0.0.1/otel'
# -- headers for usage with http (e.g. 'Authorization: <place_auth_here>')
headers: []
stdout:
enable: true
type: 'stdout'
level: 'info'
ansi: false
auth:
dkim:
# -- auth rule for signing with dkim
# @section -- DKIM
sign:
- if: "listener != 'smtp'"
then: "['rsa', 'ed25519']"
- else: false
# -- verify of dkim signature (relaxed, strict, disable)
# @section -- DKIM
verify: 'relaxed'
authentication:
fallback-admin:
# -- username for fallback authentfication
# @section -- Authentification
user: 'admin'
# -- password for fallback authentfication (use env for store in secrets of kubernetes)
# @section -- Authentification
secret: '%{env:FALLBACK_ADMIN_SECRET}%'
secrets:
env:
# -- password for fallback authentfication (env)
# @section -- Authentification
FALLBACK_ADMIN_SECRET: supersecret
serviceAccount:
# Specifies whether a service account should be created
create: false
# Automatically mount a ServiceAccount's API credentials?
automount: true
# Annotations to add to the service account
annotations: {}
# The name of the service account to use.
# If not set and create is true, a name is generated using the fullname template
name: ''
podAnnotations: {}
podLabels: {}
env: []
podSecurityContext:
{}
# fsGroup: 2000
securityContext:
{}
# capabilities:
# drop:
# - ALL
# readOnlyRootFilesystem: true
# runAsNonRoot: true
# runAsUser: 1000
service: service:
type: ClusterIP type: NodePort
ipFamilies: ['IPv4']
# -- other option is RequireDualStack
ipFamilyPolicy: 'SingleStack'
annotations: {}
ports: ports:
http: 8080
https: 443
smtp: 25 smtp: 25
smtp-submission: 587 submission: 587
smtps: 465 smtps: 465
imap: 143 imap: 143
imaps: 993 imaps: 993
sieve: 4190 sieve: 4190
http: 80
ingress:
enabled: false
className: ''
annotations:
{}
# kubernetes.io/ingress.class: nginx
# kubernetes.io/tls-acme: "true"
hosts:
- host: chart-example.local
paths:
- path: /
pathType: ImplementationSpecific
tls: []
# - secretName: chart-example-tls
# hosts:
# - chart-example.local
traefik:
enabled: false
ports:
http: websecure
imaps: imaps
smtps: smtps
certificate:
# -- not needed if certmanager is used
secretName:
certmanager:
enabled: true
issuerRef:
group: cert-manager.io
kind: ClusterIssuer
name: letsencrypt-prod
dnsNames:
- 'chart-example.local'
resources:
{}
# We usually recommend not to specify default resources and to leave this as a conscious
# choice for the user. This also increases chances charts run on environments with little
# resources, such as Minikube. If you do want to specify resources, uncomment the following
# lines, adjust them as necessary, and remove the curly braces after 'resources:'.
# limits:
# cpu: 100m
# memory: 128Mi
# requests:
# cpu: 100m
# memory: 128Mi
autoscaling:
enabled: false
minReplicas: 1
maxReplicas: 100
targetCPUUtilizationPercentage: 80
# targetMemoryUtilizationPercentage: 80
# Additional volumes on the output Deployment definition.
volumes: []
# - name: foo
# secret:
# secretName: mysecret
# optional: false
# Additional volumeMounts on the output Deployment definition.
volumeMounts: []
# - name: foo
# mountPath: "/etc/foo"
# readOnly: true
nodeSelector: {}
tolerations: []
affinity: {}
persistence: persistence:
# -- Enable persistence using Persistent Volume Claims
# ref: http://kubernetes.io/docs/user-guide/persistent-volumes/
enabled: true enabled: true
annotations: {} storageClass: 'standard'
# -- Persistent Volume Storage Class
# If defined, storageClassName: <storageClass>
# If set to "-", storageClassName: "", which disables dynamic provisioning
# If undefined (the default) or set to null, no storageClassName spec is
# set, choosing the default provisioner. (gp2 on AWS, standard on
# GKE, AWS & OpenStack)
storageClass:
# -- A manually managed Persistent Volume and Claim
# Requires persistence.enabled: true
# If defined, PVC must be created manually before volume will be bound
existingClaim:
# -- Do not create an PVC, direct use hostPath in Pod
hostPath:
# -- accessMode
accessMode: ReadWriteOnce accessMode: ReadWriteOnce
# -- size
size: 10Gi size: 10Gi
mountPath: /opt/stalwart-mail
replicaCount: 1