Docker(LEMP環境)にMailHogを追加したときのメモ

開発開始時からすでに用意していたDockerコンテナ環境で、急遽メール認証機能を実装するためメールの動作確認できるようにMailHogを設定した。結構手こずったが、多角的に調査して仮説を検証。メンターさんの力も借りてなんとか完了。

# MailHogとは
メールのテスト確認ができるツール。例えば、メール送信の動作をした場合実環境にはメールは送られず、MailHogがメールを受信する。ブラウザでメール送信のプログラムの動作ができているかが容易にできる。

https://blog.mailtrap.io/mailhog-explained/

#ツリー構造
今回の作業に主に関係あるのは、直下にあるdocker-compose-yml、docker/phpディレクトリにあるDockerfile。またphpの設定確認用に直下に`phpinfo();`を記述したinfo.phpを置いておく。

```ツリー構造
├── app
├── css
├── docker
│   ├── php
│   └── web
├──docker-compose.yml
├──info.php
├── js
└── view

```
# 導入に必要なこと
・MailHogのメールサーバー用コンテナを作成する
・mhsendmailへのパスを通す（php側での設定。appコンテナとMailHogコンテナの橋渡し役のようなもの）

# 元の環境

```docker-compose.yml
version: '3'
services:
  web:
    image: nginx:1.15.6
    ports:   
      - "8000:80"
    depends_on:
      - app
    volumes:
      - ./docker/web/default.conf:/etc/nginx/conf.d/default.conf
      - .:/var/www/html    
  app:
    build: ./docker/php
    volumes:
    - .:/var/www/html
    depends_on:
    - mysql
  mysql:
    image: mysql:5.7
    environment:
      MYSQL_DATABASE: myDB
      MYSQL_USER: Ryo
      MYSQL_PASSWORD: ryo3110
      MYSQL_ROOT_PASSWORD: alexi3110
    ports:
      - "3306:3306"
    volumes:
      - mysql-data:/var/lib/mysql
volumes:
  mysql-data:
```

```
///Dockerfile///
FROM php:7.2-fpm

RUN cd /usr/bin && curl -s http://getcomposer.org/installer \n\
| php && ln -s /usr/bin/composer.phar /usr/bin/composer
RUN apt-get update \
&& apt-get install -y \
git \
zip \
unzip \
vim

RUN apt-get update \
    && apt-get install -y libpq-dev \
    && docker-php-ext-install pdo_mysql pdo_pgsql mysqli

WORKDIR /var/www/html1
```
-----

# 追加後の環境

```docker-compose.yml
version: '3'
services:
  web:
    image: nginx:1.15.6
    ports:   
      - "8000:80"
    depends_on:
      - app
    volumes:
      - ./docker/web/default.conf:/etc/nginx/conf.d/default.conf
      - .:/var/www/html    
  app:
    build: ./docker/php
    volumes:
    - .:/var/www/html
    - ./docker/php/php.ini:/usr/local/etc/php/php.ini
    depends_on:
    - mysql
  mysql:
    image: mysql:5.7
    environment:
      MYSQL_DATABASE: myDB
      MYSQL_USER: Ryo
      MYSQL_PASSWORD: ryo3110
      MYSQL_ROOT_PASSWORD: alexi3110
    ports:
      - "3306:3306"
    volumes:
      - mysql-data:/var/lib/mysql
  mailhog:
    image: mailhog/mailhog
    ports:
      - 1025:1025
      - 8025:8025
  
volumes:
  mysql-data:
```

```
///Dockerfile///
FROM php:7.2-fpm

RUN cd /usr/bin && curl -s http://getcomposer.org/installer \n\
| php && ln -s /usr/bin/composer.phar /usr/bin/composer
RUN apt-get update \
&& apt-get install -y \
git \
zip \
unzip \
vim

RUN apt-get update \
    && apt-get install -y libpq-dev \
    && docker-php-ext-install pdo_mysql pdo_pgsql mysqli

WORKDIR /var/www/html1

RUN curl -sSLO https://github.com/mailhog/mhsendmail/releases/download/v0.2.0/mhsendmail_linux_amd64 \
    && chmod +x mhsendmail_linux_amd64 \
    && mv mhsendmail_linux_amd64 /usr/local/bin/mhsendmail \
    && echo 'sendmail_path = "/usr/local/bin/mhsendmail --smtp-addr=mailhog:1025"' > /usr/local/etc/php/conf.d/sendmail.ini
```

#変更箇所について

```docker-compose.yml
mailhog:
    image: mailhog/mailhog
    ports:
      - 1025:1025
      - 8025:8025
```
mailhogイメージを使って、ポートを1025,8025を設定とし、メールサーバー用のコンテナを作成。

```
///Dockerfile////

RUN curl -sSLO https://github.com/mailhog/mhsendmail/releases/download/v0.2.0/mhsendmail_linux_amd64 \
    && chmod +x mhsendmail_linux_amd64 \
    && mv mhsendmail_linux_amd64 /usr/local/bin/mhsendmail \
    && echo 'sendmail_path = "/usr/local/bin/mhsendmail --smtp-addr=mailhog:1025"' > /usr/local/etc/php/conf.d/sendmail.ini
```
公式ドキュメントにある通り、sendmailの代わりにmhsendmailをphp用のコンテナにインストールする。
内容としては、mhsendmailダウンロード→ダウンロードしたmhsendmailを指定ディレクトリに移動させる→php側のメール設定としてsendmail_pathへパスを通す、といった感じ。

#コンテナの再ビルド

準備できたらコンテナを再構築する。すでにコンテナ運用しており、Dockerfileの内容を変更した場合、以下のコマンドでコンテナのキャッシュをしておく。忘れるとうまく変更が反映されない。

```
docker-compose build --no-cache
```
その後、普段どおりにupする

```
docker-compose up -d
```

コンテナ再構築できたら
ブラウザでlocalhost:8000/info.phpでphpの設定を確認。sendmail_pathが
/usr/local/bin/mhsendmail --smtp-addr=mailhog:1025
となっていればOK。

![Screen Shot 2020-08-09 at 18.09.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/659747/7a77b32f-a640-b1ab-66f3-dffeeb614141.png)

また、localhost:8025でmailhogの画面が表示されることを確認。

![Screen Shot 2020-08-09 at 18.12.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/659747/2f10f82d-7bf5-f38a-b7ef-952b436dbec6.png)

#送信テスト
適当にメール送信のプログラムで確認。`$result`でtrueが返れば送信できているはず。

```mailtest.php
<?php 
​
$to = 'user@gmail.com';
$subject = '本登録をお願いします。';
$message = 'URLから本登録をお願いします。';
$from = 'test@gmail.com';
$header = "From: ".$from."\r\n";
mb_language('Japanese');
mb_internal_encoding("UTF-8");
$result = mb_send_mail($to,$subject,$message,$header);
var_dump($result);
exit;
```

こんな感じでブラウザで表示。どうも日本語は文字化けしてしまうようであり、対処方法はいまのところない模様。まあテスト用なのでとりあえずOKとしておく。
![MailHog - Google Chrome 2020_08_06 7_19_38 (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/659747/ff43f363-22df-418d-6362-f70631d64cb7.png)

ちなみに、コンテナ停止するとメールデータは削除されるが、docker-compose.ymlにvolumesでマウントする記述すれば、コンテナ停止してもメールデータが削除されないようにできる模様。しかしあくまでテスト用の運用のため、残ってほしくないので今回はスルー。