「テストメールが本番ユーザーに飛んだ」を二度と起こさないために
開発中にメール送信機能をテストしたい。でも本番のSMTPサーバーに繋いでテストすると、手が滑って実在するユーザーにテストメールが飛ぶリスクがある。GmailのSMTPを使うとレート制限に引っかかる。SendGridの無料枠を消費するのもためらわれる。
そんな時に使うのがローカルメールテストツールです。SMTPサーバーとして動作し、送信されたメールを外部に配送せず、ブラウザのUIで確認できるという仕組み。長年MailHogが定番でしたが、現在はメンテナンスが停止しており、後継のMailpitが主流になっています。
本記事では、MailHogからMailpitに乗り換えるべき理由と、Dockerでのセットアップ、アプリからの接続設定までを解説します。
MailHogとMailpitの違い
| 項目 | MailHog | Mailpit |
|---|---|---|
| メンテナンス状況 | 停止(2020年以降更新なし) | アクティブに開発中 |
| 日本語メール | 文字化けする場合あり | 正常に表示 |
| Apple Silicon対応 | amd64のみ(M1/M2で遅い) | arm64ネイティブ対応 |
| UI | 最低限 | モダンで見やすい |
| HTML/テキスト表示 | 切り替え可能 | 切り替え+ソース表示も可能 |
| API | あり | あり(MailHog互換+拡張) |
| SMTPポート | 1025 | 1025(同じ) |
| Web UIポート | 8025 | 8025(同じ) |
ポートが同じなので、MailHogからの移行はDockerイメージを差し替えるだけで済みます。アプリ側のSMTP設定を変える必要はありません。
Mailpitのセットアップ
Docker Compose(おすすめ)
既存のdocker-compose.ymlにサービスを追加するだけです。
# docker-compose.yml
services:
app:
# あなたのアプリケーション
depends_on:
- mailpit
mailpit:
image: axllent/mailpit:latest
ports:
- "8025:8025" # Web UI(ブラウザで確認)
- "1025:1025" # SMTP(アプリからの送信先)
environment:
TZ: Asia/Tokyo
MP_MAX_MESSAGES: 5000
MP_SMTP_AUTH_ACCEPT_ANY: 1
MP_SMTP_AUTH_ALLOW_INSECURE: 1
restart: unless-stoppeddocker compose up -dで起動したら、ブラウザでhttp://localhost:8025にアクセス。MailpitのWeb UIが表示されれば準備完了です。
Homebrew(Dockerなしで使いたい場合)
# macOS
brew install mailpit
# 起動
mailpit起動するとSMTPがlocalhost:1025、Web UIがlocalhost:8025で待ち受けます。
アプリからMailpitにメールを送る設定
Node.js(Nodemailer)
// lib/mailer.ts
import nodemailer from 'nodemailer';
const transporter = nodemailer.createTransport({
host: process.env.SMTP_HOST || 'localhost',
port: Number(process.env.SMTP_PORT) || 1025,
secure: false, // ローカルなのでTLS不要
});
export async function sendTestEmail() {
await transporter.sendMail({
from: '"テスト送信者" ',
to: 'user@example.com',
subject: '会員登録ありがとうございます',
html: 'ようこそ!
登録が完了しました。
',
});
} # .env(開発環境)
SMTP_HOST=localhost
SMTP_PORT=1025Next.js(API Route)
Next.jsのAPI RouteやServer Actionsから上のsendTestEmail()を呼び出すだけ。Docker Compose内のアプリからの場合は、SMTP_HOSTをサービス名のmailpitに変えてください。
# .env(Docker Compose内のアプリの場合)
SMTP_HOST=mailpit
SMTP_PORT=1025実務で使えるTips
本番とローカルの切り替えを環境変数で制御する
本番ではSendGridやSES、ローカルではMailpitという切り替えを、環境変数だけで実現しておくのが定石です。コードの中にif (dev)分岐を書くのではなく、.envの値を差し替えるだけで切り替わる設計にしましょう。
MailpitのAPIでE2Eテストに組み込む
Mailpitには受信メールを取得するAPIがあります。「フォーム送信 → メール受信を確認」というE2Eテストを自動化できます。
# 受信メール一覧を取得
curl http://localhost:8025/api/v1/messages
# 全メールを削除(テスト前のリセットに便利)
curl -X DELETE http://localhost:8025/api/v1/messagesMailHogからの移行は1行
既存のdocker-compose.ymlでmailhog/mailhogを使っている場合、イメージ名を差し替えるだけで完了です。
# Before
image: mailhog/mailhog
# After
image: axllent/mailpit:latestポートもAPIもMailHog互換なので、アプリ側の変更は不要です。
ローカル開発環境を強化する関連記事
- コマンドラインの基本と活用方法【初心者エンジニア向け】 – Docker ComposeやcurlなどCLI操作の基本
- Claude Codeとは?AI搭載のコーディングアシスタントを徹底解説 – メール送信機能の実装やDocker設定をAIに任せる活用法
- 「それ、上げちゃダメ!」GitHub管理で絶対守るべきセキュリティルールと対処法 – SMTP認証情報を.envで管理し、Gitにコミットしないための基本
- ngrokの無料プランでURLが毎回変わる問題、実はもう解決してた!静的ドメインの設定方法 – ローカル環境を外部に公開してメール受信Webhookをテストする場合に
- リリース前に必ず確認!バイブコーディング&非エンジニア向けWebアプリ安全チェックリスト – メール送信先の誤設定を含むリリース前チェック
まとめ:メールテストは「ローカルで完結」が正解
- MailHogはメンテナンス停止。日本語文字化け、Apple Silicon非対応など問題が多い
- Mailpitが後継。モダンUI、arm64対応、日本語OK、アクティブに開発中
- Dockerなら1サービス追加するだけ。ポート8025(UI)と1025(SMTP)を開ける
- MailHogからの移行はイメージ名を差し替えるだけ。ポートもAPI互換
- 環境変数でSMTP先を切り替える設計にしておけば、本番とローカルの混同を防げる
メール送信のテストは、ローカルで完結させるのが最も安全で最も速い。Mailpitなら5分でセットアップできて、ブラウザでメールの中身をすぐ確認できます。まだMailHogを使っている人も、本番SMTPで直接テストしている人も、今日Mailpitに切り替えてください。
