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

デプロイ元をCircleCIからHerokuに乗り換えた

 デプロイ元をCircleCIからHerokuに乗り換えた

Heroku Meetup #25 "Heroku Ghost" で 2 回話してきた #herokujp
https://developer.feedforce.jp/entry/2019/07/29/140000

D6c5403c0b6ef2f9fd51910ea38323a3?s=128

Takashi Masuda

July 26, 2019
Tweet

More Decks by Takashi Masuda

Other Decks in Programming

Transcript

  1. デプロイ元をCircleCIから Herokuに乗り換えた Heroku Meetup #25 "Heroku Ghost" 2019-07-26 @masutaka

  2. HerokuJP-UG Slackにて https://herokujp-ug.slack.com/archives/C9LRC3M25/p1560763558027800

  3. モチベーション

  4. モチベーション • 今関わっているサービスのデプロイフローが複雑だと感 じていた • Heroku Meetup #23 阿部さんのセッション『正しく理 解するHeroku

    Flow』 ◦ CIが通ったらHerokuのAutomatic deploysを使ってデプロイすることがベストプラクティ ス • 出来ればそれに従いたい、いつかはやろうと思っていた https://herokujp.doorkeeper.jp/events/82754
  5. Heroku Flow https://www.heroku.com/flow

  6. なぜCircleCIからデプロイしていたか • 元々はHeroku上でデプロイしていた • デプロイスピード向上のためにCircleCIでのビルドに切 り替えたそう ◦ 私がチームに入る前の話 ◦ 当時の記録によると、2分7秒に短くなったとのこと。変更前のデプロイ時間は不明

  7. 現在関わっているサービス

  8. EC Booster 国内初のGoogleショッピング広告自動運用ツール

  9. 今回の技術スタック Heroku App Web Dyno GraphQL Client (apollo-client) GraphQL Server

    (graphql-ruby on Rails) Worker Dyno Chrome (headless mode) chromedriver sidekiq Heroku Postgres Heroku Redis
  10. 1つのHeroku Appに 割とたくさん詰まっています。

  11. 以前のデプロイフロー

  12. 以前のbuildpack 1. heroku/ruby 2. heroku-buildpack-google-chrome ◦ https://github.com/heroku/heroku-buildpack-google-chrome.git 3. heroku-buildpack-chromedriver ◦

    https://github.com/heroku/heroku-buildpack-chromedriver.git
  13. 以前のデプロイフロー 1. CIが通る 2. Assets(.js,.css,.svg,...)を作成 3. 作成したAssetsをgit commit 4. git

    push heroku master 5. Slugの作成 6. Release phase 7. Dynoの起動 8. Chromeとchromedriverのvalidate 9. Bugsnagにcommit hashをcurlで通知 10. Bugsnagにsourcemapをアップロード 高速化のつもりが、 効果をなさなくなっ ていた(調査の過程 で分かった)
  14. 使用していたデプロイスクリプト(135行)

  15. 何が悪かったのか

  16. 何が悪かったのか • Heroku Flowから反している • 属人化したデプロイスクリプト • CircleCIのコンテナを無駄に消費する • Herokuだけに存在するgitのcommit

    hashが出来る • ReviewApp作成に無駄がある(後述)
  17. ReviewApp作成に無駄がある 1. ReviewApp作成開始 2. Slugの作成 3. Release phase 4. ReviewApp作成完了

    1. CI 2. Deploy 5. Slugの作成 6. Release phase 7. ReviewApp再起動 git push Assetsがないの で、まだ起動でき ない Assetsが作られ、 ようやく起動でき た PR作成をトリガーに自 動的に開始する。 CircleCIとは順序依存 なく始まる
  18. 現在のデプロイフロー

  19. 現在のbuildpack 1. heroku/nodejs ← 追加 2. heroku/ruby 3. heroku-buildpack-google-chrome ◦

    https://github.com/heroku/heroku-buildpack-google-chrome.git 4. heroku-buildpack-chromedriver ◦ https://github.com/heroku/heroku-buildpack-chromedriver.git
  20. 現在のデプロイフロー 1. CIが通る 2. Slugの作成 a. Assets(.js,.css,.svg,...)を作成 b. Bugsnagにsourcemapをアップロード 3.

    Release phase a. Chromeとchromedriverのvalidate 4. Dynoの起動 5. deployhooks:httpがBugsnagにcommit hash を通知 Heroku Automatic deploy
  21. 現在のデプロイスクリプト なし

  22. 改善されて普通になったReviewApp作成 1. ReviewApp作成開始 2. Slugの作成 3. Release phase 4. ReviewApp作成完了

    1. CI PR作成をトリガーに自 動的に開始する。 CircleCIとは順序依存 なく始まる
  23. デプロイ時間の変化

  24. 以前のデプロイ時間は6分ほど

  25. 現在のデプロイ時間も6分ほど

  26. デプロイ時間の変化 • 大きな劣化もなく、Herokuに乗り換えられた ◦ storybook作成をHerokuからCircleCIに変更するなど、細かいチューニングは行った ◦ CIやデプロイまわりの処理は徹底的に調べた

  27. 得られた知見

  28. 全般的な知見やメリット • CircleCIからgit pushするメリットはない ◦ CircleCI上でのgit commitは論外 • Heroku Automatic

    deployは賢い ◦ 連続したデプロイを1つにまとめることがある • GitHubから見るとCI時間が短くなる ◦ CircleCIのデプロイジョブがなくなるため • Review Appは作り直せば普通に動く ◦ デプロイスクリプトとはなんだったのか
  29. heroku/nodejs buildpackの知見 • package.jsonのenginesに書かれたバージョンの Node.jsとnpmをインストールする • package.jsonにbuild scriptが定義されていれば、npm install後に実行する ◦

    ただし、heroku-postbuild scriptも定義されていれば、こちらが実行される • package.jsonのdevDependenciesはSlugに含まれない https://devcenter.heroku.com/articles/nodejs-support
  30. heroku/ruby buildpackの知見 • すでにNode.jsがインストールされていれば、Node.jsを インストールしない • ゆえにheroku/nodejs buildpackとの順番が非常に大事 1. heroku/nodejs

    2. heroku/ruby • Node.jsがインストールされていなければ、固定バージョ ンのNode.jsとyarnをインストールする。npmはインス トールしない https://devcenter.heroku.com/articles/ruby-support
  31. ヒヤリ

  32. ヒヤリ • Bugsnag sourcemapアップロード時にはgitのcommit hashが必要 • $HEROKU_SLUG_COMMITを使う予定だった ◦ Heroku lab

    runtime-dyno-metadataが提供する • しかし、Slugビルド時には定義されていなかった ◦ 使い勝手が落ちるので、全部revertすることも覚悟した • Slugビルド時には$SOURCE_VERSIONが使えた ◦ https://devcenter.heroku.com/articles/buildpack-api#bin-compile-summary
  33. 教訓 • Herokuのドキュメントは充実している。まずは読むべし ◦ よく読んだらBuildpack APIのドキュメントに$SOURCE_VERSIONが書いてあった ◦ https://devcenter.heroku.com/articles/buildpack-api

  34. あわせて読みたい • buildpackのソースコードを読むとなお良い。発見が多い ◦ 例えばbuildpack-stdlibの存在 ◦ https://github.com/heroku/buildpack-stdlib

  35. 課題

  36. 課題 • まだHeroku Flowに乗りきれていない ◦ Promoteを使えていない ◦ ステージごとにCDNのURLを切り替えているため ◦ CircleCIでgit

    commitしていた負債 ◦ CDNはCloudFrontを使っており、OriginをHerokuにしている
  37. 自己紹介

  38. 自己紹介 • 増田貴士(@masutaka) • Heroku Meetupは前々回#23から参加 • 株式会社フィードフォース • EC

    Boosterの裏方エンジニア • EC Boosterはバッチ処理が多い • 安定したバッチ処理を実行するための基盤を模索中
  39. ご清聴ありがとうございました

  40. おまけ

  41. おまけ1: Chromeとchromedriverのvalidate release: bin/release # Web app web: bundle exec

    puma -C config/puma.rb worker: PROCESS_TYPE=worker bundle exec sidekiq -C config/sidekiq.yml # Ad app ad_worker: PROCESS_TYPE=ad_worker bundle exec sidekiq -C config/sidekiq.yml #!/bin/sh -eu # バイナリが実行できるかを確認。失敗したらこの スクリプトは即時にエラー終了する。 chromedriver --version $HOME/.apt/opt/google/chrome/chrome --version bin/rails db:migrate db:seed bin/release Procfile
  42. おまけ2: Chromeとchromedriverをvalidateしている理由 • 以前、起動出来ないChromeが本番環境にリリースされてしまった ◦ 原因: https://github.com/heroku/heroku-buildpack-google-chrome/issues/56 • せめて動くバイナリであってほしい・・・! •

    PR作った ◦ https://github.com/heroku/heroku-buildpack-google-chrome/pull/72 ▪ 2ヶ月ほど経過 ◦ https://github.com/heroku/heroku-buildpack-chromedriver/pull/16 ▪ 複雑になりすぎて諦めた ▪ Buildpackに依存関係を付ける機能があれば解決できた
  43. おまけ3: Chrome & chromedriver buildpackの細かすぎる知見 • chromedriver buildpackは暗黙的にChrome buildpack に依存している

    • chromedriver buildpackだけをインストールしても、必 要な.soが足りない • Chrome buildpackもインストールして初めて、ELFの実 行ファイルとして使うことが出来る https://github.com/heroku/heroku-buildpack-chromedriver/pull/16
  44. ②マージ 以前のブランチ戦略 各ブランチ master ブランチ production ブランチ production demo staging

    Revew App1 Revew App2 Revew AppN ①デプロイ ④マージ (git-pr-release) ③デプロイ ⑥デプロイ https://github.com/motemen/git-pr-release ︙
  45. ②マージ 現在のブランチ戦略 各ブランチ master ブランチ production demo staging Revew App1

    Revew App2 Revew AppN ①デプロイ ③デプロイ Review Appを極 力productionに 近づける。 ちょっと豪快かな。。。 ︙ Slugレベルで同じものを本 番環境に出せていない