Add new infra architecture 6

This commit is contained in:
Urtzi Alfaro
2026-01-19 16:31:11 +01:00
parent b78399da2c
commit 7d6845574c
58 changed files with 2360 additions and 492 deletions

View File

@@ -719,6 +719,221 @@ kubectl describe clusterissuer letsencrypt-production
From Email: noreply@yourdomain.com
```
### Option C: Self-Hosted Mailu (RECOMMENDED for Production)
**Features:**
- ✅ Full control over email infrastructure
- ✅ No external dependencies or rate limits
- ✅ Built-in antispam (rspamd) with DNSSEC validation
- ✅ Webmail interface (Roundcube)
- ✅ IMAP/SMTP with TLS
- ✅ Admin panel for user management
- ✅ Integrated with Kubernetes
**Why Mailu for Production:**
- Complete email stack (Postfix, Dovecot, Rspamd, ClamAV)
- DNSSEC validation for email authentication (DKIM/SPF/DMARC)
- No monthly email limits or third-party dependencies
- Professional email addresses: admin@bakewise.ai, noreply@bakewise.ai
#### Prerequisites
Before deploying Mailu, ensure:
1. **Unbound DNS is deployed** (for DNSSEC validation)
2. **CoreDNS is configured** to forward to Unbound
3. **DNS records are configured** for your domain
#### Step 1: Configure DNS Records
Add these DNS records for your domain (e.g., bakewise.ai):
```
Type Name Value TTL
A mail YOUR_VPS_IP Auto
MX @ mail.bakewise.ai (priority 10) Auto
TXT @ v=spf1 mx a -all Auto
TXT _dmarc v=DMARC1; p=reject; rua=... Auto
```
**DKIM record** will be generated after Mailu is running - you'll add it later.
#### Step 2: Deploy Unbound DNS Resolver
Unbound provides DNSSEC validation required by Mailu for email authentication.
```bash
# On VPS - Deploy Unbound via Helm
helm upgrade --install unbound infrastructure/platform/networking/dns/unbound-helm \
-n bakery-ia \
--create-namespace \
-f infrastructure/platform/networking/dns/unbound-helm/values.yaml \
-f infrastructure/platform/networking/dns/unbound-helm/prod/values.yaml \
--timeout 5m \
--wait
# Verify Unbound is running
kubectl get pods -n bakery-ia | grep unbound
# Should show: unbound-xxx 1/1 Running
# Get Unbound service IP (needed for CoreDNS configuration)
UNBOUND_IP=$(kubectl get svc unbound-dns -n bakery-ia -o jsonpath='{.spec.clusterIP}')
echo "Unbound DNS IP: $UNBOUND_IP"
```
#### Step 3: Configure CoreDNS for DNSSEC
Mailu requires DNSSEC validation. Configure CoreDNS to forward external queries to Unbound:
```bash
# Get the Unbound service IP
UNBOUND_IP=$(kubectl get svc unbound-dns -n bakery-ia -o jsonpath='{.spec.clusterIP}')
# Patch CoreDNS to forward to Unbound
kubectl patch configmap coredns -n kube-system --type merge -p "{
\"data\": {
\"Corefile\": \".:53 {\\n errors\\n health {\\n lameduck 5s\\n }\\n ready\\n kubernetes cluster.local in-addr.arpa ip6.arpa {\\n pods insecure\\n fallthrough in-addr.arpa ip6.arpa\\n ttl 30\\n }\\n prometheus :9153\\n forward . $UNBOUND_IP {\\n max_concurrent 1000\\n }\\n cache 30 {\\n disable success cluster.local\\n disable denial cluster.local\\n }\\n loop\\n reload\\n loadbalance\\n}\\n\"
}
}"
# Restart CoreDNS to apply changes
kubectl rollout restart deployment coredns -n kube-system
kubectl rollout status deployment coredns -n kube-system --timeout=60s
# Verify DNSSEC is working
kubectl run -it --rm debug --image=alpine --restart=Never -- \
sh -c "apk add drill && drill -D google.com"
# Should show: ;; flags: ... ad ... (ad = authenticated data = DNSSEC valid)
```
#### Step 4: Create TLS Certificate Secret
Mailu Front pod requires a TLS certificate:
```bash
# Generate self-signed certificate for internal use
# (Let's Encrypt handles external TLS via Ingress)
TEMP_DIR=$(mktemp -d)
cd "$TEMP_DIR"
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout tls.key -out tls.crt \
-subj "/CN=mail.bakewise.ai/O=bakewise"
kubectl create secret tls mailu-certificates \
--cert=tls.crt \
--key=tls.key \
-n bakery-ia
rm -rf "$TEMP_DIR"
# Verify secret created
kubectl get secret mailu-certificates -n bakery-ia
```
#### Step 5: Deploy Mailu via Helm
```bash
# Add Mailu Helm repository
helm repo add mailu https://mailu.github.io/helm-charts
helm repo update mailu
# Deploy Mailu with production values
helm upgrade --install mailu mailu/mailu \
-n bakery-ia \
--create-namespace \
-f infrastructure/platform/mail/mailu-helm/values.yaml \
-f infrastructure/platform/mail/mailu-helm/prod/values.yaml \
--timeout 10m
# Wait for pods to be ready (may take 5-10 minutes for ClamAV)
kubectl get pods -n bakery-ia -l app.kubernetes.io/instance=mailu -w
```
#### Step 6: Create Admin User
```bash
# Create initial admin user
kubectl exec -it -n bakery-ia deployment/mailu-admin -- \
flask mailu admin admin bakewise.ai 'YourSecurePassword123!'
# Credentials:
# Email: admin@bakewise.ai
# Password: YourSecurePassword123!
```
#### Step 7: Configure DKIM
After Mailu is running, get the DKIM key and add it to DNS:
```bash
# Get DKIM public key
kubectl exec -n bakery-ia deployment/mailu-admin -- \
cat /dkim/bakewise.ai.dkim.pub
# Add this as a TXT record in your DNS:
# Name: dkim._domainkey
# Value: (the key from above)
```
#### Step 8: Verify Email Setup
```bash
# Check all Mailu pods are running
kubectl get pods -n bakery-ia | grep mailu
# Expected: All 10 pods in Running state
# Test SMTP connectivity
kubectl run -it --rm smtp-test --image=alpine --restart=Never -- \
sh -c "apk add swaks && swaks --to test@example.com --from admin@bakewise.ai --server mailu-front.bakery-ia.svc.cluster.local:25"
# Access webmail (via port-forward for testing)
kubectl port-forward -n bakery-ia svc/mailu-front 8080:80
# Open: http://localhost:8080/webmail
```
#### Production Email Endpoints
| Service | URL/Address |
|---------|-------------|
| Admin Panel | https://mail.bakewise.ai/admin |
| Webmail | https://mail.bakewise.ai/webmail |
| SMTP (STARTTLS) | mail.bakewise.ai:587 |
| SMTP (SSL) | mail.bakewise.ai:465 |
| IMAP (SSL) | mail.bakewise.ai:993 |
#### Troubleshooting Mailu
**Issue: Admin pod CrashLoopBackOff with "DNSSEC validation" error**
```bash
# Verify CoreDNS is forwarding to Unbound
kubectl get configmap coredns -n kube-system -o yaml | grep forward
# Should show: forward . <unbound-ip>
# If not, re-run Step 3 above
```
**Issue: Front pod stuck in ContainerCreating**
```bash
# Check for missing certificate secret
kubectl describe pod -n bakery-ia -l app.kubernetes.io/component=front | grep -A5 Events
# If missing mailu-certificates, re-run Step 4 above
```
**Issue: Admin pod can't connect to Redis**
```bash
# Verify externalRedis is disabled in values
helm get values mailu -n bakery-ia | grep -A5 externalRedis
# Should show: enabled: false
# If enabled: true, upgrade with correct values
helm upgrade mailu mailu/mailu -n bakery-ia \
-f infrastructure/platform/mail/mailu-helm/values.yaml \
-f infrastructure/platform/mail/mailu-helm/prod/values.yaml
```
---
### WhatsApp Business API Setup
**Features:**