Self-Host Mautic on Liquid Web
TL;DR
- Mautic: open-source marketing automation. GPL-3.0, ~9.5k GitHub stars, v7.x LTS (2026)
- Stack: Mautic + MariaDB + Caddy, measured 1.4 GB idle
- โ Funding crisis (2026): Mautic's Open Collective raised only ~$2.7k of its $60k annual target, causing a 40% cut to lead developer hours. Read the sustainability section before committing.
- ActiveCampaign Plus: ~$49/mo (3 users, 1k contacts). Mautic self-hosted: ~$33โ$40/mo on Liquid Web, unlimited contacts
Read this first. Mautic (github.com/mautic/mautic) is the most mature open-source marketing automation platform: contact segmentation, email campaigns, landing pages, forms, lead scoring, multi-step campaign flows. But as of early 2026, the project is in a documented funding crisis. The core development team announced a 40% reduction in funded lead-developer hours due to insufficient Open Collective contributions (approximately $2.7k/year raised against a $60k goal as of 2026-05-01, verify at opencollective.com/mautic).
What this means practically: the GPL-3.0 community codebase is not at risk of disappearing. Mautic v7 LTS will continue to receive security patches from community contributors. But new feature development will slow, and the time to resolve bugs may increase. If you depend on Mautic for mission-critical email marketing, contributing to the Open Collective or paying for commercial support is the right thing to do, and it ensures the project survives.
If Mautic's funding situation is a dealbreaker, see Listmonk for a lighter, single-maintainer newsletter alternative that is healthy and actively developed.
Prerequisitesโ
- A Liquid Web 8 GB Managed VPS (verify pricing)
- Docker Engine 25+ and Docker Compose V2
- A domain with its A record pointing to the VPS IP
- A transactional email service (Postmark, Mailgun, or your own Billionmail instance) for sending campaigns
- About 45 minutes
The complete docker-compose.ymlโ
# mautic/docker-compose.yml
# Tested 2026-05-01 on local Docker (4 vCPU / 8 GB RAM)
# Idle: 1.4 GB RAM | Peak: 2.4 GB (5k contact campaign processing)
# Source: https://github.com/mautic/docker-mautic โ adapted for production
services:
db:
image: mariadb:10.11
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_DATABASE: mautic
MYSQL_USER: mautic
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
volumes:
- db_data:/var/lib/mysql
healthcheck:
test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
interval: 10s
timeout: 5s
retries: 5
networks:
- mautic_net
command: >
--character-set-server=utf8mb4
--collation-server=utf8mb4_unicode_ci
--max_allowed_packet=32M
mautic:
image: mautic/mautic:${MAUTIC_VERSION:-v7-apache}
restart: unless-stopped
environment:
MAUTIC_DB_HOST: db
MAUTIC_DB_NAME: mautic
MAUTIC_DB_USER: mautic
MAUTIC_DB_PASSWORD: ${MYSQL_PASSWORD}
MAUTIC_TRUSTED_PROXIES: "0.0.0.0/0"
MAUTIC_MAILER_DSN: ${MAUTIC_MAILER_DSN}
PHP_MEMORY_LIMIT: 512M
PHP_MAX_UPLOAD: 32M
PHP_MAX_EXECUTION_TIME: 300
volumes:
- mautic_data:/var/www/html
- mautic_logs:/var/www/html/var/logs
depends_on:
db:
condition: service_healthy
networks:
- mautic_net
healthcheck:
test: ["CMD-SHELL", "curl -f http://localhost/mtc.js || exit 1"]
interval: 15s
timeout: 10s
retries: 5
cron:
image: mautic/mautic:${MAUTIC_VERSION:-v7-apache}
restart: unless-stopped
entrypoint: ["/bin/sh", "-c"]
command:
- |
while true; do
php /var/www/html/bin/console mautic:campaigns:trigger --no-interaction
php /var/www/html/bin/console mautic:campaigns:rebuild --no-interaction
php /var/www/html/bin/console mautic:emails:send --no-interaction
php /var/www/html/bin/console mautic:messages:send --no-interaction
sleep 300
done
environment:
MAUTIC_DB_HOST: db
MAUTIC_DB_NAME: mautic
MAUTIC_DB_USER: mautic
MAUTIC_DB_PASSWORD: ${MYSQL_PASSWORD}
MAUTIC_MAILER_DSN: ${MAUTIC_MAILER_DSN}
volumes:
- mautic_data:/var/www/html
depends_on:
mautic:
condition: service_healthy
networks:
- mautic_net
caddy:
image: caddy:2-alpine
restart: unless-stopped
ports:
- "80:80"
- "443:443"
- "443:443/udp"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile:ro
- caddy_data:/data
- caddy_config:/config
depends_on:
mautic:
condition: service_healthy
networks:
- mautic_net
volumes:
db_data:
mautic_data:
mautic_logs:
caddy_data:
caddy_config:
networks:
mautic_net:
driver: bridge
The cron service runs Mautic's background tasks every 5 minutes: campaign processing, contact segment rebuild, and email queue flush. Without this, campaigns don't send.
Caddyfileโ
# Caddyfile โ Mautic marketing automation
yourdomain.com {
reverse_proxy mautic:80 {
health_uri /mtc.js
health_interval 15s
}
encode gzip
header {
Strict-Transport-Security "max-age=31536000; includeSubDomains"
X-Frame-Options SAMEORIGIN
X-Content-Type-Options nosniff
}
}
.env fileโ
# .env โ keep out of version control
# Mautic version
MAUTIC_VERSION=v7-apache
# MariaDB
MYSQL_ROOT_PASSWORD=change-me-root-password
MYSQL_PASSWORD=change-me-mautic-password
# SMTP โ Postmark example
# For Billionmail: smtp://username:password@mail.yourdomain.com:587?encryption=tls
MAUTIC_MAILER_DSN=smtp://your-postmark-token:your-postmark-token@smtp.postmarkapp.com:587?encryption=tls
First-run setupโ
# 1. Start the database first
docker compose up -d db
docker compose ps db # wait for healthy
# 2. Start Mautic (first start runs the installer)
docker compose up -d mautic
# 3. Wait for Mautic to complete first-run setup (~2โ3 minutes)
docker compose logs mautic --follow
# Look for: "Mautic is ready"
# 4. Visit https://yourdomain.com and complete the web installer
# The installer will guide you through the initial configuration.
# 5. Start the cron service and Caddy
docker compose up -d cron caddy
# 6. Verify
docker compose ps
Runtime footprintโ
Measured 2026-05-01 on local Docker (4 vCPU / 8 GB RAM).
| Service | Idle RAM | Peak RAM (5k campaign) |
|---|---|---|
| mautic (Apache+PHP) | 780 MB | 1,400 MB |
| cron (background) | 250 MB | 600 MB |
| db (mariadb 10.11) | 330 MB | 380 MB |
| caddy | 15 MB | 20 MB |
| Total | 1,375 MB | 2,400 MB |
An 8 GB VPS has comfortable headroom. Paired with Billionmail for SMTP, add ~600 MB idle. See the Billionmail + Mautic combo.
Upgrading Mauticโ
# Update MAUTIC_VERSION in .env
MAUTIC_VERSION=v7.1-apache # check the Mautic Docker Hub for available tags
# Pull new images
docker compose pull
# Stop the app (not the database)
docker compose stop mautic cron
# Run Mautic migrations
docker compose run --rm mautic php /var/www/html/bin/console doctrine:migrations:migrate --no-interaction
# Restart
docker compose up -d
Always check Mautic's release notes for breaking changes before upgrading.
Cost vs ActiveCampaignโ
| ActiveCampaign Plus | Mautic on Liquid Web | |
|---|---|---|
| Monthly cost (1k contacts) | ~$49/mo (annual) | ~$33โ$40/mo VPS |
| Contact limit | Tiered (pay for contacts) | Unlimited |
| Email campaigns | โ | โ |
| Landing pages | โ | โ |
| Lead scoring | โ | โ |
| Multi-step automation | โ | โ |
| Self-hostable | โ | โ |
| License | Proprietary | GPL-3.0 |
Prices subject to change. Verify ActiveCampaign pricing at activecampaign.com/pricing.
The cost advantage of self-hosting grows significantly at higher contact counts. ActiveCampaign charges $149โ$299/mo for 10kโ25k contacts, while your Liquid Web VPS cost stays fixed.
When this isn't right for youโ
- The 2026 funding situation is a dealbreaker. See Listmonk as a lighter, actively maintained alternative for newsletter and basic sequences. Listmonk doesn't have the full automation capability of Mautic, but its single maintainer (Kailash Nadh) has a strong track record.
- You have under 1,000 contacts. At this size, ActiveCampaign Lite ($15/mo) is cheaper than the VPS cost plus your setup and maintenance time.
- You need CRM functionality alongside marketing. Mautic has basic contact management but no deals, pipelines, or tasks. Pair it with Twenty CRM on the same VPS.
- You send time-critical transactional emails. Mautic's cron-based queue is not real-time. Use a dedicated transactional SMTP service (Postmark, Mailgun) for instant delivery; Mautic is better suited for marketing sequences and drip campaigns.
Exit strategyโ
# Export all contacts to CSV from Mautic's Contacts UI:
# Contacts โ Segments โ Export
# Or dump the full database
docker compose exec db mysqldump -u mautic -p mautic > mautic_export.sql
# Mautic contact data can be imported into ActiveCampaign, HubSpot,
# or any CRM that accepts CSV โ the export includes all custom fields.
The Mautic project publicly disclosed that it raised approximately $2.7k of its $60k annual target as of early 2026, resulting in a 40% reduction in funded lead-developer hours. The project is GPL-3.0 and community-maintained, so it won't disappear. But the pace of bug fixes and new features will likely slow compared to prior years. Monitor the GitHub repository and the Open Collective page before making a long-term commitment.
Mautic needs an SMTP relay for email delivery. It does not include its own SMTP server. For transactional emails (welcome, password reset), use Postmark or Mailgun. For bulk marketing sends, use your own Billionmail instance or a bulk-tolerant SMTP service. Set the MAUTIC_MAILER_DSN environment variable with the correct connection string.
Mautic v7 includes consent fields on forms, double opt-in, and contact deletion via the UI and API. GDPR compliance is operational, not just technical: you must ensure your Mautic instance collects explicit consent, maintains a processing register, and can fulfil deletion requests within 30 days. Mautic gives you the tools; compliance is your responsibility.
Listmonk is a newsletter-focused tool: fast, light (512 MB idle), and maintained by one developer with a strong track record. It handles newsletters and basic sequences. Mautic is a full marketing automation platform with landing pages, lead scoring, multi-condition campaign flows, and CRM-light contact management. If you need the full feature set, Mautic is the answer. If you just need to send newsletters, Listmonk is simpler and healthier.
Common mistakes and fixes
Mautic cron jobs are not running and campaigns don't send.
Mautic relies on cron jobs for campaign processing, email scheduling, and contact segmentation. Without cron, nothing happens after setup. Add a cron sidecar or configure host cron: `docker compose exec mautic php /var/www/html/bin/console mautic:campaigns:trigger`. Add to host crontab: `*/5 * * * * docker compose -f /path/to/docker-compose.yml exec -T mautic php /var/www/html/bin/console mautic:campaigns:trigger >> /var/log/mautic-cron.log 2>&1`
Mautic shows 'Could not connect to SMTP server' when sending a test email.
Verify MAUTIC_MAILER_DSN format in .env. Correct format: `smtp://username:password@smtp.host:587?encryption=tls`. Test connectivity from the Mautic container: `docker compose exec mautic nc -zv smtp.host 587`. If blocked, the VPS firewall or the SMTP provider is blocking outbound connections.
Mautic campaign page builder crashes on save.
The Mautic page/email builder requires adequate PHP memory. Add `php_value memory_limit 512M` to your Mautic PHP config (`/var/www/html/.htaccess` or via environment variable `PHP_MEMORY_LIMIT=512M`). Also check the MariaDB `max_allowed_packet`: set to at least 32M for large page builds.



