diff options
| author | Paul Buetow <paul@buetow.org> | 2026-06-19 21:49:02 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-06-19 21:49:02 +0300 |
| commit | 9e4c0f14ceab7840ed35b49fd63397783b1c311f (patch) | |
| tree | d43a17e6b24f0df09c08591dc0a544108ae11002 | |
| parent | 61315b40a35c1ebe54619194507ab00657b91a57 (diff) | |
protonbridge: add k8s helm chart and ArgoCD app manifest
Deploys Proton Bridge (shenxn/protonmail-bridge) as a headless pod in the
services namespace. Config persisted on NFS-backed PVC; nfs-sentinel
initContainer guards against local-XFS shadow on NFS mount failure.
Exposes IMAP (STARTTLS) on NodePort 30143 and SMTP (STARTTLS) on NodePort
30025 for LAN access. Initial ProtonMail authentication is done once via:
kubectl exec -it <pod> -n services -- bridge --cli
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
| -rw-r--r-- | f3s/argocd-apps/services/protonbridge.yaml | 28 | ||||
| -rw-r--r-- | f3s/protonbridge/helm-chart/Chart.yaml | 5 | ||||
| -rw-r--r-- | f3s/protonbridge/helm-chart/templates/deployment.yaml | 70 | ||||
| -rw-r--r-- | f3s/protonbridge/helm-chart/templates/persistent-volumes.yaml | 27 | ||||
| -rw-r--r-- | f3s/protonbridge/helm-chart/templates/service.yaml | 24 |
5 files changed, 154 insertions, 0 deletions
diff --git a/f3s/argocd-apps/services/protonbridge.yaml b/f3s/argocd-apps/services/protonbridge.yaml new file mode 100644 index 0000000..3be5959 --- /dev/null +++ b/f3s/argocd-apps/services/protonbridge.yaml @@ -0,0 +1,28 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: protonbridge + namespace: cicd + finalizers: + - resources-finalizer.argocd.argoproj.io +spec: + project: default + source: + repoURL: http://git-server.cicd.svc.cluster.local/conf.git + targetRevision: master + path: f3s/protonbridge/helm-chart + destination: + server: https://kubernetes.default.svc + namespace: services + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=false + retry: + limit: 3 + backoff: + duration: 5s + factor: 2 + maxDuration: 1m diff --git a/f3s/protonbridge/helm-chart/Chart.yaml b/f3s/protonbridge/helm-chart/Chart.yaml new file mode 100644 index 0000000..7f63a13 --- /dev/null +++ b/f3s/protonbridge/helm-chart/Chart.yaml @@ -0,0 +1,5 @@ +apiVersion: v2 +name: protonbridge +description: A Helm chart for deploying Proton Bridge in headless mode. +version: 0.1.0 +appVersion: "latest" diff --git a/f3s/protonbridge/helm-chart/templates/deployment.yaml b/f3s/protonbridge/helm-chart/templates/deployment.yaml new file mode 100644 index 0000000..e32a234 --- /dev/null +++ b/f3s/protonbridge/helm-chart/templates/deployment.yaml @@ -0,0 +1,70 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: protonbridge + namespace: services +spec: + replicas: 1 + # Recreate so the old pod fully terminates before the new one starts — + # prevents two bridge instances racing for the same config/keychain on NFS. + strategy: + type: Recreate + selector: + matchLabels: + app: protonbridge + template: + metadata: + labels: + app: protonbridge + spec: + initContainers: + - name: nfs-check-data + image: busybox:stable + command: + - sh + - -c + - | + test -f /mnt/.nfs-sentinel || ( + echo "ERROR: NFS sentinel missing at /mnt/.nfs-sentinel" + echo "refusing to start; node likely has NFS unmounted" + echo "pod would otherwise bind-mount the local-XFS shadow" + exit 1 + ) + volumeMounts: + - name: protonbridge-data + mountPath: /mnt + readOnly: true + containers: + - name: protonbridge + # shenxn/protonmail-bridge runs the bridge in headless/noninteractive mode. + # On first start, authenticate interactively: + # kubectl exec -it <pod> -n services -- bridge --cli + # > login + # Credentials and session tokens are persisted to the data PVC so + # subsequent restarts reconnect automatically without re-login. + image: shenxn/protonmail-bridge:latest + ports: + - name: imap + containerPort: 1143 + protocol: TCP + - name: smtp + containerPort: 1025 + protocol: TCP + volumeMounts: + - name: protonbridge-data + # Bridge stores its config (tokens, keychain) under ~/.config/protonmail + mountPath: /home/protonmail/.config + readinessProbe: + tcpSocket: + port: 1143 + initialDelaySeconds: 30 + periodSeconds: 15 + livenessProbe: + tcpSocket: + port: 1143 + initialDelaySeconds: 60 + periodSeconds: 30 + volumes: + - name: protonbridge-data + persistentVolumeClaim: + claimName: protonbridge-data-pvc diff --git a/f3s/protonbridge/helm-chart/templates/persistent-volumes.yaml b/f3s/protonbridge/helm-chart/templates/persistent-volumes.yaml new file mode 100644 index 0000000..aa5cffe --- /dev/null +++ b/f3s/protonbridge/helm-chart/templates/persistent-volumes.yaml @@ -0,0 +1,27 @@ +apiVersion: v1 +kind: PersistentVolume +metadata: + name: protonbridge-data-pv +spec: + capacity: + storage: 1Gi + volumeMode: Filesystem + accessModes: + - ReadWriteOnce + persistentVolumeReclaimPolicy: Retain + hostPath: + path: /data/nfs/k3svolumes/protonbridge/data + type: Directory +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: protonbridge-data-pvc + namespace: services +spec: + storageClassName: "" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi diff --git a/f3s/protonbridge/helm-chart/templates/service.yaml b/f3s/protonbridge/helm-chart/templates/service.yaml new file mode 100644 index 0000000..3a389bb --- /dev/null +++ b/f3s/protonbridge/helm-chart/templates/service.yaml @@ -0,0 +1,24 @@ +apiVersion: v1 +kind: Service +metadata: + name: protonbridge + namespace: services +spec: + selector: + app: protonbridge + type: NodePort + ports: + - name: imap + protocol: TCP + port: 1143 + targetPort: 1143 + # NodePort 30143 — configure email clients as: + # IMAP server: <any-r-vm-lan-ip>:30143, STARTTLS, accept self-signed cert + nodePort: 30143 + - name: smtp + protocol: TCP + port: 1025 + targetPort: 1025 + # NodePort 30025 — configure email clients as: + # SMTP server: <any-r-vm-lan-ip>:30025, STARTTLS, accept self-signed cert + nodePort: 30025 |
