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

Kanazawa Yuki

August 26, 2021
Tweet

More Decks by Kanazawa Yuki

Other Decks in Technology

Transcript

  1. 2021/8/25 SPACEMARKET x Lancers Engineer Meetup
    SendGrid用の
    メールモックコンテナを作った話
    https://www.lancers.jp/
    「テクノロジーで、個をエンパワーメントする」
    ランサーズ株式会社 SRE
    金澤 裕毅 [Kanazawa Yuki]

    View Slide

  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に東京から引っ越し

    View Slide

  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から
    移行中

    View Slide

  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

    View Slide

  5. 2021/8/25 SPACEMARKET x Lancers Engineer Meetup
    5
    ランサーズのサーバー構成(開発環境)
    EC2
    instance
    CloudSearch ALB
    App
    S3
    MySQL
    Mail
    Redis
    仕事検索
    ランサー検索
    ランサーズ
    SMTP
    Web
    API
    SendGrid

    View Slide

  6. 2021/8/25 SPACEMARKET x Lancers Engineer Meetup
    メールモックとは?

    View Slide

  7. 2021/8/25 SPACEMARKET x Lancers Engineer Meetup
    メールモックの役割
    ●メールの誤送信問題
    ○セキュリティインシデントで最も多い事例
    ■開発、検証環境で間違って送信するパターンも多い
    ○対策
    ■開発、検証環境のDBをマスキングする
    ■開発、検証環境のメールサーバーをモック化する
    ●メールモックとは?
    ○ダミーのメール送信サーバー
    ■メールを送信せず、サーバー内に格納する
    ■格納したメールはWEB画面で確認可能

    View Slide

  8. 2021/8/25 SPACEMARKET x Lancers Engineer Meetup
    代表的なメールモック
    ●クラウドで提供されているもの
    ○MailTrap

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  12. 2021/8/25 SPACEMARKET x Lancers Engineer Meetup
    SendGridに対応したメールモックコンテナ
    ●追加要望に対応する必要がでてきた
    ○添付ファイルの中身を確認したい
    ○50KB以上のファイルが添付できない
    ■現状、エラーとなってしまう
    ○リクエスト、レスポンスも実際のSendGirdのものと一致させたい
    ○各種エラーメッセージの対応
    ○厳密なパス対応
    ■スラッシュが連続した場合、エラーとする等
    自前でSendGridメールモックコンテナを作ることに

    View Slide

  13. 2021/8/25 SPACEMARKET x Lancers Engineer Meetup
    SendGridメールモックの自作

    View Slide

  14. 2021/8/25 SPACEMARKET x Lancers Engineer Meetup
    14
    メールモックの構成
    ●SendGrid モックAPI
    ○(自分にとって)実装しやすそう
    ●メール表示のUI
    ○実装できるが、できれば避けたい
    ■実装してもイケてるUIにならなそう
    APIのみ自前で構築
    SMTPで既存のメールモックに送信する方針で実装

    View Slide

  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を選択

    View Slide

  16. 2021/8/25 SPACEMARKET x Lancers Engineer Meetup
    SendGridモックAPIの自作

    View Slide

  17. 2021/8/25 SPACEMARKET x Lancers Engineer Meetup
    17
    言語の選定
    ●PHP
    ○一番慣れている言語
    ●Ruby
    ○MailCatcherが利用している
    ●Node.js
    ○MailDevが利用している
    ●Golang
    ○バイナリのみで動作可能
    ○マルチアーキテクチャ対応が面倒
    Golangを選択
    (マルチアーキテクチャ対応は後述)
    共通のRubyを
    使うのは難しそう
    共通のNode.jsを
    使うのは難しそう
    コンテナにGolang
    インストール不要

    View Slide

  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

    View Slide

  19. 2021/8/25 SPACEMARKET x Lancers Engineer Meetup
    19
    GitHubで公開
    ●yKanazawa/sendgrid-dev
    ○※これ単体でもMailTrap等と連携可能
    ■README参照

    View Slide

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

    View Slide

  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まで軽量化

    View Slide

  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": "[email protected]"}]}],
    "from": {"email": "[email protected]"},
    "subject": "Test Subject",
    "content": [{"type": "text/plain", "value": "Test Content"}]
    }'
    SendGrid API

    View Slide

  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": "[email protected]"}]}],
    "from": {"email": "[email protected]"},
    "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: /*

    View Slide

  24. 2021/8/25 SPACEMARKET x Lancers Engineer Meetup
    24
    DockerHubへのアップロード
    ●DockerHubにリポジトリを作成
    ○ykanazawa/sendgrid-maildev
    ●Githubリポジトリと連携
    ○ykanazawa/sendgrid-maildev
    push時に自動的に
    DockerHubを更新

    View Slide

  25. 2021/8/25 SPACEMARKET x Lancers Engineer Meetup
    コンテナの
    マルチアーキテクチャ対応について

    View Slide

  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では動かない

    View Slide

  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 .

    View Slide

  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文で対応)

    View Slide

  29. 2021/8/25 SPACEMARKET x Lancers Engineer Meetup
    まとめと今後の課題

    View Slide

  30. 2021/8/25 SPACEMARKET x Lancers Engineer Meetup
    今後の課題
    ●エラーパターンの網羅
    ○現在、大体網羅できているがコンプリートを目指す
    ●Travis CIの導入
    ○go testを回す
    ○自動的にビルド

    View Slide

  31. 2021/8/25 SPACEMARKET x Lancers Engineer Meetup
    ご清聴ありがとうございました!

    View Slide