Docker + Rails + Mailhogでメールを送信せずにブラウザで確認できる開発環境を作る

はじめまして。開発グループでエンジニアをしている石塚です。

今日はDocker + Rails + Mailhogでメールを送信せずにブラウザで確認できる開発環境の作り方を紹介したいと思います。

MailHog使ったきっかけ

Ruby on Railsでアプリケーションを開発している方なら letter_opener と letter_opener_web を使ったことがある人も多いかと思います。

letter_opener はメールを送信せずに送信内容をテキストで出力してくれるgemです。

このgemを使うことで開発環境で間違えて本番ユーザーにメールを誤送信してしまうことを防ぐことができます。

github.com

letter_opener_web はletter_openerで出力したテキストをブラウザで確認できるようにしてくれるgemです。

github.com

この letter_opener_web というgemですが sprockets が利用できる環境でないと使うことができません。

そのため、フロントエンドの開発をRailsから独立させるために sprockets をインストールしなかった場合や、RailsをAPIモードでインストールした場合などで利用することができません。

そこで、Railsに依存せずに同じことを実現できる方法がないかと調べていた時に見つけたのがMailHogです。

MailHogって何?

MailHogはGo言語で書かれているメールサーバーで、letter_opener_web と同様にブラウザでメールの内容を確認することができるようになります。

また、MailHog単体でメールサーバーとして立ち上げることができるため、Railsに限らずどんな環境でも利用することができます。

github.com

今回はDockerでMailHogサーバーとRailsサーバーを立ち上げてお互いを連携させるようにしたいと思います。

MailHogを使えるようにする

MailHogサーバーを立ち上げる

dockerhubで公開されているmailhogのイメージから立ち上げるだけです。

MailHogサーバーは8025番でhttpを受付けているので、8025番ポートを割り当ててあげます。

https://hub.docker.com/r/mailhog/mailhog/

docker-compose.yml

services:
  mailhog:
    image: mailhog/mailhog:v1.0.0
    ports:
      - '8025:8025'

RailsからMailHogにメールを送信する

config/enviroments/development.rb にメール送信の設定を記述します。

docker-compose.ymlでservices.mailhogにMailhogサーバーの設定を書きました。 このmailhogというサービス名をaddressに指定します。

また、MailHogサーバーは1025番ポートでsmtpを受付けているのでportに1025を指定します。

config/enviroments/development.rb

config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = { address: 'mailhog', port: 1025 }

送信したメールを確認する

設定はこれで完了です。

http://localhost:8025/ にアクセスすることでメールを確認することができます。

f:id:coconalainc:20180802193801p:plain f:id:coconalainc:20180802193756p:plain

さらに便利にする

コンテナを停止してもメールが消えないようにする

MailHogのデフォルトでは受け取ったメールデータをメモリに保存しています。 そのためDockerコンテナを停止すると保存していたメールが全て消えてしまいます。

そこで、環境変数の MH_STORAGE=maildir を指定することでメールデータをテキストファイルで保存されるようにします。

また、保存場所も決める必要があるため MH_MAILDIR_PATH=/tmp も一緒に指定しましょう。

docker-compose.yml

services:
  mailhog:
    image: mailhog/mailhog:v1.0.0
    ports:
      - '8025:8025'
    environment:
      MH_STORAGE: maildir
      MH_MAILDIR_PATH: /tmp

MailHogで設定できる環境変数はこちらに詳しく書いてあります。

MailHog/CONFIG.md at master · mailhog/MailHog · GitHub

コンテナを削除してもメールが消えないようにする

テキストファイルで保存していてもコンテナを削除したらデータが消えてしまいます。

そこで、メールデータはボリュームに保存されるようにボリュームをアタッチします。

docker-compose.yml

services:
  mailhog:
    image: mailhog/mailhog:v1.0.0
    ports:
      - '8025:8025'
    environment:
      MH_STORAGE: maildir
      MH_MAILDIR_PATH: /tmp
    volumes:
      - maildir:/tmp
volumes:
  maildir: {}

最終的なDockerの設定

今回作ったDocker環境のコードを載せます。

Dockerfile

FROM ruby:2.5.1

ENV TZ=Asia/Tokyo
ENV LANG C.UTF-8

# package install
RUN apt-get update \
 && apt-get install -y --no-install-recommends \
            mysql-client \
 && rm -rf /var/lib/apt/lists/*

WORKDIR /myapp

COPY . .

docker-compose.yml

version: '3.6'
services:
  web:
    build: .
    command: bin/rails s -b 0.0.0.0
    container_name: myapp_web
    depends_on:
      - db
      - mailhog
    ports:
      - '3000:3000'
    stdin_open: true
    tty: true
    volumes:
      - .:/myapp
      - bundle:/usr/local/bundle
  db:
    container_name: myapp_db
    environment:
      MYSQL_ROOT_PASSWORD: password
    image: mysql:5.7
    volumes:
      - mysql:/var/lib/mysql
  mailhog:
    container_name: myapp_mailhog
    environment:
      MH_STORAGE: maildir
      MH_MAILDIR_PATH: /tmp
    image: mailhog/mailhog:v1.0.0
    ports:
      - '8025:8025'
    volumes:
      - maildir:/tmp
volumes:
  bundle:
    name: myapp_bundle
  maildir:
    name: myapp_maildir
  mysql:
    name: myapp_mysql

まとめ

今回はDocker + Rails + Mailhogでメールをブラウザで確認できる開発環境の作り方を紹介させて頂きました。

Dockerを覚えることでRailsやGoといった言語にとらわれず、柔軟に開発環境を作ることができるようになります。

Dockerはとても便利なツールですので、今後もどんどん使いこなしていこうと思います。

f:id:coconalainc:20180803124012p:plain