AWS EC2 DockerからSES経由でメール送信
Amazon EC2内に構築したDockerのWebサーバコンテナからメールを送信する必要があったので、その方法を模索してみました。
構築にあたり懸案点としては
- AWS内からメール送信するためには、Amazon Simple Email Service(以降、SESと記載)から送信する必要がある。
- EC2からメール送信するにはSMTPサービスが必要となるが、あまりリソースを消費するSMTPサービスを採用したくない。
というものがありましたが、今回のシステム構成は次のようになりました。
DockerコンテナからのSMTPサービスには軽量の「msmtp」を採用し、Webサーバ(apache)と同一コンテナに収納します。
外部へのメール送信は、msmtpからSESを経由させる設定にします。
SESの設定
AWSダッシュボードのサービスより「Amazon Simple Email Service」を選択します。
以降、旧コンソールウィンドウで説明していきます。
左ペインより「Email Address」をクリックします。
「Verify a New Email Address」をクリックします。
送信するメールアドレスを入力し、「Verify This Email Address」をクリックします。
ここでのメールアドレスは実際にWebサーバから送信する時のメールアドレスを設定します。
また、この後確認メールを受け取らないといけないので実際に受信可能なメールアドレスを設定します。
入力したメールアドレスへの送信が正常終了するとこのウィンドウが表示されるので「Close」をクリックします。
「Verify This Address」で指定したアドレス宛にAmazonからメールが来ているので、本文中のリンクをクリックします。
先ほど入力したメールアドレスが「Verified」になっていることを確認します。
左ペインの「SMTP Settings」をクリックし、表示された「Server Name」を確認し控えておきます。
「Create My SMTP Credentials」をクリックします。
「IAM User Name」を入力するウィンドウになります。既定値のままで良いので[作成]をクリックします。
[認証情報のダウンロード]をクリックします。
SESへの接続のための認証情報が記載された「credentials.csv」というファイルがダウンロードされます。
msmtpの設定
msmtprcファイルの作成
「credentials.csv」の内容をもとにmsmtpの設定ファイル「msmtprc」を作成します。
※作成した「msmtprc」ファイルはDockerfileと同一ディレクトリ内に配置しておきます。
defaults
tls on
tls_starttls on
tls_trust_file /etc/ssl/certs/ca-certificates.crt
syslog on
logfile -
account default
host email-smtp.us-east-2.amazonaws.com <-- 「Create My SMTP Credentials」ボタンクリック前に確認した「Server Name」を記述
port 587
auth on
user XXXXXXXXX <--- 「credentials.csv」の「Smtp USername」の内容を記述
password xxxxxx <--- 「credentials.csv」の「Smtp Password」の内容を記述
from xxx@abc.com <--- 「Verify a New Email Address」で入力したメールアドレスを記述
php.iniの設定
PHPからメールを送信するために「php.ini」へ以下を追記します。
※作成した「php.ini」ファイルはDockerfileと同一ディレクトリ内に配置しておきます。
[Mail]
sendmail_path = "/usr/sbin/sendmail -t"
Dockerfileの設定
msmtpをインストールする設定をDockerfileに記述します。
今回はphp-apacheコンテナに追加する形で指定します。
FROM php:7.4-apache
COPY ./php.ini /usr/local/etc/php/
:
# Install MSMTP
RUN apt-get install -y msmtp msmtp-mta
COPY ./msmtprc /etc/msmtprc
:
メール送信テスト
sendmailコマンドでの送信テスト
「testmail.txt」のファイル名で次のテスト用ファイルを準備します。
ToとFromには「Verify a New Email Address」で入力したメールアドレスを記述します。
To:xxx@abc.com
From:xxx@abc.com
Subject: Test
Test Mail Desu
testmail.txtをコンテナにコピーします。
下記例ではコンテナ名を「web」コピー先ディレクトリを「/usr/local/src」にしています。
$ docker container cp testmail.txt web:/usr/local/src/
コンテナにログインしてメール送信してみます。
$ docker container exec -it web bash
# cd /usr/local/src
# sendmail -t < testmail.txt
:
メール送信ログが表示される
実際にメールが届けばテスト完了。msmtpとSESの設定は正常にできています。
PHPからメール送信テスト
「testmail.php」のファイル名で次のテスト用ファイルを準備します。
fromとtoには「Verify a New Email Address」で入力したメールアドレスを記述します。
<?php
mb_language("Japanese");
mb_internal_encoding("UTF-8");
$from = 'xxx@abc.com';
$to = 'xxx@abc.com';
$subject = 'Test Mail';
$body = 'テストメールです!';
$header = 'From: ' . $from;
mb_send_mail($to, $subject, $body, $header, '-f ' . $from);
?>
testmail.phpをコンテナにコピー後、コンテナにログインしてメール送信してみます。
$ docker container cp testmail.php web:/usr/local/src/
$ docker container exec -it web bash
# cd /usr/local/src
# php testmail.php
メール送信ログが表示される
:
exitcode=EX_OK <----- これが表示されればOK
サンドボックスの解除
SES設定直後は「Sandbox」という自分以外にはメールを送信できない状態になっているため、これを解除します。
SESダッシュボードの左側ペインの「Sending Statistics」をクリックし現在の状態を確認します。
「Sandbox」になっていたら、[Edit your account details]をクリックします。
表示された申請用ウィンドウに必要項目を入力し、[Submit for review]をクリックします。
最近は「Use case description」は詳細に書かないと承認されないようです。
最低限、SESを利用する目的、メールを送信する頻度、受信者リストのメンテナンス方法、バウンス・申し立て・解除申請の管理方法などについて記述する必要があるようです。
申請の結果が出るまでしばらく待ちます。
申請の結果問題なければ「Production Access」が「Enabled」に変わります。
これで任意の宛先へメール送信が可能となりました。
補足
送信元メールアドレスが増えた場合
送信元(From)のアドレスが増える場合、SESのコンソール左側ペインより「Email Addresses」を選択し、上で実施したように「Verify a New Email Address」ボタンをクリックして送信元アドレスを追加します。
設定時、AWSより確認メールが送られてきますので、ここで設定するメールアドレスは受信可能なものとする必要があります。
WordPressからのメール送信元の設定
WordPressから送信される管理用メールの送信元アドレスをSESで設定した送信元メールアドレスにしておく必要があります。
次のようにfunctions.phpに追記します。
:
function custom_mail_from( $email ) {
return 'xxx@abc.com'; <------ SESに許可された送信元メールアドレス
}
add_filter( 'wp_mail_from', 'custom_mail_from' );