Upgrade to Pro — share decks privately, control downloads, hide ads and more …

SendGrid用のメールモックコンテナを作った話

 SendGrid用のメールモックコンテナを作った話

2021/8/25に行われたオンライン勉強会
https://lancersrecruit.connpass.com/event/219434/
で発表した資料です。

エンジニアブログ
https://engineer.blog.lancers.jp/2021/08/sendgrid-maildev/

SendGrid Mock API
https://github.com/yKanazawa/sendgrid-dev

Sendgrid Maildevコンテナ
https://hub.docker.com/r/ykanazawa/sendgrid-maildev

652359244199b2b5108a5e09c027e0da?s=128

Kanazawa Yuki

August 26, 2021
Tweet

Transcript

  1. 2021/8/25 SPACEMARKET x Lancers Engineer Meetup SendGrid用の メールモックコンテナを作った話 https://www.lancers.jp/ 「テクノロジーで、個をエンパワーメントする」

    ランサーズ株式会社 SRE 金澤 裕毅 [Kanazawa Yuki]
  2. 2021/8/25 SPACEMARKET x Lancers Engineer Meetup 自己紹介 2 氏名:金澤 裕毅

    出身:宮城県仙台市 居住地:北海道札幌市 Lancers, Inc. / Site Reliability Engineer (2013/11 -) 趣味: 将棋(ウォーズ初段、将棋倶楽部24で1000点くらい) Github:yKanazawa Twitter: @yakitori009 Language: C++, Java, PHP, Go 2020/7に東京から引っ越し
  3. 2021/8/25 SPACEMARKET x Lancers Engineer Meetup 3 ランサーズのサーバー構成 EC2 instance

    CloudSearch CloudFront Route 53 CloudFront ALB API Gateway Lambda Auto Scaling App S3 Aurora Reader Aurora Reader Aurora Writer Mail ElastiCache Redis サムネイル表示 仕事検索 ランサー検索 ランサーズ Batch SMTP Web API SMTPから 移行中
  4. 2021/8/25 SPACEMARKET x Lancers Engineer Meetup 4 ランサーズのサーバー構成(検証環境) EC2 instance

    CloudSearch CloudFront Route 53 ALB Auto Scaling App S3 Aurora Reader Aurora Writer Mail ElastiCache Redis 仕事検索 ランサー検索 ランサーズ Batch SMTP Web API Containar Fargate
  5. 2021/8/25 SPACEMARKET x Lancers Engineer Meetup 5 ランサーズのサーバー構成(開発環境) EC2 instance

    CloudSearch ALB App S3 MySQL Mail Redis 仕事検索 ランサー検索 ランサーズ SMTP Web API SendGrid
  6. 2021/8/25 SPACEMARKET x Lancers Engineer Meetup メールモックとは?

  7. 2021/8/25 SPACEMARKET x Lancers Engineer Meetup メールモックの役割 •メールの誤送信問題 ◦セキュリティインシデントで最も多い事例 ▪開発、検証環境で間違って送信するパターンも多い

    ◦対策 ▪開発、検証環境のDBをマスキングする ▪開発、検証環境のメールサーバーをモック化する •メールモックとは? ◦ダミーのメール送信サーバー ▪メールを送信せず、サーバー内に格納する ▪格納したメールはWEB画面で確認可能
  8. 2021/8/25 SPACEMARKET x Lancers Engineer Meetup 代表的なメールモック •クラウドで提供されているもの ◦MailTrap

  9. 2021/8/25 SPACEMARKET x Lancers Engineer Meetup 代表的なメールモック •自前でサーバー、またはコンテナを立てるもの ◦MailCatcher

  10. 2021/8/25 SPACEMARKET x Lancers Engineer Meetup 代表的なメールモック •自前でサーバー、またはコンテナを立てるもの ◦MailDev

  11. 2021/8/25 SPACEMARKET x Lancers Engineer Meetup SendGridに対応したメールモックコンテナ •yudppp/simple-sendgrid-mock-server ◦弊社で大変お世話になっていたコンテナ

  12. 2021/8/25 SPACEMARKET x Lancers Engineer Meetup SendGridに対応したメールモックコンテナ •追加要望に対応する必要がでてきた ◦添付ファイルの中身を確認したい ◦50KB以上のファイルが添付できない

    ▪現状、エラーとなってしまう ◦リクエスト、レスポンスも実際のSendGirdのものと一致させたい ◦各種エラーメッセージの対応 ◦厳密なパス対応 ▪スラッシュが連続した場合、エラーとする等 自前でSendGridメールモックコンテナを作ることに
  13. 2021/8/25 SPACEMARKET x Lancers Engineer Meetup SendGridメールモックの自作

  14. 2021/8/25 SPACEMARKET x Lancers Engineer Meetup 14 メールモックの構成 •SendGrid モックAPI

    ◦(自分にとって)実装しやすそう •メール表示のUI ◦実装できるが、できれば避けたい ▪実装してもイケてるUIにならなそう APIのみ自前で構築 SMTPで既存のメールモックに送信する方針で実装
  15. 2021/8/25 SPACEMARKET x Lancers Engineer Meetup 15 メールモックの選定 •MailCatcher ◦CC、BCC等がTOに表示されてしまう

    ◦必要なミドルウェアが多い(ruby、sqlite、openssl等) ▪→コンテナが太る要因になる •MailDev ◦Node.jsのみで起動 ◦ISO-2022-JPの表示ができない •メールの「ソース」を見ないと確認できない •→SendGridはUTF-8なので関係なし MailDevを選択
  16. 2021/8/25 SPACEMARKET x Lancers Engineer Meetup SendGridモックAPIの自作

  17. 2021/8/25 SPACEMARKET x Lancers Engineer Meetup 17 言語の選定 •PHP ◦一番慣れている言語

    •Ruby ◦MailCatcherが利用している •Node.js ◦MailDevが利用している •Golang ◦バイナリのみで動作可能 ◦マルチアーキテクチャ対応が面倒 Golangを選択 (マルチアーキテクチャ対応は後述) 共通のRubyを 使うのは難しそう 共通のNode.jsを 使うのは難しそう コンテナにGolang インストール不要
  18. 2021/8/25 SPACEMARKET x Lancers Engineer Meetup 18 採用したライブラリ •echo ◦GolangのWebフレームワーク

    •apitest ◦UTの作成に使用 •validator.v9 ◦POSTパラメータのvalidateに使用 ▪パラメータ不足時にエラーメッセージを返す GitHubで公開 https://github.com/yKanazawa/sendgrid-dev
  19. 2021/8/25 SPACEMARKET x Lancers Engineer Meetup 19 GitHubで公開 •yKanazawa/sendgrid-dev ◦※これ単体でもMailTrap等と連携可能

    ▪README参照
  20. 2021/8/25 SPACEMARKET x Lancers Engineer Meetup SendGridモックコンテナの構築

  21. 2021/8/25 SPACEMARKET x Lancers Engineer Meetup 21 Dockerfileの作成 •組み込んだもの ◦Maildev(Node.js)

    ◦自作のSendGridモックAPI(yKanazawa/sendgrid-dev) ◦Supervisord ▪↑2つをまとめて運用するために導入 •(結果的に)組み込む必要がなくなったもの ◦WWWサーバー(Apache、Nginx等) ▪MailDevのUIを1080ポートで起動 ▪SendGrid APIを3030ポートで起動 ◦アプリケーションサーバー(PHP-FPM、Unicorn等) ▪言語レベルでアプリケーションサーバーを起動 ◦言語(PHP、Ruby、Golang等) ▪Golangを選択し、ビルド済バイナリのみ組み込み ◦SMTPサーバー(Postfix等) ▪MailDevのSMTPメールモックを利用 コンテナサイズ:144MBまで軽量化
  22. 2021/8/25 SPACEMARKET x Lancers Engineer Meetup 22 maildev sendgrid-dev sendgrid-maildev

    コンテナの処理の流れ SMTP 1025 HTTP Default:3030 App sendgrid-maildev Docker Desktop MailDev curl --request POST ¥ --url http://localhost:3030/v3/mail/send ¥ --header 'Authorization: Bearer SG.xxxxx' ¥ --header 'Content-Type: application/json' ¥ --data '{"personalizations": [{ "to": [{"email": "to@example.com"}]}], "from": {"email": "from@example.com"}, "subject": "Test Subject", "content": [{"type": "text/plain", "value": "Test Content"}] }' SendGrid API
  23. 2021/8/25 SPACEMARKET x Lancers Engineer Meetup 23 sendgrid-maildev コンテナの適用(AWS Fargateの例)

    ALB Fargate sendgrid-maildev Container curl --request POST ¥ --url http://sendgrid.example.com/v3/mail/send ¥ --header 'Authorization: Bearer SG.xxxxx' ¥ --header 'Content-Type: application/json' ¥ --data '{"personalizations": [{ "to": [{"email": "to@example.com"}]}], "from": {"email": "from@example.com"}, "subject": "Test Subject", "content": [{"type": "text/plain", "value": "Test Content"}] }' SendGrid API ( /v3/mail/send ) MailDev ( / ) App Port:3030 Health Check : / 404 Port:1080 Health Check : / 200 SENDGRID_DEV_API_KEY: SG.xxxx User Target Group Path: /v3/mail/send Path: /*
  24. 2021/8/25 SPACEMARKET x Lancers Engineer Meetup 24 DockerHubへのアップロード •DockerHubにリポジトリを作成 ◦ykanazawa/sendgrid-maildev

    •Githubリポジトリと連携 ◦ykanazawa/sendgrid-maildev push時に自動的に DockerHubを更新
  25. 2021/8/25 SPACEMARKET x Lancers Engineer Meetup コンテナの マルチアーキテクチャ対応について

  26. 2021/8/25 SPACEMARKET x Lancers Engineer Meetup 26 Intel x86_64系以外のCPUを搭載したPC、サーバー •M1

    Mac ◦Apple M1チップ搭載(Arm64系) ◦Docker for Mac、Rosetta2がある程度互換処理をしてくれる ▪sendgrid-maildevはx86_64でも動作した •理論上、パフォーマンスは若干落ちる ◦互換処理のオーバーヘッドがかかるため •EC2 t4g、c6g等のインスタンス ◦AWS Graviton プロセッサ搭載(Arm64系) ▪x86_64では動かない
  27. 2021/8/25 SPACEMARKET x Lancers Engineer Meetup 27 コンテナのマルチアーキテクチャ対応 •代表的なコンテナは大抵マルチアーキテクチャに対応している •buildxで複数アーキテクチャを指定してビルド

    $ docker buildx build --platform linux/amd64,linux/arm64 -t ykanazawa/sendgrid-maildev:latest --push .
  28. 2021/8/25 SPACEMARKET x Lancers Engineer Meetup 28 Golangバイナリのマルチアーキテクチャ対応 •x86_64に加え、Arm64のバイナリもビルドする ◦x86_64版

    ◦Arm64版 ◦リポジトリのReleaseにバイナリをアップロード •Dockerfile内でアーキテクチャを判定して対応バイナリをDL $ env GOOS=linux GOARCH=amd64 go build -o sendgrid-dev_x86_64 main.go $ env GOOS=linux GOARCH=arm64 go build -o sendgrid-dev_aarch64 main.go RUN curl -L -o /usr/local/bin/sendgrid-dev https://github.com/yKanazawa/sendgrid-dev/releases/download/v0.9.0/sendgrid-dev_ $(if [ $(uname -m) = "aarch64" ]; then echo aarch64; else echo x86_64; fi) 単純に$(uname –m)では不可(if文で対応)
  29. 2021/8/25 SPACEMARKET x Lancers Engineer Meetup まとめと今後の課題

  30. 2021/8/25 SPACEMARKET x Lancers Engineer Meetup 今後の課題 •エラーパターンの網羅 ◦現在、大体網羅できているがコンプリートを目指す •Travis

    CIの導入 ◦go testを回す ◦自動的にビルド
  31. 2021/8/25 SPACEMARKET x Lancers Engineer Meetup ご清聴ありがとうございました!