diff --git a/charts/proton-bridge/Chart.yaml b/charts/proton-bridge/Chart.yaml index ae58870..4933c0c 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.4 +version: 0.1.5 appVersion: "3.22.0" diff --git a/charts/proton-bridge/README.md b/charts/proton-bridge/README.md index a3923ee..ccb8ec8 100644 --- a/charts/proton-bridge/README.md +++ b/charts/proton-bridge/README.md @@ -94,6 +94,9 @@ Common overrides: - `bridge.host`, `bridge.smtpPort`, `bridge.imapPort` - `container.smtpPort`, `container.imapPort` - `container.enablePrivilegedPortBinding` +- `podSecurityContext.fsGroup` +- `containerSecurityContext` +- `volumePermissions.enabled` - `existingSecret` To bind directly on container ports `25` and `143`, enable privileged port binding: @@ -104,3 +107,20 @@ container: imapPort: 143 enablePrivilegedPortBinding: true ``` + +## Troubleshooting Startup Permission Errors + +If the container cannot write under `/home/bridge` at startup, set a pod `fsGroup` so Kubernetes adjusts volume group ownership: + +```yaml +podSecurityContext: + fsGroup: 1000 +``` + +If your storage backend still needs explicit ownership fixes, enable the permissions init container: + +```yaml +volumePermissions: + enabled: true + chown: "1000:1000" +``` diff --git a/charts/proton-bridge/templates/deployment.yaml b/charts/proton-bridge/templates/deployment.yaml index 76804b3..985b502 100644 --- a/charts/proton-bridge/templates/deployment.yaml +++ b/charts/proton-bridge/templates/deployment.yaml @@ -22,19 +22,57 @@ spec: {{- toYaml . | nindent 8 }} {{- end }} spec: + {{- $volumePermissions := .Values.volumePermissions | default dict }} + {{- $volumePermissionsEnabled := (get $volumePermissions "enabled" | default false) }} + {{- $vpImage := (get $volumePermissions "image" | default dict) }} + {{- $vpSecurityContext := (get $volumePermissions "securityContext") }} + {{- $vpMountPath := (get $volumePermissions "mountPath" | default "/home/bridge") }} + {{- $vpChown := (get $volumePermissions "chown" | default "1000:1000") }} + {{- $vpChmod := (get $volumePermissions "chmod" | default "u+rwX,g+rwX") }} + {{- with .Values.podSecurityContext }} + securityContext: + {{- toYaml . | nindent 8 }} + {{- end }} {{- with .Values.imagePullSecrets }} imagePullSecrets: {{- toYaml . | nindent 8 }} {{- end }} + {{- if and .Values.persistence.enabled $volumePermissionsEnabled }} + initContainers: + - name: volume-permissions + image: "{{ (get $vpImage "repository" | default "busybox") }}:{{ (get $vpImage "tag" | default "1.37.0") }}" + imagePullPolicy: {{ (get $vpImage "pullPolicy" | default "IfNotPresent") }} + {{- with $vpSecurityContext }} + securityContext: + {{- toYaml . | nindent 12 }} + {{- end }} + command: + - /bin/sh + - -ec + - >- + chown -R {{ $vpChown }} {{ $vpMountPath }} + && chmod -R {{ $vpChmod }} {{ $vpMountPath }} + volumeMounts: + - name: bridge-data + mountPath: {{ $vpMountPath }} + {{- end }} containers: - name: proton-bridge image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" imagePullPolicy: {{ .Values.image.pullPolicy }} + {{- $containerSecurityContext := deepCopy (.Values.containerSecurityContext | default dict) }} {{- if .Values.container.enablePrivilegedPortBinding }} + {{- $capabilities := get $containerSecurityContext "capabilities" | default dict }} + {{- $add := get $capabilities "add" | default (list) }} + {{- if not (has "NET_BIND_SERVICE" $add) }} + {{- $add = append $add "NET_BIND_SERVICE" }} + {{- end }} + {{- $capabilities = mergeOverwrite $capabilities (dict "add" $add) }} + {{- $containerSecurityContext = mergeOverwrite $containerSecurityContext (dict "capabilities" $capabilities) }} + {{- end }} + {{- if $containerSecurityContext }} securityContext: - capabilities: - add: - - NET_BIND_SERVICE + {{- toYaml $containerSecurityContext | nindent 12 }} {{- end }} env: - name: BRIDGE_MODE diff --git a/charts/proton-bridge/values.yaml b/charts/proton-bridge/values.yaml index f42f3a3..9a84164 100644 --- a/charts/proton-bridge/values.yaml +++ b/charts/proton-bridge/values.yaml @@ -37,6 +37,26 @@ container: # Set true to add NET_BIND_SERVICE capability so non-root process can bind <1024 (e.g. 25/143). enablePrivilegedPortBinding: false +# Pod-level security context (for example: fsGroup to allow writing mounted volumes). +podSecurityContext: {} + +# Container-level security context for the main proton-bridge container. +containerSecurityContext: {} + +# Optional init container to force volume ownership/permissions before bridge starts. +volumePermissions: + enabled: false + image: + repository: busybox + tag: "1.37.0" + pullPolicy: IfNotPresent + securityContext: + runAsUser: 0 + runAsGroup: 0 + mountPath: /home/bridge + chown: "1000:1000" + chmod: "u+rwX,g+rwX" + existingSecret: "" secretName: ""