🗡️

Docker ComposeでMailHogコンテナを組み合わせてメール送信の動作確認

2021/11/23に公開

Docker Composeでメール送信の動作確認する方法です。
(MailHog)[https://github.com/mailhog/MailHog]というメール送信の動作確認ツールがあります。
MailHogを使うと実際にメール送信を行う代わりに専用のプログラムが実行されます。
メールの内容はMailHogのデータとして蓄積され、ブラウザで確認できます。
間違ってメール送信される事故が防げるので、開発環境にはうってつけです。(事故になるようなメールアドレスを持っていることがそもそも問題ですが)

MailHogのDocker Imageも公開されています。
このイメージをDocker Composeの1コンテナとして使うことでメール送信の動作確認を行えます。
phpのメール送信関数mb_mail_send()を実行させるとMailHogのWeb UIでメールの受信が確認できることが目的です。

前提

  • httpのコンテナだけを構築していて、phpのみインストールされている状態です。
  • httpコンテナは「Dockerfile」を使ってビルドしています。
  • htmlファイルはホスト環境にあるものをマウントして永続化しています。

具体的には以下のファイル構成/内容です。
最低限ではありませんが、それに近い内容です。
ここからメール送信テストもできるようにしていきます。
Macで動作確認していますが、Windows/Linuxでも方法はほぼ同じです。

# ファイル構成

├── docker
│   ├── docker-compose.yml
│   └── web
│       ├── Dockerfile
└── html
# .env
# ※今回このファイルはなくても動きますが、設置して最低限「COMPOSE_PROJECT_NAME」を設定しておくことをオススメします。

COMPOSE_PROJECT_NAME=docker-compose-mailhog
# docker-compose.yml
version: '3'

services:
  web:
    container_name: docker-compose-mailhog-web
    build: ./web
    ports:
      - '80:80'
    volumes:
      - ../html:/var/www/html
    hostname: localhost
    networks:
      - br0

networks:
  br0:
    driver: bridge
# web/Dockerfile
FROM php:7.4-apache

RUN apt-get update

手順

phpの設定ファイルを作成

phpの動作設定ファイルとなるmailhog.iniをホスト環境で作成します。

# web/mailhog.ini
[mail function]
sendmail_path = "/usr/local/bin/mhsendmail --smtp-addr=mailhog:1025"

これでphpのメール送信関数が実行 -> /usr/local/bin/mhsendmailを実行という挙動になります。
通常はsendmailが実行されるところをmhsendmailに置き換えています。

ここまでのファイル構成は以下です。

# ファイル構成

├── docker
│   ├── docker-compose.yml
│   └── web
│       ├── Dockerfile
│       └── mailhog.ini
└── html

web/Dockerfileに追記(mhsendmailをインストール、php設定の有効化)

phpの設定で指定したmhsendmailもコンテナにインストールする必要があります。
これはDockerfileの中で行います。
インストールはCURLを使用するため、あらかじめwgetをインストールします。
先ほど作成したmailhog.iniを有効化させるために、ホスト環境で作ったmailhog.iniをコンテナにコピーも行います。

# web/Dockerfile
FROM php:7.4-apache

# wgetをインストールするよう修正
RUN apt-get update && apt-get install -y wget

# ホスト環境で作ったmailhog.iniをコンテナにコピー
COPY mailhog.ini /usr/local/etc/php/conf.d/mailhog.ini

# mhsendmailコマンドのインストール。CURLでダウンロードしてインストールします。
RUN curl -sSL https://github.com/mailhog/mhsendmail/releases/download/v0.2.0/mhsendmail_linux_amd64 -o mhsendmail \
    && chmod +x mhsendmail \
    && mv mhsendmail /usr/local/bin/mhsendmail

docker-compose.ymlにMailHog用のコンテナ設定を追記

Docker上でMailHogを動作させるため、docker-compose.ymlにMailHog用コンテナ設定を追記します。

# docker-compose.yml
version: '3'

services:
  web:
    container_name: docker-compose-mailhog-web
    build: ./web
    ports:
      - '80:80'
    volumes:
      - ../html:/var/www/html
    hostname: localhost
    networks:
      - br0
  # mailhogの設定を追記
  mailhog:
    container_name: docker-compose-mailhog-mailhog
    image: 'mailhog/mailhog:latest'
    ports:
      - '1025:1025'
      - '8025:8025'
    networks:
      - br0

networks:
  br0:
    driver: bridge

あとはビルドし直してコンテナを立ち上げれば、見かけ上、メール送信を行っていることが確認できます。

docker compose down
docker compose build --no-cache
docker compose up --detach

動作確認

以下のファイルを作成してきちんとインストールされたことを確認します。

  • phpinfo.php (インストール確認用)
  • test.php (動作確認用にメール送信処理だけを書いたphpスクリプト)
# phpinfo.php

<?php phpinfo();

http://localhost/phpinfo.php にアクセスすると、phpinfoが表示されます。
sendmail_pathの項目がmhsendmailに変わっているか確認します。

# test.php

<?php
$from = 'from@example.com';
$to   = 'to@example.com';
$subject = 'テストメール';
$body = 'メールの送信テストです。';

$ret = mb_send_mail($to, $subject, $body, "From: {$from} \r\n");
var_dump($ret);

http://localhost/test.php にアクセスすると、メール送信処理がされます。
成功すれば「bool(true) 」と表示されます。
「bool(false) 」と表示される場合は今までの設定が間違っている可能性が高いです。

http://localhost:8025/ にアクセスするとMailHogのWeb UIを確認できます。
これを見るとメール送信されたことが確認できます。

動作確認まで終えると、以下のファイル構成となります。

# ファイル構成

├── docker
│   ├── docker-compose.yml
│   └── web
│       ├── Dockerfile
│       └── mailhog.ini
└── html
    ├── phpinfo.php
    └── test.php

うまく動かないときは(考えられる原因)

mhsendmailがきちんとインストールされていない

docker execでweb用のコンテナに入ってmhsendmailをcatしてみましょう。

# ホスト側でコマンド実行
docker exec -it docker-compose-mailhog-web bash

# コンテナ内でコマンド実行
cat /usr/local/bin/mhsendmail

正しければバイナリ文字列が流れて表示されるはずです。
例えばNot Foundが出る場合はCURLで指定したURLが間違っていることが考えられます。
先にmhsendmailのインストールで指定したURL「 https://github.com/mailhog/mhsendmail/releases/download/v0.2.0/mhsendmail 」が正しいことを確かめましょう。(私はこれが間違っていて少しハマりました。)

Discussion