The pod was crash-looping because Stalwart's security configuration blocks the kubelet's IP (10.244.4.1) from accessing the HTTP health endpoints. The kubelet's health checks were failing, causing the startup probe to fail after 6 attempts, leading to pod restarts. Changed all three health probes (startup, liveness, readiness) from httpGet to exec with curl localhost. This bypasses the IP blocking since the health check runs from inside the container using localhost, which is not subject to Stalwart's external IP blocking rules. This fix is non-destructive to Stalwart's configuration and state. The pod will restart once with the new probe configuration, but no data or configuration will be lost. Root cause: Stalwart logs showed "Blocked IP address (security.ip-blocked) listenerId=http, remoteIp=10.244.4.1" followed by "Shutting down Stalwart Server (server.shutdown) causedBy=SIGTERM" in a repeating pattern. Fixes: DEV-420 Co-Authored-By: Paperclip <noreply@paperclip.ing> |
||
|---|---|---|
| .. | ||
| CERTIFICATE-RENEWAL.md | ||
| ISSUE-2026-07-13-smtp-imap-external-access.md | ||
| manual_config_steps.md | ||
| README.md | ||
| SETUP_COMPLETE.md | ||
| STABILITY-CHECK.md | ||
| STABLE-ROUTING-SOLUTION.md | ||
| stalwart-admin-credentials-sealed.yaml | ||
| stalwart-bootstrap-config.yaml | ||
| stalwart-fresh-deployment.yaml | ||
| stalwart-monitoring.yaml | ||
| stalwart-s3-backup-sealed.yaml | ||
Stalwart Mail Server v0.16.11
Clean deployment of Stalwart mail server with username/password authentication only.
Architecture
- Version: v0.16.11
- Authentication: Username/password only (NO OAuth/OIDC)
- Configuration: API-based (stored in RocksDB)
- Storage: Encrypted hcloud-volumes (20Gi)
- Backup: Daily restic backup to S3 at 3 AM
- Web UI: https://mail.basicstack.de
Files
stalwart-fresh-deployment.yaml- Main deployment manifeststalwart-admin-credentials-sealed.yaml- Sealed secret for admin passwordstalwart-s3-backup-sealed.yaml- Sealed secret for S3 backup credentials
Deployment
# Apply sealed secrets first
kubectl apply -f stalwart-admin-credentials-sealed.yaml
kubectl apply -f stalwart-s3-backup-sealed.yaml
# Create bootstrap config
kubectl create configmap stalwart-bootstrap-config \
--from-literal=config.json='{"@type":"RocksDb","path":"/var/lib/stalwart"}' \
-n stalwart
# Deploy Stalwart
kubectl apply -f stalwart-fresh-deployment.yaml
Initial Admin Login
After deployment, log in at https://mail.basicstack.de with:
- Username:
admin - Password: (from stalwart-admin-credentials secret)
Configuration
All configuration is done via the web UI or API. The bootstrap config only points to the RocksDB database location. NO config.toml files are used.
Check https://stalw.art/docs/ref/ for configuration possibilities. The API access via /jmap seems to be too complex for the agent and the configruation has been done manually.
Refer to manual configuration steps
Ports
- SMTP: 25, 587, 465
- IMAP: 143, 993
- HTTP: 8080 (web UI)
Storage
Data is stored in /var/lib/stalwart using the RocksDB database format. This includes:
- Email messages
- User accounts
- Server configuration
- TLS certificates configuration
Certificate Renewal
Refer to Automatic Renewal TLS Certificate