Отладка отправки электронной почты на этапе разработки или тестирования сайтов — один из самых коварных этапов работы сисадмина и вебмастера. Ошибка в конфигурации скрипта оформления заказа или сброса пароля может привести к тому, что сотни тестовых писем отправятся реальным клиентам интернет-магазина либо пробьют лимиты стороннего почтового шлюза и приведут к блокировке IP-адреса сервера в спам-базах.
Золотое правило безопасного тестирования: на тестовых стендах, стейджинге и локальных серверах отправка писем наружу должна быть физически заблокирована. Вместо боевого SMTP-релея используется локальный перехватчик сообщений (SMTP sink/catcher), сохраняющий всю почту в изолированную базу для визуальной инспекции.
Зачем нужен перехватчик писем и почему устарел MailHog
Долгие годы отраслевым стандартом среди разработчиков оставалась утилита MailHog. Однако её активная разработка прекратилась несколько лет назад: проект перестал получать обновления безопасности, страдает от утечек памяти в браузере при накоплении нескольких тысяч сообщений и не поддерживает современные возможности анализа верстки.
Ей на смену пришел Mailpit — современный, сверхбыстрый и надежный инструмент для тестирования почты, созданный новозеландским инженером Майклом Хендерсоном (axllent). Mailpit написан на языке Go, обладает продуманным веб-интерфейсом на Vue 3 и решает ключевые боли специалистов:
- Гарантия безопасности: письма перехватываются внутри инфраструктуры и не покидают сервер. Риск случайной рассылки клиентам равен нулю.
- Моментальный рендеринг: поддержка HTML и Plain Text версий, предварительный просмотр для мобильных устройств, планшетов и ПК с возможностью проверки адаптивности.
- Встроенный анализ спама: автоматическая оценка письма встроенным анализатором спам-триггеров (проверка проблемных ссылок, заголовков и структуры).
- Инспекция вложений и сырых данных: скачивание любых прикрепленных файлов, просмотр MIME-заголовков (Message-ID, Return-Path, DKIM).
- Автоматизация и CI/CD: полноценный REST API для интеграции с тестами (Playwright, Cypress, Selenium, PHPUnit).
| Критерий | MailHog (Устаревший) | Mailpit (Современный стандарт) |
|---|---|---|
| Статус проекта | Заброшен, нет релизов с 2020 года | Активная поддержка (актуальная ветка v1.31+) |
| Потребление RAM | 80–150 МБ (растет при нагрузке) | 15–30 МБ (сверхлегкий Go-бинарник) |
| Интерфейс | Устаревший Bootstrap 3, зависает при поиске | Современный Vue 3, мгновенный живой поиск |
| Адаптивный предпросмотр | Отсутствует | Встроенный эмулятор мобильных экранов |
| Анализ спама | Нет | Встроенный анализатор спам-рейтинга |
Архитектура Mailpit: потребление 15 МБ RAM, порты и SQLite
Mailpit скомпилирован в единый бинарный файл без внешних тяжелых зависимостей. Для работы сервиса задействуются два ключевых сетевых порта:
1025— порт внутреннего SMTP-сервера. Ваши сайты (WordPress, Bitrix), фреймворки (Laravel, Django, FastAPI) или микросервисы подключаются к нему по стандартному протоколу SMTP без шифрования (STARTTLS поддерживается при необходимости).8025— порт веб-интерфейса и REST API. Сервис отдает современный дашборд и держит WebSocket-соединение для мгновенной доставки новых писем на экран браузера без перезагрузки вкладки.
По умолчанию Mailpit может работать полностью в оперативной памяти (режим :memory:), однако в реальной практике удобно сохранять историю между перезапусками контейнеров. Для этого активируется встроенная база данных SQLite, размещаемая на постоянном томе (volume). Встроенный механизм автоматической ротации (pruning) следит за тем, чтобы количество писем не превышало заданный лимит (например, 5000), предотвращая разрастание диска.
Развертывание Mailpit в Docker Compose: production-манифест
Для надежной и изолированной работы создадим выделенный каталог на VDS и подготовим конфигурационные файлы. Подключитесь к серверу по SSH и выполните команды:
sudo mkdir -p /opt/mailpit/data
cd /opt/mailpit
sudo chown -R 1000:1000 /opt/mailpit/data
Создайте файл переменных окружения .env для безопасного хранения пароля от веб-интерфейса. Для генерации надежного пароля воспользуйтесь нашим генератором генератор стойких паролей SysKit:
# /opt/mailpit/.env
MAILPIT_UI_USER=admin
MAILPIT_UI_PASS=SuperSecureSecretPassword2026!
TZ=Europe/Moscow
Теперь сформируем манифест docker-compose.yml. Обратите особое внимание на привязку портов к 127.0.0.1: публикация сервиса на локальный интерфейс гарантирует, что почтовый перехватчик не станет открытым релеем для сканеров интернета:
services:
mailpit:
image: axllent/mailpit:latest
container_name: mailpit
restart: unless-stopped
ports:
# Публикуем порты только на локальном интерфейсе хоста
- "127.0.0.1:1025:1025"
- "127.0.0.1:8025:8025"
environment:
- MP_DATABASE=/data/mailpit.db
- MP_MAX_MESSAGES=5000
- MP_SMTP_AUTH_ACCEPT_ANY=1
- MP_UI_AUTH=${MAILPIT_UI_USER}:${MAILPIT_UI_PASS}
- TZ=${TZ}
volumes:
- ./data:/data
networks:
- mailpit_net
mem_limit: 128m
deploy:
resources:
limits:
memory: 128M
networks:
mailpit_net:
name: mailpit_net
driver: bridge
Разберем важные параметры конфигурации:
MP_DATABASE=/data/mailpit.db— указывает путь к базе данных SQLite на монтируемом томе./data. Все письма сохраняются при перезагрузках контейнера.MP_MAX_MESSAGES=5000— лимит сообщений. При получении 5001-го письма самое старое автоматически удаляется, защищая диск VDS от переполнения.MP_SMTP_AUTH_ACCEPT_ANY=1— разрешает приложениям отправлять письма с любыми фиктивными логинами и паролями (удобно, когда в разных проектах вписаны разные тестовые реквизиты).MP_UI_AUTH— устанавливает базовую авторизацию (HTTP Basic Auth) на вход в веб-интерфейс, защищая его от неавторизованного доступа.mem_limit: 128m— строгий лимит памяти на уровне Docker Engine для предотвращения аварийного завершения других служб сервера.
Запустите контейнер в фоновом режиме:
sudo docker compose up -d
Убедитесь, что контейнер успешно стартовал и слушает порты локально:
sudo docker compose ps
ss -tulpn | grep -E '1025|8025'
Если вы хотите проверить доступность портов сервера снаружи, воспользуйтесь нашим сетевым сканером проверка портов онлайн (Port Checker): порты 1025 и 8025 обязаны быть закрыты для внешнего мира.
Nginx Reverse Proxy: SSL, WebSocket и защита веб-интерфейса
Поскольку порт веб-интерфейса 8025 привязан строго к 127.0.0.1, прямой доступ из браузера закрыт. Для удобной и безопасной работы команды через поддомен (например, mailpit.yourdomain.com) настроим Nginx в качестве обратного прокси-сервера (Reverse Proxy) с бесплатным SSL-сертификатом от Let's Encrypt.
Важное требование безопасности Mailpit (v1.29+): веб-интерфейс Mailpit проверяет заголовок Origin для защиты от межсайтовых атак (CSRF). При настройке проксирования обязательно передавайте заголовок proxy_set_header Host $http_host;. Если передать нестандартный или пустой заголовок, веб-интерфейс будет блокировать входящие HTTP-запросы.
Также Mailpit активно использует постоянное WebSocket-соединение для мгновенной доставки уведомлений о новых письмах на экран без перезагрузки страницы. Без проброса заголовков Upgrade и Connection интерфейс будет регулярно выдавать ошибку соединения с сервером.
Создайте конфигурационный файл виртуального хоста в Nginx:
sudo nano /etc/nginx/sites-available/mailpit.conf
Вставьте базовую конфигурацию для порта 80, готовую к получению SSL-сертификата:
server {
listen 80;
listen [::]:80;
server_name mailpit.yourdomain.com;
location / {
proxy_pass http://127.0.0.1:8025;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Проксирование WebSocket для живого обновления входящих
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
# Буферизация и таймауты
proxy_buffering off;
proxy_read_timeout 86400s;
proxy_send_timeout 86400s;
}
}
Активируйте конфигурацию символической ссылкой и выполните проверку синтаксиса Nginx:
sudo ln -s /etc/nginx/sites-available/mailpit.conf /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
Теперь выпустите бесплатный доверенный SSL-сертификат Let's Encrypt с автоматической настройкой редиректа на HTTPS:
sudo certbot --nginx -d mailpit.yourdomain.com --redirect
Утилита Certbot автоматически обновит файл конфигурации, добавит сертификаты и настроит безопасный редирект с HTTP на HTTPS. Проверить корректность цепочки сертификатов и срок их действия вы можете через наш бесплатный инструмент проверка SSL-сертификата онлайн (SSL Checker), а для гибкой генерации конфигов серверов используйте наш генератор конфигурации Nginx.
Теперь при переходе по адресу https://mailpit.yourdomain.com браузер запросит логин и пароль, настроенные в переменной MP_UI_AUTH, после чего откроется полнофункциональная панель управления почтой.
Подключение к проектам: WordPress, Laravel, Node.js и Docker-сети
После запуска Mailpit готов мгновенно принимать корреспонденцию от любых веб-приложений и сервисов. Рассмотрим типовые конфигурации для популярных платформ и стеков.
1. Взаимодействие внутри Docker-сети
Если ваше веб-приложение (например, контейнер с бэкендом или CMS) развернуто в соседнем docker-compose.yml, вы можете объединить их в общую сеть mailpit_net. В этом случае обращение происходит по внутреннему имени сервиса:
# docker-compose.yml вашего веб-приложения
services:
web_app:
image: my-company-app:latest
environment:
- SMTP_HOST=mailpit
- SMTP_PORT=1025
networks:
- app_net
- mailpit_net
networks:
app_net:
mailpit_net:
external: true
При такой схеме трафик вообще не выходит на внешний сетевой интерфейс и циркулирует изолированно внутри виртуального моста Docker.
2. Настройка в PHP и Laravel
Во фреймворке Laravel достаточно указать реквизиты в файле .env. Благодаря флагу MP_SMTP_AUTH_ACCEPT_ANY=1 логин и пароль можно оставить пустыми либо указать произвольные:
MAIL_MAILER=smtp
MAIL_HOST=127.0.0.1
MAIL_PORT=1025
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
MAIL_FROM_ADDRESS="no-reply@dev.local"
MAIL_FROM_NAME="Test Project"
Для проверки отправки из консоли выполните artisan-команду:
php artisan tinker --execute="Mail::raw('Тестовое письмо из Laravel', fn($m) => $m->to('client@example.com')->subject('Проверка Mailpit'));"
3. Настройка в WordPress
В WordPress настроить перенаправление писем можно через любой популярный плагин (например, WP Mail SMTP или FluentSMTP) либо добавив легкий хук в файл functions.php вашей темы:
add_action('phpmailer_init', function($phpmailer) {
$phpmailer->isSMTP();
$phpmailer->Host = '127.0.0.1';
$phpmailer->Port = 1025;
$phpmailer->SMTPAuth = false;
$phpmailer->SMTPSecure = '';
});
Проверить отправку через WP-CLI можно одной строкой:
wp eval 'wp_mail("customer@test.ru", "Заказ #12345 оформлен", "Спасибо за покупку в тестовом магазине!");'
4. Интеграция в Node.js (Nodemailer)
В Node.js-проектах стандартным решением является библиотека Nodemailer:
const nodemailer = require('nodemailer');
const transporter = nodemailer.createTransport({
host: '127.0.0.1',
port: 1025,
secure: false, // TLS не требуется для локального порта
tls: {
rejectUnauthorized: false
}
});
async function sendTestEmail() {
const info = await transporter.sendMail({
from: '"Dev System" <noreply@system.local>',
to: 'tester@company.ru',
subject: 'Код подтверждения: 849201',
html: '<h1>Ваш одноразовый код</h1><p>Код: <b>849201</b></p>'
});
console.log('Письмо успешно перехвачено Mailpit: %s', info.messageId);
}
sendTestEmail();
5. Интеграция в Python
Стандартная библиотека Python позволяет отправить тестовое письмо без установки сторонних пакетов:
import smtplib
from email.message import EmailMessage
msg = EmailMessage()
msg['Subject'] = 'Сброс пароля пользователя'
msg['From'] = 'auth@company.internal'
msg['To'] = 'user@domain.com'
msg.set_content('Здравствуйте! Для сброса пароля перейдите по ссылке...')
with smtplib.SMTP('127.0.0.1', 1025) as server:
server.send_message(msg)
print("Сообщение отправлено в Mailpit!")
Проверка спам-рейтинга, мобильный рендер и REST API для CI/CD
Ключевое преимущество Mailpit перед старыми аналогами — мощный встроенный инструментарий визуального и технического аудита писем прямо в окне браузера.
1. Адаптивный рендеринг для мобильных устройств
В правом верхнем углу просмотра письма в Mailpit доступны переключатели экранов: Mobile, Tablet и Desktop. Они позволяют мгновенно проверить, не расползается ли табличная HTML-верстка рассылки, корректно ли масштабируются изображения и читабельны ли кнопки действий (CTA) на экранах смартфонов.
2. Встроенный аудит спам-факторов
Во вкладке Spam Mailpit проводит автоматический скоринг структуры сообщения по алгоритмам, аналогичным SpamAssassin. Система анализирует:
- Соотношение объема текста и изображений в теле письма.
- Наличие потенциально подозрительных или сокращенных ссылок.
- Корректность формирования обязательных технических заголовков (
Date,Message-ID,From,Subject). - Отсутствие текстовой версии (Plain Text Multipart) при наличии HTML.
Подробнее о том, как формировать письма для максимальной доставляемости на боевых почтовых серверах, читайте в нашей статье как настроить почту на VDS без попадания в спам и руководстве по проверке IP-адреса в спам-базах DNSBL.
3. Автоматизация тестирования через REST API
Mailpit предоставляет быстрый REST API со спецификацией OpenAPI. Это позволяет встраивать проверку почты в сквозные автотесты (E2E) на базе Playwright, Cypress или Python:
# Получить список последних 10 сообщений
curl -s -u admin:SuperSecureSecretPassword2026! https://mailpit.yourdomain.com/api/v1/messages?limit=10 | jq .
# Очистить почтовый ящик перед началом прогона тестов
curl -s -X DELETE -u admin:SuperSecureSecretPassword2026! https://mailpit.yourdomain.com/api/v1/messages
Пример проверки получения одноразового кода авторизации в тестах:
// Тестовый фрагмент для Playwright / Node.js
const res = await fetch('https://mailpit.yourdomain.com/api/v1/messages?query=to:tester@company.ru');
const data = await res.json();
const latestEmail = data.messages[0];
// Извлекаем код из темы или тела письма
const code = latestEmail.Subject.match(/\d{6}/)[0];
console.log('Извлеченный код из письма:', code);
Рекомендуемые VDS-провайдеры
Отказоустойчивые сервера с быстрыми NVMe и каналом до 1 Гбит/с
Timeweb Cloud — Быстрые NVMe VDS
Сверхбыстрые NVMe-диски и моментальный отклик позволяют развернуть Mailpit рядом с вашими тестовыми сайтами без просадок производительности.
Selectel — Корпоративная надежность Tier III
Идеальная площадка для создания тестовых стендов, стейджинга и CI/CD-пайплайнов с автоматическим прогоном почтовых сценариев.
Beget — Простота и отказоустойчивость
Развертывание Docker в один клик, удобный терминал и бесплатные автоматические бэкапы всей инфраструктуры VDS.
Ротация базы сообщений, резервное копирование и диагностика сбоев
Благодаря архитектуре на SQLite и встроенному сборщику мусора Mailpit практически не требует ручного вмешательства администратора. Тем не менее полезно знать ключевые эксплуатационные нюансы.
Автоматическая ротация и лимиты диска
Параметр MP_MAX_MESSAGES=5000 гарантирует, что количество писем в базе /opt/mailpit/data/mailpit.db не превысит заданное значение. Однако в SQLite при удалении строк размер файла базы на диске автоматически не уменьшается (страницы помечаются как свободные для повторного использования). Если вы провели массированное нагрузочное тестирование с миллионами писем, можно выполнить сжатие базы:
sudo docker compose exec mailpit sh -c "sqlite3 /data/mailpit.db 'VACUUM;'"
Резервное копирование
Поскольку база SQLite находится в локальном каталоге /opt/mailpit/data, для бэкапа достаточно скопировать каталог или включить его в регулярные снимки сервера:
sudo tar -czf /opt/mailpit-backup-$(date +%F).tar.gz -C /opt/mailpit data
Для настройки автоматических шифрованных бэкапов в облако рекомендуем использовать наш гайд по связке Restic и Autorestic для бэкапов Docker в S3.
Типичные неполадки и их решение
| Симптом | Причина | Способ устранения |
|---|---|---|
| Connection refused на порту 1025 | Контейнер не запущен либо приложение пытается подключиться к внешнему IP | Проверьте статус docker compose ps. Если приложение в Docker, подключайтесь по имени сервиса mailpit:1025, если на хосте — к 127.0.0.1:1025. |
| Веб-интерфейс отклоняет запросы | Несоответствие заголовка Origin в Nginx (Mailpit v1.29+) | Убедитесь, что в блоке Nginx указана директива proxy_set_header Host $http_host;. |
| Письма появляются только после обновления страницы (F5) | Nginx не проксирует WebSocket-соединение | Добавьте заголовки proxy_set_header Upgrade $http_upgrade; и proxy_set_header Connection "Upgrade"; в конфигурацию Nginx. |
Резюме: Mailpit — это идеальный инструмент разработчика и сисадмина, сочетающий микроскопическое потребление ресурсов (15–20 МБ RAM), абсолютную защиту от спама реальных пользователей и богатый арсенал для визуального и автоматизированного тестирования верстки писем.