125 lines
3.7 KiB
Markdown
125 lines
3.7 KiB
Markdown
|
|
# Stalwart Mail Server Deployment - DEV-206
|
||
|
|
|
||
|
|
**Date**: 2026-07-04
|
||
|
|
**Status**: Deployment Complete, Manual Setup Required
|
||
|
|
**Agent**: CTO
|
||
|
|
|
||
|
|
## Deployment Summary
|
||
|
|
|
||
|
|
Fresh Stalwart v0.16.11 deployment successfully completed in the `stalwart` namespace.
|
||
|
|
|
||
|
|
### ✅ Completed
|
||
|
|
|
||
|
|
1. **Infrastructure**
|
||
|
|
- Deleted old deployment completely
|
||
|
|
- Created fresh StatefulSet deployment
|
||
|
|
- Configured 20Gi encrypted hcloud-volumes PVC
|
||
|
|
- Set up daily backup cronjob (3 AM)
|
||
|
|
- Configured TLS via Let's Encrypt/cert-manager
|
||
|
|
- Ingress configured for https://mail.basicstack.de
|
||
|
|
|
||
|
|
2. **Services**
|
||
|
|
- Web UI: Accessible at https://mail.basicstack.de ✓
|
||
|
|
- SMTP LoadBalancer: Created (ports 25, 587, 465)
|
||
|
|
- IMAP LoadBalancer: Created (ports 143, 993)
|
||
|
|
|
||
|
|
3. **Authentication**
|
||
|
|
- Recovery admin account created
|
||
|
|
- Username/password authentication enabled
|
||
|
|
- NO OAuth/OIDC (as requested)
|
||
|
|
|
||
|
|
### ⚠️ Manual Steps Required
|
||
|
|
|
||
|
|
The following steps cannot be completed via API automation and require manual action:
|
||
|
|
|
||
|
|
#### 1. User Creation via Web UI
|
||
|
|
|
||
|
|
**Admin Login:**
|
||
|
|
- URL: https://mail.basicstack.de
|
||
|
|
- Username: `admin`
|
||
|
|
- Password: `VRQwu6ET7vdJN4zm23kQ`
|
||
|
|
|
||
|
|
**Users to Create:**
|
||
|
|
- admin@basicstack.de (password in sealed secret: stalwart-admin-credentials/admin-password)
|
||
|
|
- andreas.leinen@basicstack.de (password in sealed secret: stalwart-admin-credentials/andreas-password)
|
||
|
|
- andreas.leinen@imicros.de (generate new password)
|
||
|
|
|
||
|
|
#### 2. DNS Configuration
|
||
|
|
|
||
|
|
Mail ports are currently only accessible within cluster. Required:
|
||
|
|
|
||
|
|
**DNS A Record:**
|
||
|
|
```
|
||
|
|
mail.basicstack.de → 178.105.17.239 (or appropriate public IP)
|
||
|
|
```
|
||
|
|
|
||
|
|
**MX Record:**
|
||
|
|
```
|
||
|
|
@ MX 10 mail.basicstack.de
|
||
|
|
```
|
||
|
|
|
||
|
|
#### 3. Firewall Configuration
|
||
|
|
|
||
|
|
Ensure Hetzner firewall `fw-k3s` allows incoming traffic on:
|
||
|
|
- TCP 25 (SMTP)
|
||
|
|
- TCP 587 (Submission)
|
||
|
|
- TCP 465 (SMTPS)
|
||
|
|
- TCP 143 (IMAP)
|
||
|
|
- TCP 993 (IMAPS)
|
||
|
|
|
||
|
|
### Testing Performed
|
||
|
|
|
||
|
|
- ✓ Pod health: stalwart-0 running and ready (1/1)
|
||
|
|
- ✓ Web UI accessibility: https://mail.basicstack.de responds
|
||
|
|
- ✓ Ingress routing: TLS certificate valid
|
||
|
|
- ✓ Storage: PVC bound and mounted
|
||
|
|
- ✓ Backup schedule: CronJob configured
|
||
|
|
- ⚠️ SMTP/IMAP ports: Not publicly accessible (requires DNS/firewall)
|
||
|
|
- ⚠️ Email functionality: Cannot test without users and DNS
|
||
|
|
|
||
|
|
### Known Issues
|
||
|
|
|
||
|
|
1. **LoadBalancer External IP**: Services expose on cluster internal IPs (10.42.1.x) rather than public IPs
|
||
|
|
- **Impact**: Mail ports not accessible from internet
|
||
|
|
- **Resolution**: Configure DNS to point to a node's public IP, or reconfigure services
|
||
|
|
|
||
|
|
2. **User Creation API**: Stalwart JMAP API for principal management requires complex authentication flow not fully documented
|
||
|
|
- **Impact**: Users must be created manually via web UI
|
||
|
|
- **Resolution**: Board user to log in and create accounts as specified
|
||
|
|
|
||
|
|
### Next Actions
|
||
|
|
|
||
|
|
See detailed instructions in the comments on DEV-206 for:
|
||
|
|
- Step-by-step user creation
|
||
|
|
- DNS configuration examples
|
||
|
|
- Firewall rule setup
|
||
|
|
- Email client testing procedures
|
||
|
|
|
||
|
|
### Files Modified
|
||
|
|
|
||
|
|
- `stalwart-fresh-deployment.yaml` - Main deployment manifest
|
||
|
|
- Deployed to cluster on 2026-07-04
|
||
|
|
|
||
|
|
### Backup Configuration
|
||
|
|
|
||
|
|
- **Schedule**: Daily at 3 AM UTC
|
||
|
|
- **Backend**: Restic to S3
|
||
|
|
- **Retention**: 7 daily, 4 weekly, 6 monthly snapshots
|
||
|
|
- **Credentials**: stalwart-s3-backup sealed secret
|
||
|
|
|
||
|
|
### Recovery
|
||
|
|
|
||
|
|
In case of failure:
|
||
|
|
```bash
|
||
|
|
# Restore from backup
|
||
|
|
restic -r s3:${S3_ENDPOINT}/${S3_BUCKET}/stalwart restore latest --target /var/lib/stalwart
|
||
|
|
|
||
|
|
# Re-deploy
|
||
|
|
kubectl apply -f stalwart-admin-credentials-sealed.yaml
|
||
|
|
kubectl apply -f stalwart-s3-backup-sealed.yaml
|
||
|
|
kubectl create configmap stalwart-bootstrap-config \
|
||
|
|
--from-literal=config.json='{"@type":"RocksDb","path":"/var/lib/stalwart"}' \
|
||
|
|
-n stalwart
|
||
|
|
kubectl apply -f stalwart-fresh-deployment.yaml
|
||
|
|
```
|