Qall - Development env on Docker for Quipper

Qall - Development env on Docker for Quipper

Rails Developers Meetup 2018 Day 2 発表資料

https://railsdm.github.io/2018/

Fb1b9f3d7332a7a7e262b70013b5f7dd?s=128

Fumiaki MATSUSHIMA

March 25, 2018
Tweet

Transcript

  1. Qall - Docker で作る Quipper の開発環境 @mtsmfm Fumiaki Matsushima 2018.03.25

    Rails Developers Meetup 2018: Day 2
  2. ➔ Quipper Ltd 所属 ➔ Ruby と麻雀が好き ➔ 西日暮里.rb 主催

    ➔ GraphQL Tokyo 主催 @mtsmfm.inspect
  3. https://www.quipper.com/

  4. https://studysapuri.jp/

  5. https://github.com/kyanny/railsdm2018/blob/37a08ecef5d295a6d14838f34baa105fbc6c3f53/Quipper%20%E3%81%AB% E3%81%8A%E3%81%91%E3%82%8B%E3%80%8C%E9%96%A2%E5%BF%83%E3%81%AE%E5%88%86%E9%9B%A2% E3%80%8D%E3%81%AE%E6%AD%B4%E5%8F%B2.pdf

  6. None
  7. 技術的負債を作らないのは不可能。 簡単に返済できる環境を作る。 - @masatomo, Quipper Ltd CTO

  8. None
  9. Tegaki-jan http://mtsmfm.github.io/tegaki-jan/

  10. https://github.com/mtsmfm/language_server-ruby

  11. 西日暮里.rb https://ninirb.github.io

  12. https://nishinipporirb.doorkeeper.jp/events/71936

  13. GraphQL Tokyo https://www.meetup.com/ja-JP/GraphQL-Tokyo/

  14. https://www.meetup.com/ja-JP/GraphQL-Tokyo/events/248222891/

  15. 開発環境 Docker 縛り歴 1年半

  16. None
  17. Qall - Docker で作る Quipper の開発環境 @mtsmfm Fumiaki Matsushima 2018.03.25

    Rails Developers Meetup 2018: Day 2
  18. Qall - Quipper All

  19. ➔ 開発環境としての Docker の啓蒙 ➔ Docker 上の開発環境を前提とした ツールの整備の促進 発表の目的

  20. 大事なことは最初に

  21. Docker で やさしい開発環境を 作っていこう

  22. 01 02 03 Agenda | Qall がなぜ必要か Qall の構成 課題

  23. 01Qall がなぜ必要か

  24. A. セットアップが めんどくさいから

  25. 生徒用 先生用 保護者 用 管理者 用 コンテン ツ 入稿用 Mongo

    Postgres ...
  26. 生徒用 先生用 保護者 用 管理者 用 コンテン ツ 入稿用 Mongo

    Postgres ...
  27. 生徒用 Mongo Postgres Memcached Redis API Front Worker

  28. ➔ API + フロント + ワーカー + etc… を各アプリ毎に ➔

    単機能の開発だと全部は要らないことが多い ◆ あまり改修が入らないところのセットアップが 後回しにされがち ◆ 障害調査などとっさの時に困る システム全体の構成要素は増え続ける
  29. ドキュメントは劣化していく

  30. 特に新入りには厳しい!

  31. 生徒用 先生用 保護者 用 管理者 用 コンテン ツ 入稿用 Mongo

    Postgres 全部まとめて Docker Compose で ...
  32. Qall の構成 02

  33. ➔ 各リポジトリには Docker 固有のファイルを(ひとまず)持たない ◆ 最小公倍数的な Dockerfile を 1 つ

    ◆ 違うところは build arg で回避 ➔ 各リポジトリは qall 上に clone してくる Qall の基本方針
  34. qall |----- Dockerfile |----- docker-compose.yml |----- repos | |----- student-api

    | |----- student-front | |----- ... |----- envs |----- student-api.env |----- student-front.env |----- ... 各リポジトリ 各リポジトリ毎の ローカル用環境変数
  35. 日常的に使うと 見えてくる問題

  36. ➔ rails new したての状態で、bin/rails -T がローカルと比べて 10 倍以 上遅いんだけど??? Docker

    for Mac が遅い
  37. macOS Docker CLI $ dc run app rails s $

    alias dc=docker-compose
  38. Hypervisor Framework (VM) Linux Docker Container Engine macOS Docker CLI

    $ dc run app rails s $ alias dc=docker-compose
  39. Hypervisor Framework (VM) Linux OSXFS Docker Container Engine macOS Rails

    gem rails s Docker CLI $ dc run app rails s $ alias dc=docker-compose
  40. Hypervisor Framework (VM) Linux OSXFS Docker Container Engine macOS Rails

    gem rails s Docker CLI R/Wがすごく遅い $ dc run app rails s $ alias dc=docker-compose
  41. User-guided cache https://blog.docker.com/2017/05/user-guided-caching-in-docker-for-mac/#h.72tgxspoi9yj

  42. User-guided cache https://blog.docker.com/2017/05/user-guided-caching-in-docker-for-mac/#h.72tgxspoi9yj 10秒

  43. User-guided cache https://blog.docker.com/2017/05/user-guided-caching-in-docker-for-mac/#h.72tgxspoi9yj 10秒 rake -T

  44. rake -T が10秒?!?!?!

  45. 使い物にならない

  46. OSXFS を使わない

  47. 案1. docker-sync

  48. Docker Container Engine macOS Docker CLI app gem $ docker-sync

    start
  49. Docker Container Engine macOS Docker CLI docker-sync app gem $

    docker-sync start
  50. Docker Container Engine macOS Docker CLI docker-sync OSXFS app gem

    app gem /host_sync $ docker-sync start
  51. Docker Container Engine macOS Docker CLI docker-sync OSXFS app gem

    app gem /host_sync app gem /app_sync Unison で同期 $ docker-sync start
  52. Docker Container Engine macOS Docker CLI docker-sync OSXFS app gem

    app gem /host_sync app gem /app_sync $ dc run app rails s $ alias dc=docker-compose
  53. Docker Container Engine macOS rails s Docker CLI docker-sync OSXFS

    app gem app gem /host_sync app gem /app_sync $ dc run app rails s $ alias dc=docker-compose
  54. Docker Container Engine macOS rails s Docker CLI docker-sync OSXFS

    app gem app gem /host_sync app gem /app_sync 遅い 速い $ dc run app rails s $ alias dc=docker-compose
  55. 理屈上は ローカルと同じ速度になる

  56. docker-sync よく死ぬ問題

  57. Docker Container Engine macOS rails s Docker CLI docker-sync OSXFS

    app gem app gem /host_sync app gem /app_sync なぜか死ぬことがある
  58. ➔ OSXFS がうまく更新できていなかったり、Unison が同期に失敗したり ➔ 問題が起きたときに気づくのが非常に難しい ◆ エディタ上は保存しているのにコンテナ内には反映されていないか もしれない事を常に気にしないといけない docker-sync

    よく死ぬ問題
  59. 案2. R/W が多いところを ひたすら Volume 化

  60. Hypervisor Framework (VM) Linux Docker Container Engine macOS rails s

    $ dc run app rails s Docker CLI BUNDLE_PATH を Volume に gem app Gem 以外は諦める OSXFS $ alias dc=docker-compose
  61. ➔ vendor/bundle、tmp、node_modules とか ◆ sprockets 使っているときは tmp がよく効く ➔ ディレクトリがないところに

    mount すると所有者が root に なってしまうため、Rails コマンドなどを実行するユーザとして Dockerfile 内で予め作っておく R/W が多いところは Volume に
  62. 速度か安定性か

  63. 速度 >>> 安定性

  64. - binding.pry 書いたのに止まらない - なんか SyntaxError - テスト落ちる

  65. エディタを睨んでも わからない -> docker-sync 死んでる

  66. 速度 >>> 安定性 そう思った時期もありました

  67. docker-sync なしでも動くように

  68. 誰も使わなくなったので 設定を完全削除

  69. 速度 <<< 安定性

  70. https://github.com/mtsmfm/rails-on-docker-benchmark

  71. ※実際は app 以下が 育つことで もっと docker-sync の方が速 くなる

  72. Dockerfile の例 ARG QALL_REPO_NAME ARG QALL_MOUNT_DIRS RUN mkdir -p /quipper/$QALL_REPO_NAME

    && \ cd /quipper/$QALL_REPO_NAME && \ (test -z "$QALL_MOUNT_DIRS" || mkdir -p $QALL_MOUNT_DIRS) && \ chown -R quipper:quipper /quipper
  73. ➔ Bash とか Pry とかのヒストリバックが C-p のあとに何か押さないと動かない ➔ C-p C-q

    が Docker のデフォルトのデタッチキーバインド ◆ Docker CLI なら config.json で上書きできるが、 Docker Compose だと config.json を見ない... Compose 介すと C-p が動かない
  74. 直した

  75. https://github.com/docker/docker-py/pull/1826

  76. docker-compose 1.20 (docker-py 3.0.0) から ~/.docker/config.json を 見てくれるように

  77. ➔ localhost:3000 が生徒用で、localhost:3001 が先生用で... Port 番号が覚えられない

  78. Pow ってあったね

  79. ➔ <app name>.test でアクセスできるようにしてくれるやつ Pow http://pow.cx/

  80. Docker でも欲しい

  81. 作った

  82. https://mtsmfm.github.io/2017/06/29/yaichi.html

  83. ➔ http://<container-name>.localhost でアクセスできる ◆ http://localhost には一覧が出る ◆ ngx-mruby 製 ◆

    HMR などもちゃんと動く Yaichi
  84. https://hub.docker.com/r/mtsmfm/yaichi/

  85. ➔ このリポジトリには mongo と pg と redis と memcached 、こっちは

    redis は要らなくて... ◆ リポジトリ毎に欲しくなるミドルウェアと、それに対応した環境変数を 都度書くのがめんどくさすぎる 複雑化する docker-compose.yml
  86. docker-compose.yml.erb

  87. api: ruby_version: 2.5.0 nodejs_version: 6.13.1 commands: default: bundle exec rails

    s -b 0.0.0.0 worker: bundle exec rake resque:start depends_on: [mongo, redis] mount_dirs: [tmp] こんな感じの YAML を元にする Build args に 各々 service と command に Build args に リポジトリ単位の service に
  88. services: api: &api container_name: qall-api command: bundle exec rails s

    -b 0.0.0.0 build: context: . args: RUBY_VERSION: 2.5.0 NODEJS_VERSION: 6.13.1 QALL_REPO_NAME: api QALL_MOUNT_DIRS: tmp working_dir: /quipper/api volumes: - vendor:/vendor - home:/home/quipper - ./repos:/quipper:cached - tmp-api:/quipper/api/tmp environment: BUNDLE_PATH: /vendor/bundle/2.5.0 MONGODB_HOST: mongo REDIS_URL: redis://redis-api env_file: - envs/common.env - envs/api.env depends_on: [mongo, redis-api] tty: true stdin_open: true api-worker: <<: *api container_name: qall-api-worker command: bundle exec rake resque:start mongo: container_name: qall-mongo image: mongo volumes: - mongo-data:/data/db redis-api: container_name: qall-redis-api image: redis:alpine yaichi: container_name: qall-yaichi image: mtsmfm/yaichi ports: - 80:3000 volumes: - /var/run/docker.sock:/var/run/docker.sock volumes: home: mongo-data: vendor: tmp-api:
  89. https://gist.github.com/mtsmfm/3235b3fc4a55baa45d8538f8acab911e

  90. 課題 03

  91. 1. Qall としての課題 2. Docker 上開発環境を 取り巻く課題

  92. ➔ 本番 (Deis) と同じイメージに ➔ 各リポジトリ毎に Dockerfile を ➔ 個々人で

    docker build せずに pull する構造に ➔ docker-compose やめて k8s に移行 ◆ helm? Qall の課題
  93. Docker 上開発環境を 取り巻く課題

  94. Docker 化によって、 今までのように 動かなくなるものも

  95. ➔ letter_opener ◆ コンテナ上にブラウザがいない ➔ ChromeDriver による E2E テスト ◆

    コンテナ上にブラウザがいない 今まで通りでは動かなくなるが 解決策があるもの
  96. ➔ SMTP サーバと Web インターフェースがくっついたものを Docker 上 で立てるのが楽 ◆ sj26/mailcatcher

    ◆ djfarrelly/maildev letter_opener
  97. ➔ Selenium の公式イメージを使って、Remote Driver として セットアップ ◆ selenium/standalone-chrome-debug はデスクトップ環境が ついてきて、

    VNC でログインできて便利 ChromeDriver (Selenium)
  98. 詳しくはこっちを https://speakerdeck.com/mtsmfm/rails-system-test-on-docker

  99. ➔ save_and_open_page ◆ スクショ.png を ホストに見えるところに置けば開けるが... ➔ bundle open ◆

    Gem はホストにない ◆ エディタはホストにある 今までのように動かなくなるもの
  100. ➔ Linter などのエディタ連携 ◆ 基本ホストにインストールされている前提 ◆ Gem がコンテナ内にしかない • ホストからは見えないファイルがある

    今までのように動かなくなるもの
  101. ➔ 静的解析にしろ、動的解析にしろ、アプリと同一環境、 同一イメージじゃないと得られない情報がある ➔ docker-compose の起動コストが高い ◆ Docker 上で何かプロセスを上げといて、そいつとエディタを繋げ ればいいのでは?

    • それ Language Server で Docker 時代のエディタ連携
  102. http://rubykaigi.org/2017/presentations/mtsmfm.html

  103. 特に OSS とか セットアップの 敷居低いほうがいいよね

  104. docker-py は手元でも docker 上でテスト https://github.com/docker/docker-py/blob/a4e642b015c50d9c628413341ed00c89599f66be/Makefile

  105. https://github.com/mtsmfm/docker-rails-dev-box rails/rails-dev-box の Docker 版

  106. ホストOS上に 何がいるべきか よくわからなくなってくる

  107. エディタ、ブラウザ etc も Docker 上であるべき?

  108. みたいな議論がしたい

  109. そもそも Docker 上に 開発環境作っている人が 少ない (?)

  110. 既に環境ができている人、 慣れている人からすると 移行するメリットが薄い

  111. 人もアプリも協働するもの

  112. Docker で やさしい開発環境を 作っていこう

  113. None