#!/bin/bash # ============================================================================= # Mailu Production Deployment Script # ============================================================================= # This script automates the deployment of Mailu mail server for production. # It handles: # 1. CoreDNS configuration with DNS-over-TLS for DNSSEC validation # 2. TLS certificate secret creation # 3. Admin credentials secret creation # 4. Mailu Helm deployment (admin user created automatically via initialAccount) # # Usage: # ./deploy-mailu-prod.sh [--domain DOMAIN] [--admin-password PASSWORD] # # Example: # ./deploy-mailu-prod.sh --domain bakewise.ai --admin-password 'SecurePass123!' # ============================================================================= set -e # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # Default values DOMAIN="${DOMAIN:-bakewise.ai}" ADMIN_PASSWORD="${ADMIN_PASSWORD:-}" NAMESPACE="bakery-ia" SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" MAILU_HELM_DIR="$(dirname "$SCRIPT_DIR")" # Parse arguments while [[ $# -gt 0 ]]; do case $1 in --domain) DOMAIN="$2" shift 2 ;; --admin-password) ADMIN_PASSWORD="$2" shift 2 ;; --help) echo "Usage: $0 [--domain DOMAIN] [--admin-password PASSWORD]" echo "" echo "Options:" echo " --domain Domain for Mailu (default: bakewise.ai)" echo " --admin-password Password for admin@DOMAIN user" echo "" exit 0 ;; *) echo -e "${RED}Unknown option: $1${NC}" exit 1 ;; esac done print_step() { echo -e "\n${BLUE}==>${NC} ${GREEN}$1${NC}" } print_warning() { echo -e "${YELLOW}WARNING:${NC} $1" } print_error() { echo -e "${RED}ERROR:${NC} $1" } print_success() { echo -e "${GREEN}✓${NC} $1" } # ============================================================================= # Step 0: Prerequisites Check # ============================================================================= print_step "Step 0: Checking prerequisites..." if ! command -v kubectl &> /dev/null; then print_error "kubectl not found. Please install kubectl." exit 1 fi if ! command -v helm &> /dev/null; then print_error "helm not found. Please install helm." exit 1 fi if ! kubectl get namespace "$NAMESPACE" &>/dev/null; then print_warning "Namespace $NAMESPACE does not exist. Creating..." kubectl create namespace "$NAMESPACE" fi print_success "Prerequisites check passed" # ============================================================================= # Step 1: Configure CoreDNS with DNS-over-TLS for DNSSEC # ============================================================================= print_step "Step 1: Configuring CoreDNS with DNS-over-TLS for DNSSEC validation..." # Check if CoreDNS is already configured with DNS-over-TLS CURRENT_FORWARD=$(kubectl get configmap coredns -n kube-system -o jsonpath='{.data.Corefile}' 2>/dev/null | grep -o 'tls://1.1.1.1' || echo "") if [ -z "$CURRENT_FORWARD" ]; then echo "Updating CoreDNS to use DNS-over-TLS with Cloudflare for DNSSEC validation..." # Create a temporary file with the CoreDNS configuration TEMP_COREFILE=$(mktemp) cat > "$TEMP_COREFILE" </dev/null; then print_success "TLS certificate secret already exists" else 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.$DOMAIN/O=$DOMAIN" 2>/dev/null kubectl create secret tls mailu-certificates \ --cert=tls.crt \ --key=tls.key \ -n "$NAMESPACE" rm -rf "$TEMP_DIR" print_success "TLS certificate secret created" fi # ============================================================================= # Step 3: Create Admin Credentials Secret # ============================================================================= print_step "Step 3: Creating admin credentials secret..." if kubectl get secret mailu-admin-credentials -n "$NAMESPACE" &>/dev/null; then print_success "Admin credentials secret already exists" # Retrieve existing password for summary output if [ -z "$ADMIN_PASSWORD" ]; then ADMIN_PASSWORD=$(kubectl get secret mailu-admin-credentials -n "$NAMESPACE" -o jsonpath='{.data.password}' | base64 -d) fi else if [ -z "$ADMIN_PASSWORD" ]; then # Generate a random password ADMIN_PASSWORD=$(openssl rand -base64 16 | tr -d '/+=' | head -c 16) echo -e "${YELLOW}Generated admin password: $ADMIN_PASSWORD${NC}" echo -e "${YELLOW}Please save this password securely!${NC}" fi kubectl create secret generic mailu-admin-credentials \ --from-literal=password="$ADMIN_PASSWORD" \ -n "$NAMESPACE" print_success "Admin credentials secret created" fi # ============================================================================= # Step 4: Deploy Mailu via Helm # ============================================================================= print_step "Step 4: Deploying Mailu via Helm..." # Add Mailu Helm repository helm repo add mailu https://mailu.github.io/helm-charts 2>/dev/null || true helm repo update mailu # Deploy Mailu with CoreDNS configuration helm upgrade --install mailu mailu/mailu \ -n "$NAMESPACE" \ -f "$MAILU_HELM_DIR/values.yaml" \ -f "$MAILU_HELM_DIR/prod/values.yaml" \ --set global.custom_dns_servers="$COREDNS_IP" \ --timeout 10m print_success "Mailu Helm release deployed (admin user will be created automatically)" # ============================================================================= # Step 5: Wait for Pods to be Ready # ============================================================================= print_step "Step 5: Waiting for Mailu pods to be ready..." echo "This may take 5-10 minutes (ClamAV takes time to initialize)..." # Wait for admin pod first (it's the key dependency) kubectl wait --for=condition=ready pod -l app.kubernetes.io/component=admin -n "$NAMESPACE" --timeout=300s || { print_error "Admin pod failed to start. Checking logs..." kubectl logs -n "$NAMESPACE" -l app.kubernetes.io/component=admin --tail=50 exit 1 } print_success "Admin pod is ready" # Show pod status echo "" echo "Mailu Pod Status:" kubectl get pods -n "$NAMESPACE" | grep mailu print_success "Admin user created automatically via Helm initialAccount" # ============================================================================= # Summary # ============================================================================= echo "" echo "==============================================" echo -e "${GREEN}Mailu Deployment Complete!${NC}" echo "==============================================" echo "" echo "Admin Credentials:" echo " Email: admin@$DOMAIN" echo " Password: $ADMIN_PASSWORD" echo "" echo "Access URLs (configure Ingress/DNS first):" echo " Admin Panel: https://mail.$DOMAIN/admin" echo " Webmail: https://mail.$DOMAIN/webmail" echo " SMTP: mail.$DOMAIN:587 (STARTTLS)" echo " IMAP: mail.$DOMAIN:993 (SSL)" echo "" echo "DNS Configuration:" echo " CoreDNS is configured with DNS-over-TLS (Cloudflare) for DNSSEC validation" echo " CoreDNS IP: $COREDNS_IP" echo "" echo "Next Steps:" echo " 1. Configure DNS records (A, MX, SPF, DMARC)" echo " 2. Get DKIM key: kubectl exec -n $NAMESPACE deployment/mailu-admin -- cat /dkim/$DOMAIN.dkim.pub" echo " 3. Add DKIM TXT record to DNS" echo " 4. Configure Ingress for mail.$DOMAIN" echo "" echo "To check pod status:" echo " kubectl get pods -n $NAMESPACE | grep mailu" echo ""