hero_picture
Cover Image for msmtpを使いdockerのwordpressのようなphpコンテナからsendmailコマンドでAmazon SESにリレーしてメール送信

msmtpを使いdockerのwordpressのようなphpコンテナからsendmailコマンドでAmazon SESにリレーしてメール送信

クラウドソリューション事業部の原口です。

スプラトゥーン3、やっぱ発売したらやっちゃいますよねー。

さて。

PHPコンテナのようなコンテナ環境からメールを送信する場合は通常SMTP通信を行い、外部に用意されたメールサーバーからメールを送信する、とする事が多いと思います。

しかしWordPressのような一般に配布されているようなPHPプログラムをPHPコンテナで動かす場合、デフォルトではsendmailコマンドでメールを送るように設計されています。

もちろん、WordPressにWP Mail SMTP といった外部SMTPサーバーにリレーするようなプラグインを入れて対応したりと、そもそものプログラムをいじれるなら問題は無いです。

今回はプログラム側を修正する事なくsendmailコマンドが外部SMTPサーバーにリレーしてメールを送るようにできないか、という事でその方法を考えます。

Postfixを入れれば解決するが…

一般にMTAと呼ばれるソフトを入れればsendmailコマンドは使えるようになります。代表的なMTAはPostfix、Exim4などでしょうか。

このように一般のMTAがあればsendmailコマンドを外部メールサーバーにリレーさせる設定というのが可能です

例えばAmazon SESに統合する場合はAWSからも公式にドキュメントがあり各種MTAにおける設定方法が解説されています。

https://docs.aws.amazon.com/ja_jp/ses/latest/dg/send-email-smtp-existing-server.html

しかし、dockerのコンテナにおいては「1コンテナ1プロセス」という原則があり、postfixの導入はその禁を破る事となります。

実際のところコンテナの中でpostfixとphpの二つのプロセスを管理する事になるし、もちろんリソースも食うのでこれは非常によくないですよね。

そこでmsmtpという選択

msmtpはメール送信専用の超シンプルな MTA です。MTAだとさっきのPostfixと同じじゃねーか!となるかもしれませんがmsmtpはSMTP サーバとして起動しなくても外部のサーバに接続してメール送信することができます。つまりデーモンとして常駐させる必要がありません。

SMTPサーバーは構築したくないけどメールは送信したい!という時に最適です。

もともと ssmtp というものが有名だったようなのですが、更新が止まってるようでmsmtpを選択しました。

導入と設定も非常に簡単で、aptのようなパッケージマネージャーでインストールして、設定のテキストファイルを置くだけでOKという手軽さです。

ちなみにインストールは以下のような感じです。msmtpのバイナリは/usr/bin/msmtpにあるのですがdebian系だとmsmtp-mtaを入れると実行パスをsendmailに合わせてくれます。

1apt-get install msmtp msmtp-mta

redhut系だと epelリポジトリにmsmtpがあるのですが、msmtp-mtaは無いのでsendmailにシンボリックリンク貼ったりとかちょっと追加設定が必要になります。

msmtpの設定ファイルの作成

設定ファイルは /etc/msmtprc に作成して置く事で反映されます。

Amazon SESにリレーする場合

Amazon SESにリレーしたい場合は以下のような設定ファイルを作成すればOKです。

1defaults
2tls on
3tls_starttls on
4tls_trust_file /etc/ssl/certs/ca-certificates.crt
5logfile /path/to/msmtp.log
6
7account default
8host email-smtp.ap-northeast-1.amazonaws.com
9port 587
10auth on
11user YOUR_AMAZON_SES_SMTP_USERNAME
12password YOUR_AMAZON_SES_SMTP_PASSWORD
13from YOUR_AMAZON_SES_VERIFIED_SENDER

userとpasswordはアクセスキーとシークレットキーですね。fromはSESで認証済みのメールアドレスを指定します。

logfileなどはデバッグ用で出す感じになります。phpのログと混じるのが嫌でなければstdoutでもいいと思います。

自分の用意したSMTPサーバーを使う場合

EC2でdockerを使っていてホストのpostfixから送信したかったり、別コンテナpostfixとかを使ったり、自前で用意したメールサーバーがあるという場合は以下のような感じです。(認証なしでリレーできるとした場合になります)

1account default
2from example@example.com
3host YOUR_SMTP_SERVER_HOST
4port 25
5logfile /path/to/msmtp.log

Gmailにリレーしてみたりの場合

ちょっとローカル環境でメールのテストしたいんやーって時。

1defaults
2auth on
3tls on
4tls_starttls on
5tls_trust_file /etc/ssl/certs/ca-certificates.crt
6tls_certcheck off
7logfile /path/to/msmtp.log
8
9account default
10host smtp.gmail.com
11port 587
12from YOUR_GMAIL_USERNAME@gmail.com
13user YOUR_GMAIL_USERNAME@gmail.com
14password YOUR_GMAIL_PASSWORD

mailcatcherやmailhogのような別コンテナにリレー(エアプです)

別コンテナにmailcacherやmailhogのようなSMTPコンテナがある場合

1account default
2host YOUR_SMTP_SERVER_CONTAINER_NAME
3port 1025
4from username@example.com
5user YOUR_SMTP_USERNAME
6password YOUR_SMTP_PASSWORD

msmtpを使うphpコンテナのDockerfile例

Dockerfileは以下の感じで設定するのがいいのではないでしょうか。

1FROM php:8.1.10-apache-bullseye
2...
3...
4RUN apt-get -q -y --no-install-recommends install msmtp msmtp-mta
5COPY msmtprc /etc/msmtprc

SESのアクセスキーなどはうまく環境変数とした方がいいかと思います。

imageがパブリックに公開されるならそのあたりは注意してください。

ほなカイサン!!!