Docker環境のMailDevでSMTP認証をする


Docker初心者なので個人的な備忘録として。。。

はじめに

メール配信は、Sendmail/SMTPの両方に対応しないといけません。
そして、SMTP配信を使う場合は、SMTP Authを使っての認証を使うことが欠かせません。

このためSMTP Authの開発・テスト環境を作っていきます。

前回作成した、DockerでPHP-alpineのメール配信テスト(SMTP/sendmail)環境を構築するをベースに、step10-php5-xdebug-redis-mail3として作成していきます。

TL;DR

GitHub上のサンプルコードのStep10をご覧ください。
step10-php5-xdebug-redis-mail3

MailDevのSMTP Auth対応

SMTP Authへの対応は、MailDevのUsageに書いています。
MailDevの起動オプションに、「--incoming-user」と「--incoming-pass」をつければいいそうです。

maildev [options]

  -h, --help                      output usage information
  -V, --version                   output the version number
  -s, --smtp <port>               SMTP port to catch emails [1025]
  -w, --web <port>                Port to run the Web GUI [1080]
・・・省略・・・
  --incoming-user <user>          SMTP user for incoming emails
  --incoming-pass <pass>          SMTP password for incoming emails
・・・省略・・・
  -o, --open                      Open the Web GUI after startup
  -v, --verbose
  --silent

ここまではわかるのですが、じゃ、Dockerとしてはどうしたらいいの?ってなりました。

MailDevのDockerHubに記載されているDockerfileを見ると、最後に「CMD ["bin/maildev", "--web", "80", "--smtp", "25"]」という記載があります。

MailDevのデフォルトのDockerfile
FROM node:6-alpine
MAINTAINER "Dan Farrelly <[email protected]>"

ENV NODE_ENV production

RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app

ADD package.json /usr/src/app/

RUN npm install && \
    npm prune && \
    npm cache clean \
    rm -rf /tmp/*

ADD . /usr/src/app/

EXPOSE 80 25

CMD ["bin/maildev", "--web", "80", "--smtp", "25"]

ここを書き換えてImageを作り直すのかな?ってとも思いました。

さらに調査すると、docker-compose.ymlでcommandという形で指定ができることがわかりました。

step10のdocker-compose.ymlを以下のように書き換えます。
SMTP AUTHのID/PWは変更する可能性があるので環境変数指定にします。

docker-compose.yml
version: '3'
services:
・・・省略・・・
  maildev:
    image: kanemu/maildev-with-iconv
    command: bin/maildev -w 80 -s 25 --incoming-user ${SMTP_USER} --incoming-pass ${SMTP_PASSWORD}
    ports:
      - "1025:25"
      - "8025:80"
・・・省略・・・

.envファイルにID/PWを追記します。

.env
MYSQL_RANDOM_ROOT_PASSWORD=yes
MYSQL_DATABASE=step3
MYSQL_USER=db_user
MYSQL_PASSWORD=password

# REDIS関係
REDIS_PORT=6379
REDIS_PASSWORD=password

# Mail <-ここ
SMTP_USER=smtpuser
SMTP_PASSWORD=password

次にsendmailの役割を担っているssmtp.confにもSMTP Authの設定を追記します。
ちなみに、直接記述していますが、環境変数で指定ができるといいんですけど、いい方法はないでしょうか?
まぁ、最終手段として、.envを見てssmtp.confを生成するスクリプトを作成すればよいのですが。。。

app/ssmtp.conf
root=postmaster
mailhub=maildev:25
hostname=app
FromLineOverride=YES

AuthUser=smtpuser
AuthPass=password
AuthMethod=LOGIN

最後に、サンプルファイルであるindex.phpのSMTP送信部分を書き換えます。
sendmailの方は、SMTP Authをssmtpが対応してくれましたので、修正はありません。

data/html/index.php
        use PHPMailer\PHPMailer\PHPMailer;
        use PHPMailer\PHPMailer\Exception;

        // Load Composer's autoloader
        require 'vendor/autoload.php';

        // Instantiation and passing `true` enables exceptions
        $mail = new PHPMailer;

        try {
            //Server settings
            echo '<pre class="log">';
            echo 'SMTPでメール配信' . PHP_EOL;

            $mail->SMTPDebug = 2;                                       // Enable verbose debug output
            $mail->isSMTP();                                            // Set mailer to use SMTP
            $mail->Host       = 'maildev';  // Specify main and backup SMTP servers
            $mail->SMTPAuth   = true;                                   // Enable SMTP authentication
            $mail->Username   = getenv('SMTP_USER');                     // SMTP username
            $mail->Password   = getenv('SMTP_PASSWORD');                               // SMTP password
            $mail->SMTPSecure = false;                                  // Enable TLS encryption, `ssl` also accepted
            $mail->SMTPAutoTLS = false;
            $mail->Port       = 25;                                    // TCP port to connect to

            //Recipients
            $mail->setFrom('[email protected]', mb_encode_mimeheader('日本語送信者名SMTP AUTH'));
            $mail->addAddress('[email protected]', mb_encode_mimeheader('日本語受信者名SMTP AUTH'));     // Add a recipient

テスト

127.0.0.1にアクセスすると、SMTP/Sendmailでメールが1通ずつ送信されます。
127.0.0.1:8025にアクセスをして、2通のメールの受信ができればOKです。

まとめ

これで一般的なメールのテストに対応ができると思います。