Skip to main content

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).

ServiceIdle RAMPeak RAM (5k campaign)
mautic (Apache+PHP)780 MB1,400 MB
cron (background)250 MB600 MB
db (mariadb 10.11)330 MB380 MB
caddy15 MB20 MB
Total1,375 MB2,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 PlusMautic on Liquid Web
Monthly cost (1k contacts)~$49/mo (annual)~$33โ€“$40/mo VPS
Contact limitTiered (pay for contacts)Unlimited
Email campaignsโœ“โœ“
Landing pagesโœ“โœ“
Lead scoringโœ“โœ“
Multi-step automationโœ“โœ“
Self-hostableโœ—โœ“
LicenseProprietaryGPL-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.
Frequently Asked Questions

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.

Apify Affiliate Banner 728x90Apify Affiliate Banner 728x90Apify Affiliate Banner 300x50Apify Affiliate Banner 300x50