ec2(Docker)からAmazonSES経由でメール送信

AWS

仕事でEC2(AmazonLinux2)上のDockerコンテナ(PHP[Laravel])から外部へメール送信する必要があったので、個人環境で調べてみました。Dockerからメール送信する汎用的な方法について書きた買ったんですが、現在実行できたのは、AmazonSES経由でのメール送信です。今回のシステム構成は、次の通りです。

メール送信はpostfixで作りたかったんですが、msmtpというソフトがわかりやすかったのです。

AmazonSESへドメインの登録

「AmazonSES>Verified identities」でDomainを追加します。「Domain」記入欄以外は何も設定していません。

DKIMの情報が表示されるのでメモする。

DNSに登録する

ドメインのStatusがVerifiedになる。

これで、メールが送れるようになったので、テストメールを送ってみましょう。また、Legacy Txt Recordの設定が必要な場合は、CSVをダウンロードしてDNSを設定してください。

EC2(Linux)環境の準備

今回必要なDockerとDocker-composeコマンドをインストールします。手順は、こちらを参照。

EC2にDockerをインストール
Amazon Linux2についてdockerとdocker-composeを利用可能にするコマンドを記載します。(2022/2/9に確認しました)

Docker用のファイルを作成

ディレクトリ構成※赤字と青字のファイルは説明あり

$ pwd;find . | sort | sed '1d;s/^\.//;s/\/\([^/]*\)$/|--\1/;s/\/[^/|]*/| /g'
/home/ec2-user/testdocker3
|--docker-compose.yml
|--html
| |--index.html
| |--mail.txt
| |--testmail.php
|--nginx
| |--conf.d
| | |--default.conf
|--php
| |--Dockerfile
| |--msmtprc
| |--php.ini

[docker-compose.yml]

version: '3'
services:
web:
image: nginx:stable
container_name: "nginx-mail"
depends_on:
- php
ports:
- '8080:80'
volumes:
- ./nginx/conf.d:/etc/nginx/conf.d
- ./html:/var/www/html
php:
build: ./php
container_name: "php-mail"
volumes:
- ./html:/var/www/html
- ./php/php.ini:/usr/local/etc/php/php.ini
- ./php/msmtprc:/etc/msmtprc

[Dockerfile]

From区はphp-fpmでも良いんですが、旧式のLaravelを動かしたいので、DockerHubからイメージを探してきました。

FROM laradock/php-fpm:latest-5.6

ENV PATH $PATH:/usr/local/bin/php

### ソフトウェアのインストール
RUN apt-get update && apt-get install -y apt-utils
RUN apt-get update && apt-get install -y git
RUN apt-get update && apt-get install -y wget
RUN apt-get update && apt-get install -y vim
RUN apt-get update && apt-get install -y libmcrypt-dev
RUN apt-get update && apt-get install -y mcrypt
RUN apt-get update && apt-get install -y libpq-dev
RUN apt-get install -y msmtp msmtp-mta

### PHP拡張インストール
RUN apt-get update \
&& docker-php-ext-install pdo_mysql pdo_pgsql 

### Laravel設定用のComposerをセットアップ
COPY --from=composer /usr/bin/composer /usr/bin/composer
RUN composer self-update --1

[msmtprc]

書き換えるのは、赤字と青字部分。

defaults
tls on
tls_starttls on
tls_trust_file /etc/ssl/certs/ca-certificates.crt
syslog on
logfile -

account default
host email-smtp.ap-northeast-1.amazonaws.com  # SESのSMTPサーバ
port 587                                      # SESのSMTPサーバのポート
auth on
user AK*******************         #「Create SMTP credentials」で作成したID
password BAm********************   # 「Create SMTP credentials」で作成したPASS
from ec2-user@wp-pre-struct.com   # メールアドレスを指定

[php.ini]

[Mail]
sendmail_path = "/usr/sbin/sendmail -t"

メール送信できるか確認_その1

準備ができたら、Dockerのコンテナをいつものコマンドで起動

docker-compose up -d
docker exec -it php-mail bash

sendmailコマンドを実行してみます。コピペがうまくいかなかったので、ファイルを準備しています。

root@c95bf1326cca:/var/www/html# cat mail.txt 
To: *******@gmail.com 
From: ec2-user@wp-pre-struct.com
Subject: test
this is msmail test.

root@c95bf1326cca:/var/www/html# sendmail -t < mail.txt
Feb 13 10:19:31 host=email-smtp.ap-northeast-1.amazonaws.com tls=on auth=on user=AKIA6EAGAM4AMGEG3B57 from=ec2-user@wp-pre-struct.com recipients=**********@gmail.com mailsize=137 smtpstatus=250 smtpmsg='250 Ok 0106017ef2984005-66cccd4c-7c67-4170-af48-5b03135d4d86-000000' exitcode=EX_OK

ログがOKと出たので、Gmailを確認してみましょう。

直接のコマンドはOKですね。

メール送信できるか確認_その2

次にPHPからメール送信できるかを確認してみましょう。

root@c95bf1326cca:/var/www/html# cat testmail.php 
<?php
    mb_language("Japanese"); 
    mb_internal_encoding("UTF-8");
    $from = 'ec2-user@wp-pre-struct.com';
    $to = '*********@gmail.com';
    $subject = 'Test Mail';
    $body = 'test mail from ses docker';
    $header = 'From: ' . $from;
    mb_send_mail($to, $subject, $body, $header, '-f ' . $from);
?>
root@c95bf1326cca:/var/www/html# php testmail.php 
Feb 13 10:27:23 host=email-smtp.ap-northeast-1.amazonaws.com tls=on auth=on user=AKIA6EAGAM4AMGEG3B57 from=ec2-user@wp-pre-struct.com recipients=********@gmail.com mailsize=241 smtpstatus=250 smtpmsg='250 Ok 0106017ef29f750c-46bb4ac8-84ba-4ccf-acec-55107c622abf-000000' exitcode=EX_OK

ログOKなので、メールを確認すると、

こちらも送れていますね

まとめ

とりあえずEC2から外部へメール送信できました。本番導入時は、ドメインに対してSPFレコードの追加をしたり、本番用メールアドレスの設計が必要ですが、ここまでくれば何とかなりそうです。

あとは、この構成をとると本番用Dockerと開発用Docker分けないといかんですね。

最後に、今回は下記のページが決め手となりました。大変ありがとうございます。

AWS EC2 DockerからSES経由でメール送信 - K'z Arch@K'z Style(ケイズスタイル)

コメント

タイトルとURLをコピーしました