MAATRIX / Блог / Mailtrain на Ubuntu 24.04: пошаговая установка

Mailtrain на Ubuntu 24.04: пошаговая установка

MAATRIX

Если рассылки для проекта переросли лимиты бесплатных SaaS-сервисов, а платить за каждую тысячу писем сторонним платформам не хочется — логичный шаг поставить свою систему рассылок на своём сервере. Mailtrain — open-source платформа для email-маркетинга с гибкой сегментацией подписчиков, кампаниями, шаблонами и статистикой открытий, которую можно развернуть за час и дальше не платить никому, кроме своего хостинга и SMTP-провайдера. Ниже — рабочая установка на чистом Ubuntu 24.04 через Docker Compose, с нуля до первой отправленной кампании.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →

Что такое Mailtrain и когда он оправдан

Mailtrain — это self-hosted аналог Mailchimp: списки подписчиков с произвольными полями, сегменты по условиям (например, "открыл последнее письмо, но не кликнул"), визуальный конструктор кампаний, A/B-тесты, автоматизация (триггерные цепочки), веб-хуки и REST API. Проект живёт на GitHub с версии 1 (Node.js + MySQL) и версии 2 (переписан, активная разработка).

Ставить свой Mailtrain имеет смысл, если:

  • у вас база от нескольких тысяч подписчиков и SaaS-тарифы уже кусаются;
  • нужна полная сегментация без ограничений тарифного плана;
  • важно держать данные подписчиков у себя, а не в чужом облаке;
  • есть SMTP-провайдер (или готовность настроить свой Postfix) для доставки.

Не имеет смысла, если рассылки редкие и небольшие (до пары сотен писем в месяц) — тут проще и дешевле остаться на бесплатном тарифе стороннего сервиса, а вопросы репутации IP и попадания в спам решает провайдер, а не вы.

Для работы нужен отдельный сервер — под очереди рассылки, MySQL и веб-интерфейс с запасом лучше брать от 2 ГБ RAM и 2 vCPU. Если сервера ещё нет, можно арендовать VPS в России, США или Великобритании — с оплатой картой или криптой, без привязки к зарубежным платёжным системам.

Подготовка сервера

Обновляем систему и ставим базовые зависимости:

apt update && apt upgrade -y
apt install -y curl git ufw

Если Docker ещё не установлен — разверните его по нашей отдельной инструкции: Docker на Ubuntu 24.04 с нуля. Кратко:

curl -fsSL https://get.docker.com | sh
systemctl enable --now docker
docker compose version

Создаём пользователя без root-прав (по желанию, но правильно с точки зрения безопасности) и добавляем его в группу docker:

adduser mailtrain
usermod -aG docker mailtrain

Открываем нужные порты в файрволе: SSH, HTTP/HTTPS для веб-интерфейса и панели администратора Mailtrain:

ufw allow OpenSSH
ufw allow 80/tcp
ufw allow 443/tcp
ufw enable

Отдельно порт для SMTP-исходящей отправки открывать не нужно — Mailtrain внутри контейнера будет ходить наружу к вашему SMTP-релею, а не принимать входящие письма.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

DNS: домен, поддомен и A-запись

Прежде чем ставить контейнеры, определитесь с доменной структурой. У Mailtrain обычно два адреса:

  • основной домен интерфейса, например mail.example.com — панель управления;
  • домен для трекинга кликов и открытий (может совпадать с основным).

В панели вашего DNS-провайдера (или в панели MAATRIX, если домен привязан там) добавьте A-запись, указывающую на IP сервера:

mail.example.com.   A   203.0.113.10

Подождите распространения DNS (обычно 5–30 минут, проверить можно через dig mail.example.com). Если домен и DNS вы настраиваете впервые — есть отдельный разбор: настройка домена и DNS с нуля (шаги применимы и к Ubuntu, там речь о самой логике DNS, а не о дистрибутиве).

Docker Compose: структура проекта

Создаём рабочую директорию и файл .env с переменными:

mkdir -p /opt/mailtrain && cd /opt/mailtrain

.env:

MYSQL_ROOT_PASSWORD=замените_на_сложный_пароль
MYSQL_PASSWORD=замените_на_другой_сложный_пароль
MAILTRAIN_HOSTNAME=mail.example.com
MAILTRAIN_WWW_SECRET=сгенерируйте_случайную_строку_32_символа
MAILTRAIN_ADMIN_ACCESS_KEY_FILE=/etc/mailtrain/access-token

Секрет и ключ доступа можно сгенерировать так:

openssl rand -hex 32

docker-compose.yml:

services:
  mongo:
    image: mongo:6
    restart: unless-stopped
    volumes:
      - mongo-data:/data/db

  redis:
    image: redis:7-alpine
    restart: unless-stopped
    volumes:
      - redis-data:/data

  mysql:
    image: mysql:8.0
    restart: unless-stopped
    environment:
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
      MYSQL_DATABASE: mailtrain
      MYSQL_USER: mailtrain
      MYSQL_PASSWORD: ${MYSQL_PASSWORD}
    volumes:
      - mysql-data:/var/lib/mysql

  mailtrain:
    image: mailtrain/mailtrain:latest
    restart: unless-stopped
    depends_on:
      - mysql
      - mongo
      - redis
    environment:
      MYSQL_HOST: mysql
      MYSQL_DATABASE: mailtrain
      MYSQL_USER: mailtrain
      MYSQL_PASSWORD: ${MYSQL_PASSWORD}
      MONGO_HOST: mongo
      REDIS_HOST: redis
      WWW_HOSTNAME: ${MAILTRAIN_HOSTNAME}
      WWW_SECRET: ${MAILTRAIN_WWW_SECRET}
      WWW_PROXY: "true"
    ports:
      - "127.0.0.1:3000:3000"
    volumes:
      - mailtrain-files:/app/server/files

volumes:
  mongo-data:
  redis-data:
  mysql-data:
  mailtrain-files:

Важный момент: Mailtrain использует три хранилища — MySQL для основной модели данных (списки, подписчики, кампании), MongoDB для логов и очередей, Redis для кеша и сессий. Это не опечатка и не избыточность — так устроена архитектура проекта начиная со второй версии. Публикуем контейнер только на 127.0.0.1:3000, наружу его отдаст обратный прокси с TLS.

Поднимаем стек:

docker compose up -d
docker compose logs -f mailtrain

Дождитесь строки о том, что сервер слушает порт, и что миграции базы данных прошли успешно — при первом запуске Mailtrain создаёт таблицы в MySQL сам, ждать нужно от 30 секунд до пары минут в зависимости от диска.

Обратный прокси и SSL

Проще всего поставить Caddy — он сам получит сертификат Let's Encrypt и обновит его без вашего участия. Если Caddy ещё не установлен, инструкция здесь: Caddy с авто-SSL на Ubuntu 24.04.

/etc/caddy/Caddyfile:

mail.example.com {
    reverse_proxy 127.0.0.1:3000
}
systemctl reload caddy

Через минуту-другую сертификат выпустится автоматически, и https://mail.example.com откроет страницу входа Mailtrain. Если предпочитаете nginx — тоже вариант, но тогда сертификат придётся выпускать отдельно через certbot; сравнение двух подходов есть в статье Caddy или nginx — что выбрать для сервера.

Первый вход и базовая настройка

Учётные данные администратора при первом запуске генерируются автоматически и пишутся в лог контейнера:

docker compose logs mailtrain | grep -i password

Если строку с паролем найти не удалось (в некоторых сборках она выводится только один раз при самой первой инициализации базы), сбросьте пароль администратора напрямую через MySQL:

docker compose exec mysql mysql -u root -p mailtrain
UPDATE users SET password = SHA2('новый_пароль', 256) WHERE username = 'admin';

Точное имя таблицы и алгоритм хеширования зависят от версии Mailtrain — свежий образ может использовать bcrypt вместо SHA2, тогда пароль лучше менять штатной формой восстановления через email, а не прямым UPDATE. Проверьте это в интерфейсе до того, как трогать базу руками.

После входа:

  1. Settings → Global — укажите WWW_HOSTNAME совпадающим с реальным доменом, если ещё не совпадает.
  2. Send Configuration — здесь настраивается транспорт отправки.
  3. Lists — создайте первый список подписчиков с полями (имя, email, произвольные атрибуты для сегментации).

Настройка отправки: SMTP-релей или свой Postfix

Mailtrain сам писем не доставляет — он формирует очередь и отдаёт её через SMTP-транспорт. Два рабочих варианта:

Вариант А — внешний SMTP-релей (проще и надёжнее для старта). Подходят сервисы вроде Amazon SES, Mailgun, SendGrid — они уже прогрели репутацию IP и берут на себя часть работы по доставляемости. В Send Configuration → SMTP укажите хост, порт, логин и пароль релея.

Вариант B — собственный Postfix на этом же или соседнем сервере. Даёт полный контроль, но требует отдельной настройки репутации IP, обратной DNS-записи (PTR) и постоянного мониторинга спам-листов. Если решите пойти этим путём — вот подробная установка: почтовый сервер Postfix на Ubuntu 24.04, а сравнение с готовым почтовым стеком — в статье Postfix или Mailcow — что выбрать для сервера.

Для рассылок объёмом от нескольких тысяч писем в месяц собственный Postfix без предварительного прогрева IP почти гарантированно приведёт к попаданию в спам — почтовые провайдеры (Gmail, Mail.ru, Яндекс) смотрят на историю IP, а не только на корректность настроек.

SPF, DKIM, DMARC — обязательный минимум

Без этих трёх записей в DNS письма будут либо отбрасываться, либо помечаться как подозрительные независимо от качества контента. Их настройка не зависит от того, используете вы SaaS-релей или свой Postfix — записи всегда добавляются на стороне DNS домена-отправителя.

Базовый SPF (пример для отправки через свой сервер, для внешнего релея провайдер даст свою строку):

example.com.   TXT   "v=spf1 ip4:203.0.113.10 ~all"

DKIM генерируется на стороне почтового транспорта (Postfix + OpenDKIM, либо панель релея выдаёт готовую запись) и публикуется как TXT-запись с публичным ключом. DMARC:

_dmarc.example.com.   TXT   "v=DMARC1; p=quarantine; rua=mailto:dmarc@example.com"

Подробный разбор всех трёх механизмов с примерами для разных сценариев — в статье как настроить SPF, DKIM и DMARC на VPS. Не пропускайте этот шаг ради экономии времени — без него дальнейшая настройка Mailtrain теряет смысл, письма просто не будут доходить.

Резервное копирование

Три хранилища — три места, которые нужно бэкапить. MySQL:

docker compose exec mysql mysqldump -u root -p mailtrain > mailtrain-$(date +%F).sql

MongoDB:

docker compose exec mongo mongodump --archive=/data/db/backup-$(date +%F).gz --gzip

Файлы вложений и шаблонов (том mailtrain-files):

docker run --rm -v mailtrain_mailtrain-files:/data -v $(pwd):/backup alpine \
  tar czf /backup/mailtrain-files-$(date +%F).tar.gz -C /data .

Собрать это в единый скрипт с cron-задачей — вопрос десяти минут; более общий разбор бэкапа Docker-томов и типичных ошибок есть в статье бэкап Docker volume на сервере.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.

Частые вопросы

Можно ли обойтись без Docker и поставить Mailtrain напрямую на систему?

Технически да, но официальный образ поддерживается активнее, чем инструкции по ручной установке зависимостей (Node.js нужной версии, MySQL, MongoDB, Redis по отдельности). Docker Compose из этой статьи — надёжнее и проще в обслуживании.

Почему письма уходят, но получатели их не видят?

В 9 случаях из 10 причина — отсутствующие или неверные SPF/DKIM/DMARC записи, либо отправка с "холодного" IP без репутации. Проверьте DNS-записи через dig TXT example.com и dig TXT _dmarc.example.com, и посмотрите репутацию IP через любой публичный чекер blacklists.

Сколько подписчиков потянет сервер на 2 ГБ RAM?

Для базы в несколько десятков тысяч контактов и умеренной частоты кампаний этого достаточно. При росте базы за сотню тысяч и активной сегментации в реальном времени стоит увеличить память под MySQL и MongoDB — конкретные пороги зависят от нагрузки, ориентируйтесь на мониторинг docker stats, а не на фиксированное число.

Нужен ли отдельный сервер под Mailtrain, если сайт уже крутится на VPS?

Не обязательно, если ресурсов хватает с запасом и сайт не критичен к простоям. Но при рассылках на десятки тысяч адресов очереди Mailtrain могут заметно нагружать CPU и диск — лучше разносить на отдельный инстанс, чтобы рассылка не влияла на доступность основного сайта.

Что делать, если после обновления образа Mailtrain перестал стартовать?

Проверьте логи docker compose logs mailtrain на предмет ошибок миграции базы — иногда новая версия ожидает схему MySQL, которой ещё нет. Перед обновлением на проде всегда делайте свежий дамп MySQL и Mongo, чтобы откатиться было куда.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →