Antivirus Scanning
Mailpilot supports optional antivirus scanning of email attachments using ClamAV.
Overview
When enabled, Mailpilot scans all email attachments before LLM classification. If a virus is detected, the email is handled according to your configured action (quarantine, delete, or flag).
Requirements
ClamAV is resource-intensive due to loading virus definitions into memory.
Resource Requirements
| Resource | Minimum | Recommended |
|---|---|---|
| Memory | 1 GB | 2 GB |
| Disk | 500 MB | 1 GB |
| CPU | 1 core | 2 cores |
| Startup time | 2-5 minutes | - |
The high memory requirement is because ClamAV loads its entire virus signature database (~400MB) into RAM for fast scanning.
Startup Time
ClamAV takes 2-5 minutes to start because it must:
- Download/update virus definitions (first run)
- Load all signatures into memory
The Docker health check is configured with a 5-minute start_period to accommodate this.
Docker Deployment
1. Enable ClamAV with Docker Compose
Use the ClamAV override file alongside the main compose file:
docker compose -f docker-compose.yaml -f docker-compose.clamav.yaml up -dThis automatically:
- Adds the ClamAV service with proper resource limits
- Configures Mailpilot to wait for ClamAV to be healthy
- Creates a persistent volume for virus definitions
2. Enable in config.yaml
Add the antivirus configuration:
antivirus:
enabled: true
host: clamav # Docker service name
port: 3310 # ClamAV daemon port
timeout: 30s # Scan timeout per attachment
on_virus_detected: quarantine # quarantine | delete | flag_only3. Start the services
docker compose -f docker-compose.yaml -f docker-compose.clamav.yaml up -dWait for ClamAV to become healthy (2-5 minutes):
docker compose -f docker-compose.yaml -f docker-compose.clamav.yaml ps
# Wait until clamav shows "healthy"Tip: Create an alias or shell script to avoid typing the full command:
alias mailpilot-up='docker compose -f docker-compose.yaml -f docker-compose.clamav.yaml up -d'Actions on Virus Detection
| Action | Behavior |
|---|---|
quarantine | Move email to "Quarantine" folder, skip LLM processing |
delete | Delete the email immediately |
flag_only | Flag email with $Virus and \Flagged, continue processing |
Quarantine Folder
When using quarantine action, Mailpilot moves infected emails to a folder named "Quarantine". This folder is created automatically if it doesn't exist.
Review quarantined emails periodically - false positives are possible.
Non-Docker Deployment
If running Mailpilot outside Docker, install ClamAV separately:
Ubuntu/Debian
sudo apt install clamav clamav-daemon
sudo systemctl enable clamav-daemon
sudo systemctl start clamav-daemonmacOS
brew install clamav
# Edit /opt/homebrew/etc/clamav/clamd.conf
# Start: clamdConfiguration
Point Mailpilot to your ClamAV daemon:
antivirus:
enabled: true
host: localhost # or IP address
port: 3310Monitoring
Check ClamAV Status
# Docker (when using ClamAV override)
docker compose -f docker-compose.yaml -f docker-compose.clamav.yaml exec clamav clamdscan --version
# Check if responsive
docker compose -f docker-compose.yaml -f docker-compose.clamav.yaml exec clamav clamdscan --ping 1View Scan Logs
Mailpilot logs all scan results:
# Successful scans (debug level)
2024-01-15T10:30:00Z [DEBUG] [antivirus] Attachment clean {"filename":"report.pdf"}
# Virus detected (warn level)
2024-01-15T10:30:01Z [WARN ] [antivirus] Virus detected {"filename":"malware.exe","virus":"Win.Malware.Generic"}Troubleshooting
ClamAV Won't Start
Symptom: Container keeps restarting or stays unhealthy.
Cause: Usually insufficient memory.
Fix: Ensure at least 1GB RAM is available:
deploy:
resources:
limits:
memory: 2G
reservations:
memory: 1GScan Timeouts
Symptom: Scans fail with timeout errors.
Cause: Large attachments or slow system.
Fix: Increase timeout in config:
antivirus:
timeout: 60s # Increase from default 30sConnection Refused
Symptom: ECONNREFUSED errors in logs.
Cause: ClamAV not running or wrong host/port.
Fix:
- Check ClamAV is running:
docker compose -f docker-compose.yaml -f docker-compose.clamav.yaml ps - Verify host/port in config matches your setup
- If using Docker, use service name (
clamav) notlocalhost
High Memory Usage
Expected: ClamAV uses 1-2GB RAM by design.
If excessive: Check for memory leaks by restarting:
docker compose -f docker-compose.yaml -f docker-compose.clamav.yaml restart clamavPerformance Considerations
- Scan time: Typically 100-500ms per attachment
- Memory: Fixed ~1GB regardless of scan volume
- CPU: Spikes during scans, idle otherwise
- Network: Virus definitions update daily (~10MB)
For high-volume deployments, consider:
- Running ClamAV on a dedicated host
- Using multiple ClamAV instances behind a load balancer
- Caching scan results (not built-in, requires custom implementation)