# Mailpit: мастерская почтовых уведомлений

8 задач / 16 вариантов. Авторский код MIT, зависимости имеют собственные лицензии.
Mailpit 1.33.1, Nodemailer 10.5.0, PHPMailer 7.2.0. Нужны Node.js 24+, PHP 8.2+, Composer 2 и Docker Compose v2.

Публичная мастерская воспроизводит сохранённые результаты настоящих SMTP/HTTP-операций. В браузере нет SMTP-сервера: новый запуск выполняется командами ниже. Мини-конструктор изменяет и скачивает шаблон, но не отправляет письмо.

## Windows / PowerShell

Откройте терминал в распакованном mailpit-project. Запустите Docker Desktop с Linux containers.

```powershell
npm ci --ignore-scripts
composer install --no-dev --no-interaction --prefer-dist
docker compose up -d mailpit chaos
npm test
npm run capture
npm run serve
```

Откройте http://127.0.0.1:8533 — мастерская. Настоящий интерфейс Mailpit: http://127.0.0.1:18025.
SMTP для приложений хоста: 127.0.0.1:11025; отдельный Chaos: 127.0.0.1:11026.
Для отдельного PHP-письма: `php php/send.php manual 1`. Последовательный повтор разрешён, но Message-ID будет тем же; для независимого теста задайте новый первый аргумент, например manual2.

## Linux: те же исходники

С установленными PHP, Composer и Node выполняйте те же команды. Для записи с меткой Linux:

```bash
npm ci --ignore-scripts
composer install --no-dev --no-interaction --prefer-dist
docker compose up -d mailpit chaos
npm test
CAPTURE_NAME=linux npm run capture
npm run serve
```

Для полностью контейнерного повтора PHP + Node:

```bash
docker compose build linux
docker compose run --rm linux
```

Этот образ устанавливает зависимости из lock-файлов и выполняет тесты/все 16 вариантов. Mailpit работает в отдельных сервисах. Из контейнера используется имя `mailpit:1025`, а не localhost. Windows-драйвер и Linux-драйвер могут обращаться к одному локальному Docker-стенду; каждый запуск изолирован уникальным Message-ID. Даты, UUID и общая численность писем между запусками закономерно отличаются.

## Linux/VPS: закрытый почтовый стенд

Разместите проект, например, в `/srv/mailpit-workshop`. Права на исходники и Docker выдайте только администратору проекта. `docker compose up -d mailpit chaos` публикует порты исключительно на 127.0.0.1 хоста. Внешний SMTP relay/forwarding не настроен. Не меняйте привязку на 0.0.0.0 ради удобства доступа.

С рабочего компьютера:

```bash
ssh -N -L 18025:127.0.0.1:18025 user@your-server
```

После этого локальный http://127.0.0.1:18025 показывает Mailpit на сервере. Для реального приложения в общей Docker-сети достаточно внутреннего SMTP-порта 1025; публикацию SMTP-порта на хост можно убрать. Если нужен общий браузерный доступ команде, отдельно настройте HTTPS, аутентификацию и сетевые ограничения согласно официальной документации. Публичный сайт статьи не является таким сервером.

## Что проверять

1. Первое Node.js-письмо: русский/английский текст.
2. PHPMailer: HTML + AltBody, имя со спецсимволами.
3. CSV/JSON: MIME-вложение и побайтовое сравнение скачанного файла.
4. Reply-To, Cc/Bcc: Mailpit знает SMTP envelope и показывает всех получателей теста.
5. Теги и поиск: `messages_count` — совпадения; `total` — весь ящик.
6. Контракт: SMTP-принятие не доказывает правильность темы/содержимого.
7. Chaos: 451 при MAIL FROM. Второй вариант использует исправный порт; автоматический retry не реализован.
8. Поиск по точному Message-ID вместо «последнего письма» в общем ящике.

Проверка не доказывает боевую доставляемость, прохождение SPF/DKIM/DMARC, отображение во всех клиентах или отсутствие попадания в спам. Такие этапы проверяются отдельно.

## Файлы, данные и остановка

- `src/mail.mjs` — Nodemailer и проверка контракта.
- `src/api.mjs` — ограниченный HTTP API и ожидание конкретного письма.
- `php/send.php` — PHPMailer.
- `tools/capture.mjs` — реальное выполнение 16 вариантов.
- `public/records/windows.json` и `linux.json` — полученные записи.
- `tests/` — проверки контракта и ограничений учебного клиента.
- `public/` — готовая статическая мастерская.

На текущем стенде база Mailpit временная: после удаления контейнера письма исчезают. Для сохранения установите MP_DATABASE и отдельный том; резервирование и сроки хранения тогда становятся вашей задачей. Тесты не вызывают Delete All и не удаляют другие письма.

```bash
docker compose down
```

Ctrl+C останавливает локальный preview. Не используйте глобальную очистку Docker для завершения этого проекта. На VPS обновляйте фиксированную версию отдельно и повторяйте проверки; для автоматического запуска после перезагрузки задайте restart policy с учётом собственной эксплуатации.

Источники: https://mailpit.axllent.org/docs/ · https://nodemailer.com/smtp · https://github.com/PHPMailer/PHPMailer
