Add new infra architecture 6
This commit is contained in:
@@ -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:**
|
||||
|
||||
Reference in New Issue
Block a user