Deploy Mautic
Open source email marketing, lead scoring and campaign automation
mautic-cron
Just deployed
MySQL
Just deployed
/var/lib/mysql
mautic-worker
Just deployed
mautic-web
Just deployed
/data
mailpit
Just deployed
/data

Deploy and Host Mautic on Railway
Mautic is the largest open source marketing automation platform. It stores contacts, groups them into segments, tracks what they do on your site, and runs campaigns that send email, score leads and hand qualified people to sales — the self-hosted answer to HubSpot and Mailchimp.
Deploy Mautic on Railway and the production topology comes up wired together: the web app, a queue worker, a cron service, managed MySQL and Mailpit as the mail hub. The web app queues email and tracking hits into MySQL, the worker consumes them, cron refreshes segments and drives campaigns, and mail leaves through Mailpit — point it at your own SMTP provider when ready. The first admin is created on first boot from two variables you fill in at deploy time.

Getting Started with Mautic on Railway
Fill in MAUTIC_ADMIN_EMAIL and MAUTIC_ADMIN_PASSWORD before deploying — those become your login. When the deploy finishes, open the mautic-web public URL and sign in. There is no public registration; further users are added under Settings → Users.
Create a contact under Contacts → New, then a segment filtered on Email — is not empty. It shows Building until cron runs mautic:segments:update on the quarter hour — the clearest proof the stack is live. To check delivery, open a contact and use Send email: the message is queued to MySQL, consumed by the worker and delivered to Mailpit, behind the MP_UI_AUTH credentials. The tracking script is under Settings → Configuration → Tracking Settings.

About Hosting Mautic
Marketing automation holds your most sensitive first-party data. Self-hosting Mautic keeps that database yours, removes per-contact pricing, and lets you send through a provider you already pay for.
Key features:
- Contacts with custom fields, companies, tags, stages and scoring
- Segments from behavioural and field filters, rebuilt on a schedule
- Drag-and-drop campaign builder with decisions, actions and waits
- Email builder with A/B testing, dynamic content and click tracking
- Landing pages, forms, site tracking and per-contact timelines
- REST API, webhooks and a plugin marketplace
Mautic ships as three roles sharing one codebase and database. Web serves the UI, API and tracking endpoints. Worker consumes the email and hit queues, so sending never blocks a web request. Cron runs the segment rebuilds and campaign triggers. Splitting them is upstream's recommendation and lets you scale sending independently of browsing.
Why Deploy Mautic on Railway
Railway removes the parts of self-hosting Mautic that go wrong.
- No Docker Compose, volume permissions or Apache tuning to get right
- Private networking between app, worker, cron, MySQL and mail host
- Managed MySQL with backups, not a container you babysit
- Managed TLS, a public URL on first deploy, custom domains later
- Scale the worker independently of the web app
Common Use Cases
- An opt-in newsletter with double opt-in, a preference centre and unsubscribe handling, sent through your own SES or Mailgun account
- SaaS trial onboarding drips that branch on whether the user logged in, opened the last email or hit the pricing page
- Lead scoring and hand-off: track visits, score behaviour, push contacts to a CRM over the REST API
Dependencies for Mautic
- Mautic —
mautic/mautic:7.1.2-apache, deployed as web, worker and cron from https://github.com/gridalpha/mautic-railway - MySQL — Railway managed; also backs the
doctrine://queues, so no broker is needed - Mailpit —
axllent/mailpit:latest, the SMTP endpoint every Mautic role sends through
Environment Variables Reference
| Variable | Description | Required |
|---|---|---|
MAUTIC_ADMIN_EMAIL | Email of the admin created on first boot | Yes |
MAUTIC_ADMIN_PASSWORD | Password for that admin; this is your login | Yes |
MAUTIC_SITE_URL | Public URL used in links and tracking pixels | Yes |
MAUTIC_SECRET_KEY | Encrypts integration credentials; same on all roles, never change it | Yes |
MAUTIC_MAILER_DSN | Symfony Mailer DSN for outbound mail | Yes |
MAUTIC_MESSENGER_DSN_EMAIL | Email queue transport; doctrine://default uses MySQL | Yes |
DOCKER_MAUTIC_ROLE | mautic_web, mautic_worker or mautic_cron | Yes |
MP_UI_AUTH | user:password protecting the Mailpit inbox | Yes |
Any setting works this way: parameter foo_bar is read from MAUTIC_FOO_BAR, and the environment beats config/local.php. Worker and cron do not share the web container's disk, so anything that must match across roles — the mail DSN especially — belongs in a variable, not the admin UI.
Deployment Dependencies
- Docker Hub: https://hub.docker.com/r/mautic/mautic
- Source: https://github.com/gridalpha/mautic-railway
- Docs: https://docs.mautic.org
- Runtime: PHP 8.4 with Apache, MySQL 8.0+ or MariaDB 10.4+
Server Requirements to Self-Host Mautic
| Resource | Minimum | Recommended |
|---|---|---|
| CPU | 1 vCPU per role | 2 vCPU web and worker |
| RAM | 1 GB web, 512 MB worker and cron | 2 GB web, 2 GB worker |
| Storage | 1 GB volume for config and media | 10 GB, plus MySQL growth |
| Database | MySQL 8.0+ / MariaDB 10.4+ | Managed MySQL with backups |
The image sets PHP's memory_limit to 512M — segment rebuilds are memory-hungry on large contact tables. Only the web role needs a volume.
How to Self-Host Mautic with Docker
Upstream publishes one image for all three roles:
x-mautic: &mautic
image: mautic/mautic:7.1.2-apache
volumes: ["config:/var/www/html/config", "media:/var/www/html/docroot/media"]
environment: &env
MAUTIC_DB_HOST: db
MAUTIC_DB_DATABASE: mautic
MAUTIC_DB_USER: root
MAUTIC_DB_PASSWORD: change-me
MAUTIC_MESSENGER_DSN_EMAIL: doctrine://default
MAUTIC_MESSENGER_DSN_HIT: doctrine://default
services:
db:
image: mysql:8
environment: { MYSQL_ROOT_PASSWORD: change-me, MYSQL_DATABASE: mautic }
volumes: ["mysql:/var/lib/mysql"]
mautic_web: { <<: *mautic, ports: ["8080:80"] }
mautic_worker: { <<: *mautic, environment: { <<: *env, DOCKER_MAUTIC_ROLE: mautic_worker } }
mautic_cron: { <<: *mautic, environment: { <<: *env, DOCKER_MAUTIC_ROLE: mautic_cron } }
volumes: { mysql: {}, config: {}, media: {} }
Then create the admin without the installer:
docker compose up -d
docker compose exec --user www-data --workdir /var/www/html mautic_web \
php bin/console mautic:install https://mautic.example.com \
--force --no-interaction \
--admin_email you@example.com --admin_password 'a-strong-password'
Pin the same tag on all three: they migrate one schema, and a floating tag lets one container land on a different release from the others.
Is Mautic Free?
Mautic is open source under the GPLv3 and free to run — no per-contact fees, no feature gating. On Railway you pay only for compute, database and storage. Third-party managed Mautic hosting starts around $16/month and runs to several hundred with an SLA. Your other real cost is email delivery, through whichever SMTP provider you supply.
Mautic vs HubSpot vs Mailchimp
| Mautic | HubSpot | Mailchimp | |
|---|---|---|---|
| Open source | Yes, GPLv3 | No | No |
| Self-hostable | Yes | No | No |
| Pricing | Infrastructure only | Per contact | Per contact |
| Lead scoring | Yes | Paid tiers | No |
| Data ownership | Your database | Vendor | Vendor |
Mautic trades polish for control. Choose it when data residency, cost at scale, or the ability to change the platform itself matter more than a managed experience.
FAQ
What is Mautic and why self-host it? An open source marketing automation platform covering contacts, segments, campaigns, email, landing pages and forms. Self-hosting keeps first-party behavioural data in a database you own.
What does this Railway template deploy? Five services: the web app on a public URL with a volume, a queue worker, a cron service, managed MySQL, and Mailpit as the mail hub with its own inbox.
Why does the template include a separate worker, cron and MySQL service?
Mautic queues outbound email and tracking hits rather than handling them in the web request, and the worker consumes those queues; cron runs the segment rebuilds and campaign triggers. Without both, email sits in the queue and campaigns never advance. Mautic supports MySQL and MariaDB only, and that database also backs the doctrine:// queues, so no broker is needed.
How do I send campaign email from self-hosted Mautic in production?
Set MAUTIC_MAILER_DSN on all three services to your provider's Symfony Mailer DSN — ses+smtp://KEY:SECRET@default, say, or smtp://user:pass@smtp.example.com:587. Or keep Mailpit in front and set its relay variables, which also keeps a searchable copy of everything sent. Keep MAUTIC_SECRET_KEY stable and pin the same tag on all three roles.
How do I add a custom domain to Mautic on Railway?
Attach the domain to mautic-web, then update MAUTIC_SITE_URL — that variable is what Mautic writes into tracking pixels, unsubscribe links and password-reset emails.
Template Content
mautic-cron
gridalpha/mautic-railwayMySQL
mysql:9.4mautic-worker
gridalpha/mautic-railwaymautic-web
gridalpha/mautic-railwaymailpit
axllent/mailpit:latest