#!/bin/bash LOG=/var/log/mailcow-agent.log MAILCOW_DIR=/opt/mailcow-dockerized MAILCOW_HOSTNAME=mail2.onsethost.com DB_ROOT=8StOwipONifACqYhWFjxk4MuJK20 API_KEY=36A627-BEAEB4-ECD597-F4E182-8006F1 NFS_SERVER=172.16.0.1 DOMAINS=("relevantmediaproperties.com" "broadcastbeat.com" "broadcastengineering.com" "avbeat.com" "backlotbeat.com" "thepinkpulse.com" "rimshotsports.com" "onsethost.com" "crewgrid.com") log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a $LOG; } ok() { log "✅ $1"; } warn() { log "⚠️ $1"; } err() { log "❌ $1"; } section() { log ""; log "========== $1 =========="; } section "STORAGE NETWORK" if ! mountpoint -q /mnt/mail_data; then warn "mail_data not mounted, mounting..." sudo mkdir -p /mnt/mail_data sudo mount -t nfs $NFS_SERVER:/volume1/mail_data /mnt/mail_data 2>/dev/null mountpoint -q /mnt/mail_data && ok "mail_data mounted" || err "Failed to mount mail_data" else ok "mail_data already mounted" fi if ! mountpoint -q /mnt/backups; then sudo mkdir -p /mnt/backups sudo mount -t nfs $NFS_SERVER:/volume1/backups /mnt/backups 2>/dev/null mountpoint -q /mnt/backups && ok "backups mounted" || err "Failed to mount backups" else ok "backups already mounted" fi if ! grep -q "mail_data" /etc/fstab; then echo "$NFS_SERVER:/volume1/mail_data /mnt/mail_data nfs defaults,_netdev 0 0" | sudo tee -a /etc/fstab fi if ! grep -q "backups" /etc/fstab; then echo "$NFS_SERVER:/volume1/backups /mnt/backups nfs defaults,_netdev 0 0" | sudo tee -a /etc/fstab fi sudo systemctl daemon-reload section "MAILCOW CONTAINERS" cd $MAILCOW_DIR CONTAINERS_DOWN=$(sudo docker compose ps --status exited --status dead 2>/dev/null | grep -v "^NAME" | wc -l) if [ "$CONTAINERS_DOWN" -gt 0 ]; then warn "$CONTAINERS_DOWN containers down, restarting..." sudo docker compose up -d 2>&1 | tee -a $LOG sleep 15 fi for container in postfix-mailcow dovecot-mailcow nginx-mailcow mysql-mailcow redis-mailcow; do sudo docker ps --format '{{.Names}}' | grep -q $container && ok "$container running" || err "$container NOT running" done section "MAILCOW CONFIGURATION" sudo sed -i "s/^MAILCOW_HOSTNAME=.*/MAILCOW_HOSTNAME=$MAILCOW_HOSTNAME/" $MAILCOW_DIR/mailcow.conf ok "Hostname set to $MAILCOW_HOSTNAME" sudo sed -i "s/^SKIP_LETS_ENCRYPT=.*/SKIP_LETS_ENCRYPT=n/" $MAILCOW_DIR/mailcow.conf ok "Lets Encrypt enabled" section "DOMAINS" for domain in "${DOMAINS[@]}"; do RESULT=$(curl -sk -X POST "https://127.0.0.1/api/v1/add/domain" \ -H "X-API-Key: $API_KEY" \ -H "Content-Type: application/json" \ -d "{\"domain\":\"$domain\",\"description\":\"$domain\",\"aliases\":0,\"mailboxes\":100,\"defquota\":3072,\"maxquota\":102400,\"quota\":102400,\"active\":1,\"rl_value\":10,\"rl_frame\":\"s\",\"backupmx\":0,\"relay_all_recipients\":0}" 2>/dev/null) echo "$RESULT" | grep -q "domain_added\|domain_exists" && ok "Domain $domain OK" || warn "Domain $domain: $RESULT" done section "DKIM" for domain in "${DOMAINS[@]}"; do DKIM=$(curl -sk "https://127.0.0.1/api/v1/get/dkim/$domain" -H "X-API-Key: $API_KEY" 2>/dev/null) if echo "$DKIM" | grep -q "dkim_txt"; then ok "DKIM exists for $domain" else curl -sk -X POST "https://127.0.0.1/api/v1/add/dkim" \ -H "X-API-Key: $API_KEY" \ -H "Content-Type: application/json" \ -d "{\"dkim_selector\":\"dkim\",\"domain\":\"$domain\",\"key_size\":2048}" 2>/dev/null ok "DKIM generated for $domain" fi done section "SELF-HEALING CRON" sudo tee /usr/local/bin/mailcow-healer.sh > /dev/null << 'HEALER' #!/bin/bash LOG=/var/log/mailcow-healer.log MAILCOW_DIR=/opt/mailcow-dockerized NFS_SERVER=172.16.0.1 log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> $LOG; } if ! mountpoint -q /mnt/mail_data; then log "mail_data unmounted, remounting..." sudo mount -t nfs $NFS_SERVER:/volume1/mail_data /mnt/mail_data 2>/dev/null && log "remounted OK" || log "remount FAILED" fi if ! mountpoint -q /mnt/backups; then log "backups unmounted, remounting..." sudo mount -t nfs $NFS_SERVER:/volume1/backups /mnt/backups 2>/dev/null && log "remounted OK" || log "remount FAILED" fi cd $MAILCOW_DIR STOPPED=$(sudo docker compose ps --status exited --status dead 2>/dev/null | grep -v "^NAME" | wc -l) if [ "$STOPPED" -gt 0 ]; then log "$STOPPED containers stopped, restarting..." sudo docker compose up -d 2>/dev/null fi tail -1000 $LOG > /tmp/healer.tmp && mv /tmp/healer.tmp $LOG HEALER sudo chmod +x /usr/local/bin/mailcow-healer.sh if ! sudo crontab -l 2>/dev/null | grep -q "mailcow-healer"; then (sudo crontab -l 2>/dev/null; echo "*/5 * * * * /usr/local/bin/mailcow-healer.sh") | sudo crontab - ok "Self-healing cron installed" else ok "Self-healing cron already installed" fi section "SUMMARY" log "MAIL_02 Setup Complete" log "Hostname: $MAILCOW_HOSTNAME" log "Admin: https://mail2.onsethost.com/admin" log "Self-healing cron runs every 5 minutes"