Commit graph

8 commits

Author SHA1 Message Date
CTO Agent
d8cd3638fa Fix Stalwart backup CronJob to handle ReadWriteOnce PVC
Implement scale-down/backup/scale-up pattern to work around PVC access mode limitation.

Changes:
- Add RBAC (ServiceAccount, Role, RoleBinding) with statefulsets/scale and pods permissions
- Switch to alpine:3.19 base image with kubectl and restic
- Scale down StatefulSet to 0 replicas before backup
- Run restic backup while pod is stopped
- Scale back up to 1 replica with error handling
- Add cleanup trap to ensure scale-up even on failure
- Set 10-minute timeout and backoff limit

Tested successfully: backup completes in ~32 seconds with minimal downtime.
Resolves DEV-236.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-07-11 11:21:39 +00:00
CTO Agent
b0f2acf5f3 Stalwart reliability hardening: fix k3s service networking issues
Root cause: k3s service ClusterIP routing instability causing intermittent
failures despite healthy pods. This is the 5th incident - prior fixes treated
symptoms, not the systemic networking fragility.

Changes:
- Add startup probe (60s delay, prevents premature service registration)
- Fix backup job env var substitution (use shell ${VAR}, not K8s $(VAR))
- Add comprehensive monitoring (ServiceMonitor, PrometheusRule, blackbox probes)
- Add alerting for service failures, high latency, pod restarts, backup failures

Evidence:
- Pod healthy (4d15h uptime, 0 restarts) but service ClusterIP routing broken
- Direct pod IP worked, service ClusterIP failed with "Connection reset by peer"
- Iptables rules correct, endpoints correct, but packets not flowing
- Required pod restart + Traefik restart to restore service

Monitoring now tests full service path from outside cluster, not just pod health.
Will alert immediately on failures instead of relying on reactive discovery.

Related: DEV-213, DEV-221, DEV-223, DEV-224, DEV-230, DEV-231

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-07-11 11:06:36 +00:00
CTO Agent
8054ef4018 Implement automatic TLS certificate renewal for Stalwart
Added Stakater Reloader to automatically restart Stalwart pods when
TLS certificates are renewed by cert-manager. This ensures seamless
certificate rotation without manual intervention.

Changes:
- Deploy Stakater Reloader in infrastructure/networking/
- Add Reloader annotation to Stalwart StatefulSet to watch stalwart-tls secret
- Document certificate renewal process and troubleshooting

The certificate is managed by cert-manager with Let's Encrypt and will
automatically renew 30 days before expiration (renewal date: 2026-08-20).
Reloader detects secret updates and triggers a rolling restart of the
Stalwart StatefulSet to load the new certificate.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-07-04 16:48:48 +00:00
CTO Agent
afe05cc772 Clean up Stalwart deployment - remove all old configs and OIDC attempts
Removed all experimental files, patches, OIDC configs, and Helm values.
Keeping only the clean v0.16.11 deployment with username/password auth.

Files kept:
- stalwart-fresh-deployment.yaml (main manifest)
- stalwart-admin-credentials-sealed.yaml (admin password)
- stalwart-s3-backup-sealed.yaml (backup credentials)
- README.md (updated documentation)

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-07-04 13:22:36 +00:00
CTO Agent
3acfa1f5e1 Remove config.toml ConfigMap and add TLS certificate mount
- Removed stalwart-config ConfigMap (config.toml not used in v0.16.11)
- All configuration is done via Stalwart API and stored in RocksDB
- Added TLS certificate mount from stalwart-tls secret
- Using stalwartlabs/stalwart:v0.16.11

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-07-04 12:13:18 +00:00
CTO Agent
0d4d9b9adf fix(stalwart): Add config.json to load web UI configuration
- Mount /etc/stalwart/config.json pointing to RocksDB
- Allows Stalwart to load configuration from web UI setup
- Resolves bootstrap mode loop

Refs: DEV-206

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-07-04 10:34:28 +00:00
CTO Agent
843affde05 fix(stalwart): Correct permissions to 2000:2000
- Fixed init container to set ownership to 2000:2000
- Stalwart container runs as user 2000 by default
- Resolves permission denied error during web UI setup

Refs: DEV-206

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-07-04 10:23:15 +00:00
CTO Agent
509bbebe10 feat(stalwart): Fresh deployment with basic auth
- Deployed Stalwart v0.16.11 in stalwart namespace
- Configured encrypted hcloud storage (20Gi PVC)
- Set up LoadBalancer services for SMTP/IMAP
- Configured Ingress with TLS for mail.basicstack.de
- Daily backup CronJob with S3/restic
- Bootstrap mode requires web UI setup completion

Refs: DEV-206

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-07-04 10:17:39 +00:00