From 1403e7ceaa46a3c8b82afa5d5e644785ddf72386 Mon Sep 17 00:00:00 2001 From: Mark Garratt Date: Sun, 15 Feb 2026 10:02:39 +0000 Subject: [PATCH 1/2] Fix proton-bridge default port wiring for Kubernetes --- charts/proton-bridge/Chart.yaml | 2 +- charts/proton-bridge/README.md | 2 +- charts/proton-bridge/templates/secret.yaml | 7 +++++++ charts/proton-bridge/values.yaml | 4 ++-- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/charts/proton-bridge/Chart.yaml b/charts/proton-bridge/Chart.yaml index a0fa9bd..133da02 100644 --- a/charts/proton-bridge/Chart.yaml +++ b/charts/proton-bridge/Chart.yaml @@ -2,5 +2,5 @@ apiVersion: v2 name: proton-bridge description: Proton Mail Bridge deployment for in-cluster SMTP/IMAP access type: application -version: 0.1.6 +version: 0.1.7 appVersion: "3.22.0" diff --git a/charts/proton-bridge/README.md b/charts/proton-bridge/README.md index b2c7379..f46992f 100644 --- a/charts/proton-bridge/README.md +++ b/charts/proton-bridge/README.md @@ -62,7 +62,7 @@ kubectl -n "$NAMESPACE" rollout status deploy/"$DEPLOYMENT" ## Defaults - Service type: `ClusterIP` -- Service ports: SMTP `25`, IMAP `143` (mapped to container ports `1025`/`1143` by default) +- Service ports: SMTP `25`, IMAP `143` (mapped to container ports `1026`/`1144` by default) - Image tag: `latest` - PVC: enabled, `ReadWriteOnce`, `2Gi` diff --git a/charts/proton-bridge/templates/secret.yaml b/charts/proton-bridge/templates/secret.yaml index 1ae5238..c20461c 100644 --- a/charts/proton-bridge/templates/secret.yaml +++ b/charts/proton-bridge/templates/secret.yaml @@ -1,3 +1,10 @@ +{{- $localBridgeHost := or (eq .Values.bridge.host "127.0.0.1") (eq .Values.bridge.host "localhost") (eq .Values.bridge.host "::1") -}} +{{- if and $localBridgeHost (eq (toString .Values.bridge.smtpPort) (toString .Values.container.smtpPort)) -}} +{{- fail "invalid proton-bridge values: bridge.smtpPort must differ from container.smtpPort when bridge.host is local" -}} +{{- end -}} +{{- if and $localBridgeHost (eq (toString .Values.bridge.imapPort) (toString .Values.container.imapPort)) -}} +{{- fail "invalid proton-bridge values: bridge.imapPort must differ from container.imapPort when bridge.host is local" -}} +{{- end -}} {{- if not .Values.existingSecret }} apiVersion: v1 kind: Secret diff --git a/charts/proton-bridge/values.yaml b/charts/proton-bridge/values.yaml index fe9341f..cddb711 100644 --- a/charts/proton-bridge/values.yaml +++ b/charts/proton-bridge/values.yaml @@ -32,8 +32,8 @@ bridge: mode: noninteractive container: - smtpPort: 1025 - imapPort: 1143 + smtpPort: 1026 + imapPort: 1144 # Set true to add NET_BIND_SERVICE capability so non-root process can bind <1024 (e.g. 25/143). enablePrivilegedPortBinding: false From 1724857b4bd7ce51c4581f7ea58310c24d12f233 Mon Sep 17 00:00:00 2001 From: Mark Garratt Date: Sun, 15 Feb 2026 10:10:14 +0000 Subject: [PATCH 2/2] Make proton-bridge port defaults upgrade-safe --- charts/proton-bridge/Chart.yaml | 2 +- charts/proton-bridge/README.md | 2 ++ .../proton-bridge/templates/deployment.yaml | 15 ++++++++++++-- charts/proton-bridge/templates/secret.yaml | 20 +++++++++++-------- 4 files changed, 28 insertions(+), 11 deletions(-) diff --git a/charts/proton-bridge/Chart.yaml b/charts/proton-bridge/Chart.yaml index 133da02..a67a80d 100644 --- a/charts/proton-bridge/Chart.yaml +++ b/charts/proton-bridge/Chart.yaml @@ -2,5 +2,5 @@ apiVersion: v2 name: proton-bridge description: Proton Mail Bridge deployment for in-cluster SMTP/IMAP access type: application -version: 0.1.7 +version: 0.1.8 appVersion: "3.22.0" diff --git a/charts/proton-bridge/README.md b/charts/proton-bridge/README.md index f46992f..2caa1d6 100644 --- a/charts/proton-bridge/README.md +++ b/charts/proton-bridge/README.md @@ -98,6 +98,8 @@ Common overrides: - `volumePermissions.enabled` - `existingSecret` +If `bridge.host` is local (`127.0.0.1`, `localhost`, `::1`) and `container.*Port` matches `bridge.*Port`, the chart automatically shifts container ports by `+1` to avoid bridge/socat bind conflicts during installs and upgrades. + To bind directly on container ports `25` and `143`, enable privileged port binding: ```yaml diff --git a/charts/proton-bridge/templates/deployment.yaml b/charts/proton-bridge/templates/deployment.yaml index 985b502..75b389a 100644 --- a/charts/proton-bridge/templates/deployment.yaml +++ b/charts/proton-bridge/templates/deployment.yaml @@ -29,6 +29,17 @@ spec: {{- $vpMountPath := (get $volumePermissions "mountPath" | default "/home/bridge") }} {{- $vpChown := (get $volumePermissions "chown" | default "1000:1000") }} {{- $vpChmod := (get $volumePermissions "chmod" | default "u+rwX,g+rwX") }} + {{- $localBridgeHost := or (eq .Values.bridge.host "127.0.0.1") (eq .Values.bridge.host "localhost") (eq .Values.bridge.host "::1") }} + {{- $bridgeSmtpPort := int .Values.bridge.smtpPort }} + {{- $bridgeImapPort := int .Values.bridge.imapPort }} + {{- $containerSmtpPort := int .Values.container.smtpPort }} + {{- $containerImapPort := int .Values.container.imapPort }} + {{- if and $localBridgeHost (eq $bridgeSmtpPort $containerSmtpPort) }} + {{- $containerSmtpPort = add $bridgeSmtpPort 1 }} + {{- end }} + {{- if and $localBridgeHost (eq $bridgeImapPort $containerImapPort) }} + {{- $containerImapPort = add $bridgeImapPort 1 }} + {{- end }} {{- with .Values.podSecurityContext }} securityContext: {{- toYaml . | nindent 8 }} @@ -85,10 +96,10 @@ spec: name: {{ include "proton-bridge.secretName" . }} ports: - name: smtp - containerPort: {{ .Values.container.smtpPort }} + containerPort: {{ $containerSmtpPort }} protocol: TCP - name: imap - containerPort: {{ .Values.container.imapPort }} + containerPort: {{ $containerImapPort }} protocol: TCP {{- if .Values.persistence.enabled }} volumeMounts: diff --git a/charts/proton-bridge/templates/secret.yaml b/charts/proton-bridge/templates/secret.yaml index c20461c..33eef78 100644 --- a/charts/proton-bridge/templates/secret.yaml +++ b/charts/proton-bridge/templates/secret.yaml @@ -1,9 +1,13 @@ {{- $localBridgeHost := or (eq .Values.bridge.host "127.0.0.1") (eq .Values.bridge.host "localhost") (eq .Values.bridge.host "::1") -}} -{{- if and $localBridgeHost (eq (toString .Values.bridge.smtpPort) (toString .Values.container.smtpPort)) -}} -{{- fail "invalid proton-bridge values: bridge.smtpPort must differ from container.smtpPort when bridge.host is local" -}} +{{- $bridgeSmtpPort := int .Values.bridge.smtpPort -}} +{{- $bridgeImapPort := int .Values.bridge.imapPort -}} +{{- $containerSmtpPort := int .Values.container.smtpPort -}} +{{- $containerImapPort := int .Values.container.imapPort -}} +{{- if and $localBridgeHost (eq $bridgeSmtpPort $containerSmtpPort) -}} +{{- $containerSmtpPort = add $bridgeSmtpPort 1 -}} {{- end -}} -{{- if and $localBridgeHost (eq (toString .Values.bridge.imapPort) (toString .Values.container.imapPort)) -}} -{{- fail "invalid proton-bridge values: bridge.imapPort must differ from container.imapPort when bridge.host is local" -}} +{{- if and $localBridgeHost (eq $bridgeImapPort $containerImapPort) -}} +{{- $containerImapPort = add $bridgeImapPort 1 -}} {{- end -}} {{- if not .Values.existingSecret }} apiVersion: v1 @@ -15,8 +19,8 @@ metadata: type: Opaque stringData: PROTON_BRIDGE_HOST: {{ .Values.bridge.host | quote }} - PROTON_BRIDGE_SMTP_PORT: {{ .Values.bridge.smtpPort | quote }} - PROTON_BRIDGE_IMAP_PORT: {{ .Values.bridge.imapPort | quote }} - CONTAINER_SMTP_PORT: {{ .Values.container.smtpPort | quote }} - CONTAINER_IMAP_PORT: {{ .Values.container.imapPort | quote }} + PROTON_BRIDGE_SMTP_PORT: {{ $bridgeSmtpPort | quote }} + PROTON_BRIDGE_IMAP_PORT: {{ $bridgeImapPort | quote }} + CONTAINER_SMTP_PORT: {{ $containerSmtpPort | quote }} + CONTAINER_IMAP_PORT: {{ $containerImapPort | quote }} {{- end }}