Production & Bulk Automation Guide

Best practices for managing MailShrink across multi-server hosting environments, automated maintenance cronjobs, and fleet-wide storage optimization.

1. Ansible Deployment 2. Mass Scanning & Analytics 3. Automated Cronjobs 4. Pre-Migration Optimization 5. Disk Monitoring & Alert Hooks

📦 1. Deploying MailShrink with Ansible

MailShrink compiles to a single self-contained static binary with zero runtime dependencies. You can distribute and update it across thousands of cPanel, DirectAdmin, or custom Linux mail servers using a lightweight Ansible task.

Production Playbook (`deploy-mailshrink.yml`)

This playbook downloads the latest binary directly from GitHub Releases, installs it to /usr/local/bin, verifies execution, and runs the built-in Dovecot zlib pre-flight check:

deploy-mailshrink.yml
---
- name: Deploy MailShrink to Mail Servers
  hosts: mail_servers
  become: yes
  vars:
    mailshrink_version: "v2026.08.15"
    mailshrink_arch: "{{ 'arm64' if ansible_architecture == 'aarch64' else 'amd64' }}"

  tasks:
    - name: Download MailShrink binary
      ansible.builtin.get_url:
        url: "https://github.com/nemke82/mailshrink/releases/download/{{ mailshrink_version }}/mailshrink-linux-{{ mailshrink_arch }}"
        dest: "/usr/local/bin/mailshrink"
        mode: '0755'
        owner: root
        group: root

    - name: Verify MailShrink version
      ansible.builtin.command: /usr/local/bin/mailshrink version
      register: mailshrink_ver
      changed_when: false

    - name: Run Dovecot readiness pre-flight check
      ansible.builtin.command: /usr/local/bin/mailshrink check
      register: dovecot_check
      changed_when: false
      failed_when: false

    - name: Print Dovecot readiness status
      ansible.builtin.debug:
        msg: "{{ dovecot_check.stdout }}"
Zero Package Manager Overhead

Because MailShrink is compiled with CGO_ENABLED=0, it works seamlessly on AlmaLinux 8/9, Rocky Linux, CentOS, Ubuntu 20.04/22.04/24.04, and Debian without installing Go, Python modules, or pip packages.

📊 2. Mass Scanning & Fleet Analytics

When managing servers with hundreds of accounts and hundreds of gigabytes of Maildir storage, MailShrink provides multi-threaded scanning and structured JSON output for scriptable storage auditing.

Scan Server with High Concurrency

By default, MailShrink uses 4 parallel workers. On servers with NVMe or high-speed disk arrays, you can scale concurrency up to speed up discovery:

Terminal
# Scan all mailboxes under /home with 16 parallel threads
mailshrink analyze --path /home -j 16

# Scan only emails older than 2 years
mailshrink analyze --older-than 2y

Extracting Top Reclaimable Domains with `jq`

Using the --json flag, you can pipe MailShrink results into jq or reporting pipelines:

Bash / JQ Pipeline
# Find the top 5 domains by reclaimable disk space
mailshrink analyze --json | jq '.estimates | to_entries | sort_by(-.value.EstimatedSavings) | .[0:5][] | {domain: .key, savings_mb: (.value.EstimatedSavings / 1048576 | round)}'

Exporting a Detailed Per-Account Plan to CSV

Generate a spreadsheet report of compressible mailboxes for customer billing or quota reviews:

Bash Export
# Generate CSV from plan output
echo "Account,Folder,Period,Size_Bytes,Est_Savings_Bytes" > /var/log/mailshrink_report.csv
mailshrink plan --json | jq -r '.[] | "\(.account),\(.folder),\(.period),\(.size),\(.estimate.EstimatedSavings // 0)"' >> /var/log/mailshrink_report.csv

3. Automated Maintenance Cronjobs

Compressing old emails should be a hands-off, recurring maintenance task. MailShrink's atomic design, advisory locking, and mtime preservation ensure it can run safely in the background on live production servers.

Low-Priority Background Execution (`nice` & `ionice`)

To guarantee that compression never causes I/O spikes or slows down active IMAP/SMTP deliveries, always run cronjobs with nice -n 19 (lowest CPU priority) and ionice -c 3 (idle disk I/O class):

/etc/cron.d/mailshrink
# /etc/cron.d/mailshrink - Weekly automated Dovecot Maildir compression
# Runs every Sunday at 02:30 AM
30 2 * * 0 root /usr/bin/ionice -c 3 /usr/bin/nice -n 19 /usr/local/bin/mailshrink compress \
  --path /home \
  --older-than 1y \
  --apply \
  >> /var/log/mailshrink.log 2>&1

Tiered Compression Strategies

Different folders accumulate data at different rates. Here are proven production recipes:

Built-in Idempotency

MailShrink inspects the magic bytes of every email before compressing. If a file is already gzip-compressed, MailShrink skips it instantly (0 ms). Running a weekly cronjob is ultra-fast because it only touches newly aged emails.

🚀 4. Pre-Migration Optimization

Transferring massive Maildirs across servers (e.g., during cPanel-to-cPanel transfers, DirectAdmin migrations, or rsync syncs) is often bottlenecked by millions of small files and heavy disk usage.

The 3-Step Migration Workflow:

  1. Verify Target Server: Run mailshrink check on both source and target servers to ensure Dovecot's zlib plugin is enabled on both sides.
  2. Compress Source Mailboxes First: Run MailShrink on the source server before starting your transfer:
    Source Server
    mailshrink compress --path /home --older-than 6m --apply
  3. Transfer Compressed Maildir: Run your standard cPanel Transfer Tool or rsync -aHAX. The transfer completes 25% to 40% faster, saving gigabytes of network bandwidth and disk on the destination.

🛡️ 5. Disk Monitoring & Emergency Reclamation

If your monitoring system (e.g., Zabbix, Prometheus, Datadog, or Munin) detects that a mail partition has crossed 90% utilization, you can trigger MailShrink automatically to reclaim critical disk space before service degradation occurs.

Emergency Reclamation Script (`mailshrink-emergency.sh`)

/usr/local/sbin/mailshrink-emergency.sh
#!/usr/bin/env bash
# Emergency disk space reclamation for Dovecot Maildir
set -euo pipefail

DISK_USAGE=$(df -h /home | awk 'NR==2 {print $5}' | tr -d '%')
THRESHOLD=90

if [ "$DISK_USAGE" -ge "$THRESHOLD" ]; then
    logger -t mailshrink "Disk usage on /home is ${DISK_USAGE}%. Triggering emergency MailShrink compression..."
    
    # Compress Sent items older than 90 days
    /usr/local/bin/mailshrink compress --path /home --folder Sent --older-than 90d --apply
    
    # Compress any mail older than 1 year
    /usr/local/bin/mailshrink compress --path /home --older-than 1y --apply
    
    NEW_USAGE=$(df -h /home | awk 'NR==2 {print $5}' | tr -d '%')
    logger -t mailshrink "Emergency compression completed. New disk usage: ${NEW_USAGE}%."
fi