Docker で Mailpit コンテナを作る方法
Docker の PHP コンテナで開発する際に、テスト用のメールサーバーを使用すると便利です。 メールを外部に送信せずに、メールの動作確認を行うことができます。
Mailpit とは?
Mailpit はテスト用に開発されたメールサーバーです。 Go 言語で実装されています。 本物のメールサーバーのように振舞いながらも、メールを外部には送信しませんので、メールの動作確認をする場合はとても便利です。
同じようなテスト用のメールサーバーとして MailHog がありましたが、 MailHog は動作速度があまりよろしくなく、性能面での問題を抱えていたため、MailHog の代替として Mailpit が開発されました。 そのため、Mailpit の方が MailHog よりも高速に動作します。 また、Mailpit のインストール方法や使用方法などは、ほぼ MailHog と同じですので、 MailHog を使用している方は簡単に Mailpit へ移行することができます。 MailHog の上位互換だと思ってもらって良いのではないでしょうか。
Docker で Mailpit コンテナを作る
Docker で Mailpit のコンテナを作成してみましょう。
コンテナのイメージは、下記のイメージを使用します。
イメージのバージョン(タグ)は特にこだわりが無ければ最新版(latest
)で良いと思います。
Mailpit のコンテナの中には、メールを受け取る用の SMTP サーバーと、受け取ったメールの内容を表示するための Web サーバーが含まれています。
Mailpit の Web サーバーのコンテナ側のポート番号は 8025 番です。 80 番ではないので注意してください。 ホスト側から Web ブラウザ(Chrome など)で接続できるよう、コンテナ側のポート 8025 番へのマッピングを設定しましょう。 ホスト側のポート番号は、他で使用されていないものなら何番でも良いと思います。
Mailpit の SMTP サーバーのコンテナ側のポート番号は 1025 番です。 25 番ではないので注意してください。 もしホスト側から接続する必要があるのであれば、コンテナ側のポート 1025 番へのマッピングを設定しましょう。 PHP から Mailpit コンテナにメールを送る方法は後述します。
version: "3.8" services: # Mailpit コンテナ mailpit: image: axllent/mailpit:latest ports: - 18025:8025
データが消えないようにする
Mailpit のメールデータはデフォルトでは SQLite のデータベースファイルとして /tmp に保存されますが、 コンテナを再起動したりコンテナを再作成したりすると受け取ったメールが消えてしまいます。 Mailpit の主な用途は開発時のテストだと思いますので、メールが消えて困る場面は少ないと思うのですが、 メールが消えてしまうと困るという場合は、消えないように設定しましょう。
コンテナ再起動時に消えないようにするには、
環境変数 MP_DATA_FILE
を使用して、SQLite のデータベースファイルの名前を指定します。
コンテナ再作成時に消えないようにするには、
バインドマウントか名前付きボリュームを使用して、コンテナの外にメールデータが保存されるように変更しましょう。
version: "3.8" services: # Mailpit コンテナ mailpit: image: axllent/mailpit:latest ports: - 18025:8025 environment: MP_DATA_FILE: /tmp/mailpit.db volumes: - ./mailpit-data:/tmp
PHP から Mailpit コンテナにメールを送る
Mailpit コンテナにメールを送る際は、Mailpit コンテナの SMTP サーバーに送る必要があります。
ホスト名として docker-compose.yml で定義しているサービス名(つまり、services
項目で指定しているキー)を使用できます。
上記の例では、ホスト名として "mailpit" が使用できます。
ポート番号は 1025 番です。
PHP でメールを送る際、大きく分けて2つの方法があります。 どちらの方法を使用しているかによって設定方法が異なります。
1つ目は、PHP のメール送信関数 mail()
もしくは mb_send_mail()
を使用する方法です。
mail()
もしくは mb_send_mail()
は、
メールを直接メールサーバーに送っているわけではなく、sendmail
コマンドにメールを送っています。
実際にメールを送信しているのは sendmail
コマンドなのです。
つまり、sendmail
コマンドから Mailpit コンテナに接続するよう設定しなければなりません。
これがちょっと難しい。
そこで sendmail
コマンドの代わりになるコマンド mailpit sendmail
コマンドが用意されていますので、
これを使用すると良いでしょう。
2つ目は、PHP からソケットを開けて直接メールサーバーに接続してメールを送る方法です。 有名なフレームワークやメールライブラリなどは、だいたいこちらの方法でメールを送信しているのではないでしょうか。 こちらの場合は接続先のホストとポート番号を Mailpit コンテナの SMTP サーバーに変更するだけなので特に問題はないと思います。
mailpit sendmail コマンドを使用する
PHP のメール送信関数 mail()
もしくは mb_send_mail()
を使用している場合は、
mailpit sendmail
コマンドを使用して Mailpit コンテナにメールを送信するように変更しましょう。
mailpit コマンドをインストールする
mailpit sendmail
コマンドは、mailpit
コマンドの一部で、Mailpit のパッケージに含まれています。
mailpit
コマンドをインストールするには、Dockerfile を下記のように変更します。
なお、これを行うのは PHP が入ってるコンテナであって、Mailpit コンテナではないので注意してください。
FROM php:8.2-apache # apt を最新化 RUN apt update # 2024/07/15 追記:下記の Go 言語を使用する方法は古い方法です。 # Go 言語のバージョン違いによりエラーが出てしまうことがあるので使用しない方が良いです。# Go 言語をインストール# - mailpit コマンドを go install でインストールするために必要RUN apt install -y golang-go# mailpit コマンドをインストール# - インストール先が /root 配下だと Web サーバーから実行できないので、/usr/local/bin へ移動RUN go install github.com/axllent/mailpit@latest \&& mv /root/go/bin/mailpit /usr/local/bin# 2024/07/15 追記:最新のドキュメントによると下記のコマンドでインストールできます。 # Go 言語を使用せずにインストールできるのでオススメです。 # インストール先は /usr/local/bin/mailpit になります。 # mailpit コマンドをインストール RUN ["/bin/bash", "-c", "bash < <(curl -sL https://raw.githubusercontent.com/axllent/mailpit/develop/install.sh)"]
php.ini の sendmail_path を変更する
mailpit
コマンドがインストールできたら、次は PHP の設定ファイル php.ini を変更します。
php.ini の sendmail_path
の値に、mailpit sendmail
コマンドを指定します。
--smtp-addr
オプションで、Mailpit コンテナの SMTP サーバーのホストとポート番号を指定します。
--smtp-addr
オプション には、エイリアス(別名) -S
オプションがあります。
[mail function] sendmail_path="/usr/local/bin/mailpit sendmail -S mailpit:1025"