Add new infra architecture 3

This commit is contained in:
Urtzi Alfaro
2026-01-19 13:57:50 +01:00
parent 8461226a97
commit 9edcc8c231
110 changed files with 2568 additions and 4636 deletions

View File

@@ -0,0 +1,198 @@
# Mailu Migration Guide: From Kustomize to Helm
This document outlines the migration process from the Kustomize-based Mailu deployment to the Helm-based deployment.
## Overview
The Mailu email server has been migrated from a Kustomize-based deployment to a Helm chart-based deployment. This change provides better maintainability, easier upgrades, and standardized configuration management.
## Key Changes
### 1. Service Names
- **Old**: `mailu-smtp`, `email-smtp`, `mailu-front`, `mailu-admin`, `mailu-imap`, `mailu-antispam`
- **New**: `mailu-postfix`, `mailu-front`, `mailu-admin`, `mailu-dovecot`, `mailu-rspamd`
### 2. Configuration Method
- **Old**: Individual YAML manifests with Kustomize overlays
- **New**: Helm chart with values files for environment-specific configuration
### 3. Directory Structure
- **Old**: `infrastructure/platform/mail/mailu/{base,overlays/{dev,prod}}`
- **New**: `infrastructure/platform/mail/mailu-helm/{dev,prod}`
### 4. Ingress Configuration
- **Old**: Ingress resources created as part of the Kustomize setup
- **New**: Built-in ingress disabled in Helm chart to work with existing ingress controller
## Updated Service References
The following configurations have been updated to use the new Helm service names:
## Ingress Configuration
The Mailu Helm chart has been configured to work with your existing ingress setup:
- **ingress.enabled: false**: Disables the chart's built-in Ingress creation
- **tlsFlavorOverride: notls**: Tells Mailu's internal NGINX not to enforce TLS, as your Ingress handles TLS termination
- **realIpHeader: X-Forwarded-For**: Ensures Mailu's NGINX logs and processes the correct client IPs from behind your Ingress
- **realIpFrom: 0.0.0.0/0**: Trusts all proxies (restrict to your Ingress pod CIDR for security)
### Required Ingress Resource
You need to create an Ingress resource to route traffic to Mailu. Here's an example:
```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: mailu-ingress
namespace: bakery-ia # Same as Mailu's namespace
annotations:
kubernetes.io/ingress.class: nginx # Or your Ingress class
nginx.ingress.kubernetes.io/proxy-body-size: "100m" # Allow larger email attachments
nginx.ingress.kubernetes.io/proxy-read-timeout: "3600" # For long connections
nginx.ingress.kubernetes.io/proxy-send-timeout: "3600"
nginx.ingress.kubernetes.io/force-ssl-redirect: "true" # Redirect HTTP to HTTPS
# If using Cert-Manager: cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
tls:
- hosts:
- mail.bakery-ia.local # or mail.bakewise.ai for prod
secretName: mail-tls-secret # Your TLS Secret
rules:
- host: mail.bakery-ia.local # or mail.bakewise.ai for prod
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: mailu-front-http # Mailu's front service (check with kubectl get svc -n bakery-ia)
port:
number: 80
```
Apply it: `kubectl apply -f ingress.yaml`.
This routes all traffic from https://mail.[domain]/ to Mailu's internal NGINX, which proxies to webmail (/webmail), admin (/admin), etc.
## Updated Service References
The following configurations have been updated to use the new Helm service names:
### Common ConfigMap
- `SMTP_HOST` changed from `email-smtp.bakery-ia.svc.cluster.local` to `mailu-postfix.bakery-ia.svc.cluster.local`
### SigNoz Configuration
- `signoz_smtp_host` changed from `email-smtp.bakery-ia.svc.cluster.local` to `mailu-postfix.bakery-ia.svc.cluster.local`
- `smtp_smarthost` changed from `email-smtp.bakery-ia.svc.cluster.local:587` to `mailu-postfix.bakery-ia.svc.cluster.local:587`
## Deployment Process
### Prerequisites
1. Helm 3.x installed
2. Access to Kubernetes cluster
3. Namespace `bakery-ia` exists
### Deployment Commands
#### For Development:
```bash
# Add Mailu Helm repository
helm repo add mailu https://mailu.github.io/helm-charts/
helm repo update
# Install Mailu for development
helm upgrade --install mailu-dev mailu/mailu \
--namespace bakery-ia \
--create-namespace \
--values infrastructure/platform/mail/mailu-helm/values.yaml \
--values infrastructure/platform/mail/mailu-helm/dev/values.yaml
```
#### For Production:
```bash
# Add Mailu Helm repository
helm repo add mailu https://mailu.github.io/helm-charts/
helm repo update
# Install Mailu for production
helm upgrade --install mailu-prod mailu/mailu \
--namespace bakery-ia \
--create-namespace \
--values infrastructure/platform/mail/mailu-helm/values.yaml \
--values infrastructure/platform/mail/mailu-helm/prod/values.yaml
```
## Critical Configuration Preservation
All critical configurations from the original Kustomize setup have been preserved:
- Domain and hostname settings
- External SMTP relay configuration (Mailgun)
- Redis integration with shared cluster
- Database connection settings
- TLS certificate management
- Resource limits and requests
- Network policies
- Storage configuration (10Gi PVC)
## Rollback Procedure
If rollback to the Kustomize setup is needed:
1. Uninstall the Helm release:
```bash
helm uninstall mailu-dev -n bakery-ia # or mailu-prod
```
2. Revert the configuration changes in `infrastructure/environments/common/configs/configmap.yaml` and `infrastructure/monitoring/signoz/signoz-values-prod.yaml`
3. Deploy the old Kustomize manifests:
```bash
kubectl apply -k infrastructure/platform/mail/mailu/overlays/dev
# or
kubectl apply -k infrastructure/platform/mail/mailu/overlays/prod
```
## Verification Steps
After deployment, verify the following:
1. Check that all Mailu pods are running:
```bash
kubectl get pods -n bakery-ia | grep mailu
```
2. Verify SMTP connectivity from other services:
```bash
# Test from a pod in the same namespace
kubectl run test-smtp --image=curlimages/curl -n bakery-ia --rm -it -- \
nc -zv mailu-postfix.bakery-ia.svc.cluster.local 587
```
3. Check that notification service can send emails:
```bash
kubectl logs -n bakery-ia deployment/notification-service | grep -i smtp
```
4. Verify web interface accessibility:
```bash
kubectl port-forward -n bakery-ia svc/mailu-front 8080:80
# Then visit http://localhost:8080/admin
```
## Known Issues
1. During migration, existing email data should be backed up before uninstalling the old deployment
2. DNS records may need to be updated to point to the new service endpoints
3. Some custom configurations may need to be reapplied after Helm installation
## Support
For issues with the new Helm-based deployment:
1. Check the [official Mailu Helm chart documentation](https://github.com/Mailu/helm-charts)
2. Review Helm release status: `helm status mailu-[dev|prod] -n bakery-ia`
3. Check pod logs: `kubectl logs -n bakery-ia deployment/[mailu-postfix|mailu-front|etc.]`
4. Verify network connectivity between services

View File

@@ -0,0 +1,171 @@
# Mailu Helm Chart for Bakery-IA
This directory contains the Helm chart configuration for Mailu, replacing the previous Kustomize-based setup.
## Overview
The Mailu email server is now deployed using the official Mailu Helm chart instead of Kustomize manifests. This provides better maintainability, easier upgrades, and standardized configuration. The setup is configured to work behind your existing Ingress controller (NGINX), with the internal Mailu NGINX acting as a proxy for services like webmail while your existing Ingress handles traffic routing, TLS termination, and forwarding to Mailu's internal NGINX on HTTP (port 80).
## Directory Structure
```
mailu-helm/
├── values.yaml # Base configuration values
├── dev/
│ └── values.yaml # Development-specific overrides
├── prod/
│ └── values.yaml # Production-specific overrides
└── mailu-ingress.yaml # Sample ingress configuration for use with existing ingress
```
## Critical Configuration Preservation
The following critical configurations from the original Kustomize setup have been preserved:
- **Domain settings**: Domain and hostnames for both dev and prod
- **External relay**: Mailgun SMTP relay configuration
- **Redis integration**: Connection to shared Redis cluster (database 15)
- **Database settings**: PostgreSQL connection details
- **Resource limits**: CPU and memory requests/limits matching original setup
- **Network policies**: Security policies restricting access to authorized services
- **Storage**: 10Gi persistent volume for mail data
- **Ingress configuration**: Built-in ingress disabled to work with existing ingress
## Deployment
### Prerequisites
1. Helm 3.x installed
2. Kubernetes cluster with storage provisioner
3. Ingress controller (NGINX) - already deployed in your cluster
4. Cert-manager for TLS certificates (optional, depends on your ingress setup)
5. External SMTP relay account (Mailgun)
### Deployment Commands
#### For Development:
```bash
helm repo add mailu https://mailu.github.io/helm-charts/
helm repo update
helm install mailu-dev mailu/mailu \
--namespace bakery-ia \
--create-namespace \
--values mailu-helm/values.yaml \
--values mailu-helm/dev/values.yaml
```
#### For Production:
```bash
helm repo add mailu https://mailu.github.io/helm-charts/
helm repo update
helm install mailu-prod mailu/mailu \
--namespace bakery-ia \
--create-namespace \
--values mailu-helm/values.yaml \
--values mailu-helm/prod/values.yaml
```
### Upgrading
To upgrade to a newer version of the Mailu Helm chart:
```bash
helm repo update
helm upgrade mailu-dev mailu/mailu \
--namespace bakery-ia \
--values mailu-helm/values.yaml \
--values mailu-helm/dev/values.yaml
```
## Ingress Configuration
The Mailu Helm chart is configured to work with your existing Ingress setup:
- **ingress.enabled: false**: Disables the chart's built-in Ingress creation
- **tlsFlavorOverride: notls**: Tells Mailu's internal NGINX not to enforce TLS, as your Ingress handles TLS termination
- **realIpHeader: X-Forwarded-For**: Ensures Mailu's NGINX logs and processes the correct client IPs from behind your Ingress
- **realIpFrom: 0.0.0.0/0**: Trusts all proxies (restrict to your Ingress pod CIDR for security)
### Required Ingress Resource
You need to create an Ingress resource to route traffic to Mailu. Here's an example:
```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: mailu-ingress
namespace: bakery-ia # Same as Mailu's namespace
annotations:
kubernetes.io/ingress.class: nginx # Or your Ingress class
nginx.ingress.kubernetes.io/proxy-body-size: "100m" # Allow larger email attachments
nginx.ingress.kubernetes.io/proxy-read-timeout: "3600" # For long connections
nginx.ingress.kubernetes.io/proxy-send-timeout: "3600"
nginx.ingress.kubernetes.io/force-ssl-redirect: "true" # Redirect HTTP to HTTPS
# If using Cert-Manager: cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
tls:
- hosts:
- mail.bakery-ia.local # or mail.bakewise.ai for prod
secretName: mail-tls-secret # Your TLS Secret
rules:
- host: mail.bakery-ia.local # or mail.bakewise.ai for prod
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: mailu-front-http # Mailu's front service (check with kubectl get svc -n bakery-ia)
port:
number: 80
```
Apply it: `kubectl apply -f ingress.yaml`.
This routes all traffic from https://mail.[domain]/ to Mailu's internal NGINX, which proxies to webmail (/webmail), admin (/admin), etc.
## Configuration Details
### Environment-Specific Values
- **Development** (`dev/values.yaml`):
- Domain: `bakery-ia.local`
- No TLS enforcement internally (handled by ingress)
- Disabled antivirus to save resources
- Debug logging level
- **Production** (`prod/values.yaml`):
- Domain: `bakewise.ai`
- No TLS enforcement internally (handled by ingress)
- Enabled antivirus
- Warning logging level
### Secrets Management
Sensitive values like passwords and API keys should be managed through Kubernetes secrets rather than being stored in the values files. The Helm chart supports referencing existing secrets for:
- Database passwords
- Redis passwords
- External relay credentials
- Mailu secret key
## Integration with Notification Service
The notification service continues to connect to Mailu via the internal service name `mailu-postfix.bakery-ia.svc.cluster.local` on port 587 with STARTTLS.
## Access Information
- **Admin Panel**: `https://mail.[domain]/admin`
- **Webmail**: `https://mail.[domain]/webmail`
- **SMTP**: `mail.[domain]:587` (STARTTLS) - handled via separate TCP services if needed
- **IMAP**: `mail.[domain]:993` (SSL/TLS) - handled via separate TCP services if needed
## Migration Notes
When migrating from the Kustomize setup to Helm:
1. Ensure all existing PVCs are preserved during migration
2. Export any existing mail data before migration if needed
3. Update any hardcoded service references in other deployments
4. Verify that network policies still allow necessary communications
5. Configure your existing ingress to route traffic to the Mailu services

View File

@@ -0,0 +1,50 @@
# Dev-specific Mailu Helm values for Bakery-IA
# Overrides base configuration for development environment
# Domain configuration for dev
domain: "bakery-ia.local"
hostnames:
- "mail.bakery-ia.local"
# External relay configuration for dev
externalRelay:
host: "[smtp.mailgun.org]:587"
username: "postmaster@bakery-ia.local"
password: "mailgun-api-key-replace-in-production"
# Ingress configuration for dev - disabled to use with existing ingress
ingress:
enabled: false # Disable chart's Ingress; use existing one
tls: false # Disable TLS in chart since ingress handles it
tlsFlavorOverride: notls # No TLS on internal NGINX; expect external proxy to handle TLS
realIpHeader: X-Forwarded-For # Header for client IP from your Ingress
realIpFrom: 0.0.0.0/0 # Trust all proxies (restrict to your Ingress pod CIDR for security)
path: /
pathType: ImplementationSpecific
# TLS flavor for dev (may use self-signed)
tls:
flavor: "cert"
# Welcome message (disabled in dev)
welcomeMessage:
enabled: false
# Log level for dev
logLevel: "DEBUG"
# Network Policy for dev
networkPolicy:
enabled: true
ingressController:
namespace: ingress-nginx
podSelector: |
matchLabels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/component: controller
monitoring:
namespace: monitoring
podSelector: |
matchLabels:
app: signoz-prometheus

View File

@@ -0,0 +1,28 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: mailu-ingress
namespace: bakery-ia # Same as Mailu's namespace
annotations:
kubernetes.io/ingress.class: nginx # Or your Ingress class
nginx.ingress.kubernetes.io/proxy-body-size: "100m" # Allow larger email attachments
nginx.ingress.kubernetes.io/proxy-read-timeout: "3600" # For long connections
nginx.ingress.kubernetes.io/proxy-send-timeout: "3600"
nginx.ingress.kubernetes.io/force-ssl-redirect: "true" # Redirect HTTP to HTTPS
# If using Cert-Manager: cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
tls:
- hosts:
- mail.bakery-ia.local # or mail.bakewise.ai for prod
secretName: mail-tls-secret # Your TLS Secret
rules:
- host: mail.bakery-ia.local # or mail.bakewise.ai for prod
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: mailu-front-http # Mailu's front service (check with kubectl get svc -n bakery-ia)
port:
number: 80

View File

@@ -0,0 +1,57 @@
# Production-specific Mailu Helm values for Bakery-IA
# Overrides base configuration for production environment
# Domain configuration for production
domain: "bakewise.ai"
hostnames:
- "mail.bakewise.ai"
# External relay configuration for production
externalRelay:
host: "[smtp.mailgun.org]:587"
username: "postmaster@bakewise.ai"
password: "PRODUCTION_MAILGUN_API_KEY" # This should be set via secret
# Ingress configuration for production - disabled to use with existing ingress
ingress:
enabled: false # Disable chart's Ingress; use existing one
tls: false # Disable TLS in chart since ingress handles it
tlsFlavorOverride: notls # No TLS on internal NGINX; expect external proxy to handle TLS
realIpHeader: X-Forwarded-For # Header for client IP from your Ingress
realIpFrom: 0.0.0.0/0 # Trust all proxies (restrict to your Ingress pod CIDR for security)
path: /
pathType: ImplementationSpecific
# TLS flavor for production (uses Let's Encrypt)
tls:
flavor: "cert"
# Welcome message (enabled in production)
welcomeMessage:
enabled: true
subject: "Welcome to Bakewise.ai Email Service"
body: "Welcome to our email service. Please change your password and update your profile."
# Log level for production
logLevel: "WARNING"
# Enable antivirus in production
antivirus:
enabled: true
flavor: "clamav"
# Network Policy for production
networkPolicy:
enabled: true
ingressController:
namespace: ingress-nginx
podSelector: |
matchLabels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/component: controller
monitoring:
namespace: monitoring
podSelector: |
matchLabels:
app: signoz-prometheus

View File

@@ -0,0 +1,206 @@
# Base Mailu Helm values for Bakery-IA
# Preserves critical configurations from the original Kustomize setup
# Domain configuration
domain: "DOMAIN_PLACEHOLDER"
hostnames:
- "mail.DOMAIN_PLACEHOLDER"
# Mailu version to match the original setup
mailuVersion: "2024.06"
# Secret key for authentication cookies
secretKey: "cb61b934d47029a64117c0e4110c93f66bbcf5eaa15c84c42727fad78f7"
# Timezone
timezone: "Etc/UTC"
# Postmaster configuration
postmaster: "admin"
# TLS configuration
tls:
flavor: "cert"
# Limits configuration
limits:
messageSizeLimitInMegabytes: 50
authRatelimit:
ip: "60/hour"
user: "100/day"
messageRatelimit:
value: "200/day"
# External relay configuration (Mailgun)
externalRelay:
host: "[smtp.mailgun.org]:587"
username: "postmaster@DOMAIN_PLACEHOLDER"
password: "mailgun-api-key-replace-in-production"
# Webmail configuration
webmail:
enabled: true
flavor: "roundcube"
# Antivirus and antispam configuration
antivirus:
enabled: false # Disabled in dev to save resources
antispam:
enabled: true
flavor: "rspamd"
# Welcome message
welcomeMessage:
enabled: false # Disabled during development
# Logging
logLevel: "INFO"
# Network configuration
subnet: "10.42.0.0/16"
# Redis configuration - using external Redis (shared cluster Redis)
externalRedis:
enabled: true
host: "redis-service.bakery-ia.svc.cluster.local"
port: 6380
adminQuotaDbId: 15
adminRateLimitDbId: 15
rspamdDbId: 15
# Database configuration - using external database
externalDatabase:
enabled: true
type: "postgresql"
host: "postgres-service.bakery-ia.svc.cluster.local"
port: 5432
database: "mailu"
username: "mailu"
password: "E8Kz47YmVzDlHGs1M9wAbJzxcKnGONCT"
# Persistence configuration
persistence:
single_pvc: true
size: 10Gi
storageClass: ""
accessModes: [ReadWriteOnce]
# Ingress configuration - disabled to use with existing ingress
ingress:
enabled: false # Disable chart's Ingress; use existing one
tls: false # Disable TLS in chart since ingress handles it
tlsFlavorOverride: notls # No TLS on internal NGINX; expect external proxy to handle TLS
realIpHeader: X-Forwarded-For # Header for client IP from your Ingress
realIpFrom: 0.0.0.0/0 # Trust all proxies (restrict to your Ingress pod CIDR for security)
path: /
pathType: ImplementationSpecific
# Optional: Enable PROXY protocol for mail protocols if your Ingress supports TCP proxying
proxyProtocol:
smtp: false
smtps: false
submission: false
imap: false
imaps: false
pop3: false
pop3s: false
manageSieve: false
# Front configuration
front:
image:
tag: "2024.06"
replicaCount: 1
service:
type: ClusterIP
ports:
http: 80
https: 443
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 200m
memory: 256Mi
# Admin configuration
admin:
image:
tag: "2024.06"
replicaCount: 1
service:
type: ClusterIP
port: 80
resources:
requests:
cpu: 100m
memory: 256Mi
limits:
cpu: 300m
memory: 512Mi
# Postfix configuration
postfix:
image:
tag: "2024.06"
replicaCount: 1
service:
type: ClusterIP
ports:
smtp: 25
submission: 587
resources:
requests:
cpu: 100m
memory: 256Mi
limits:
cpu: 500m
memory: 512Mi
# Dovecot configuration
dovecot:
image:
tag: "2024.06"
replicaCount: 1
service:
type: ClusterIP
ports:
imap: 143
imaps: 993
resources:
requests:
cpu: 100m
memory: 256Mi
limits:
cpu: 500m
memory: 512Mi
# Rspamd configuration
rspamd:
image:
tag: "2024.06"
replicaCount: 1
service:
type: ClusterIP
ports:
rspamd: 11333
rspamd-admin: 11334
resources:
requests:
cpu: 200m
memory: 512Mi
limits:
cpu: 1000m
memory: 1Gi
# Network Policy
networkPolicy:
enabled: true
ingressController:
namespace: ingress-nginx
podSelector: |
matchLabels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/component: controller