blob: 833a810f11524201924c95aaa3fc515e9ef49aa9 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
|
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 vault 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
- name: setup-pass
# Initializes GPG + pass on first run so Bridge v3 has a working keychain.
# All state is written to /bridge-data (the PVC) so it persists across restarts.
# No-op on subsequent starts (idempotency checks on pubring.kbx + password-store).
image: shenxn/protonmail-bridge:latest
command:
- /bin/sh
- -c
- |
export GNUPGHOME=/bridge-data/.gnupg
export PASSWORD_STORE_DIR=/bridge-data/.password-store
if [ ! -f "${GNUPGHOME}/pubring.kbx" ]; then
echo "First run: initializing GPG key..."
mkdir -p "${GNUPGHOME}" && chmod 700 "${GNUPGHOME}"
printf "allow-loopback-pinentry\n" > "${GNUPGHOME}/gpg-agent.conf"
printf "pinentry-mode loopback\n" > "${GNUPGHOME}/gpg.conf"
gpg --batch --gen-key <<'GPGEOF'
Key-Type: RSA
Key-Length: 2048
Name-Real: protonbridge
Name-Email: protonbridge@local
Expire-Date: 0
%no-protection
%commit
GPGEOF
echo "GPG key created."
fi
FINGERPRINT=$(gpg --list-secret-keys --with-colons 2>/dev/null | awk -F: '/^fpr/{print $10; exit}')
if [ -n "$FINGERPRINT" ] && [ ! -d "${PASSWORD_STORE_DIR}" ]; then
echo "Initializing pass with key $FINGERPRINT..."
pass init "$FINGERPRINT"
fi
echo "Pass setup complete."
volumeMounts:
- name: protonbridge-data
mountPath: /bridge-data
containers:
- name: protonbridge
# Bridge v3 CLI kept open with an attachable TTY so it can run headlessly.
#
# Session persists in pass on NFS PVC; subsequent restarts reconnect automatically.
#
# ACCOUNT LOGIN (when Bridge reports no active accounts):
# 1. Get pod name: kubectl get pod -n services -l app=protonbridge
# 2. Attach to the Bridge CLI: kubectl attach -it -n services <pod-name>
# 3. At the bridge> prompt, type 'login' and follow the prompts
# 4. Type 'quit'; the pod restarts and reconnects with the saved session
#
# EMAIL CLIENT SETUP (after login):
# IMAP: <any-r-vm-lan-ip>:30143, STARTTLS, accept self-signed cert
# SMTP: <any-r-vm-lan-ip>:30025, STARTTLS, accept self-signed cert
# Username: your ProtonMail address
# Password: bridge-generated password (from 'info' in the CLI above)
image: shenxn/protonmail-bridge:latest
stdin: true
tty: true
command:
- /bin/bash
- -c
- |
export GNUPGHOME=/bridge-data/.gnupg
export PASSWORD_STORE_DIR=/bridge-data/.password-store
apt-get update -qq
apt-get install -y -qq --no-install-recommends libfido2-1
socat TCP-LISTEN:25,fork TCP:127.0.0.1:1025 &
socat TCP-LISTEN:143,fork TCP:127.0.0.1:1143 &
exec protonmail-bridge --cli
env:
- name: GNUPGHOME
value: /bridge-data/.gnupg
- name: PASSWORD_STORE_DIR
value: /bridge-data/.password-store
ports:
- name: imap
containerPort: 1143
protocol: TCP
- name: smtp
containerPort: 1025
protocol: TCP
volumeMounts:
- name: protonbridge-data
mountPath: /bridge-data
- name: protonbridge-data
# Bridge writes its config (login tokens, account data) to ~/.config/protonmail.
# The container runs as root so HOME=/root; mount a subpath for the bridge config.
mountPath: /root/.config
subPath: dot-config
- name: protonbridge-data
# Persist Bridge's self-updated binary across pod restarts.
mountPath: /root/.local
subPath: dot-local
readinessProbe:
tcpSocket:
port: 1143
initialDelaySeconds: 30
periodSeconds: 15
startupProbe:
tcpSocket:
port: 1143
periodSeconds: 10
failureThreshold: 30
livenessProbe:
tcpSocket:
port: 1143
initialDelaySeconds: 60
periodSeconds: 30
volumes:
- name: protonbridge-data
persistentVolumeClaim:
claimName: protonbridge-data-pvc
|