$30 off During Our Annual Pro Sale. View Details »

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/

Fumiaki MATSUSHIMA

March 25, 2018
Tweet

More Decks by Fumiaki MATSUSHIMA

Other Decks in Programming

Transcript

  1. Qall - Docker で作る
    Quipper の開発環境
    @mtsmfm Fumiaki Matsushima
    2018.03.25 Rails Developers Meetup 2018: Day 2

    View Slide

  2. ➔ Quipper Ltd 所属
    ➔ Ruby と麻雀が好き
    ➔ 西日暮里.rb 主催
    ➔ GraphQL Tokyo 主催
    @mtsmfm.inspect

    View Slide

  3. https://www.quipper.com/

    View Slide

  4. https://studysapuri.jp/

    View Slide

  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

    View Slide

  6. View Slide

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

    View Slide

  8. View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  16. View Slide

  17. Qall - Docker で作る
    Quipper の開発環境
    @mtsmfm Fumiaki Matsushima
    2018.03.25 Rails Developers Meetup 2018: Day 2

    View Slide

  18. Qall - Quipper All

    View Slide

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

    View Slide

  20. 大事なことは最初に

    View Slide

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

    View Slide

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

    View Slide

  23. 01Qall がなぜ必要か

    View Slide

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

    View Slide

  25. 生徒用
    先生用
    保護者

    管理者

    コンテン

    入稿用 Mongo
    Postgres
    ...

    View Slide

  26. 生徒用
    先生用
    保護者

    管理者

    コンテン

    入稿用 Mongo
    Postgres
    ...

    View Slide

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

    View Slide

  28. ➔ API + フロント + ワーカー + etc… を各アプリ毎に
    ➔ 単機能の開発だと全部は要らないことが多い
    ◆ あまり改修が入らないところのセットアップが
    後回しにされがち
    ◆ 障害調査などとっさの時に困る
    システム全体の構成要素は増え続ける

    View Slide

  29. ドキュメントは劣化していく

    View Slide

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

    View Slide

  31. 生徒用
    先生用
    保護者

    管理者

    コンテン

    入稿用 Mongo
    Postgres
    全部まとめて
    Docker Compose で
    ...

    View Slide

  32. Qall の構成
    02

    View Slide

  33. ➔ 各リポジトリには Docker 固有のファイルを(ひとまず)持たない
    ◆ 最小公倍数的な Dockerfile を 1 つ
    ◆ 違うところは build arg で回避
    ➔ 各リポジトリは qall 上に clone してくる
    Qall の基本方針

    View Slide

  34. qall
    |----- Dockerfile
    |----- docker-compose.yml
    |----- repos
    | |----- student-api
    | |----- student-front
    | |----- ...
    |----- envs
    |----- student-api.env
    |----- student-front.env
    |----- ...
    各リポジトリ
    各リポジトリ毎の
    ローカル用環境変数

    View Slide

  35. 日常的に使うと
    見えてくる問題

    View Slide

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

    View Slide

  37. macOS
    Docker CLI
    $ dc run app rails s
    $ alias dc=docker-compose

    View Slide

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

    View Slide

  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

    View Slide

  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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  45. 使い物にならない

    View Slide

  46. OSXFS を使わない

    View Slide

  47. 案1. docker-sync

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  55. 理屈上は
    ローカルと同じ速度になる

    View Slide

  56. docker-sync よく死ぬ問題

    View Slide

  57. Docker
    Container
    Engine
    macOS
    rails s
    Docker CLI
    docker-sync
    OSXFS
    app
    gem
    app
    gem
    /host_sync
    app
    gem
    /app_sync
    なぜか死ぬことがある

    View Slide

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

    View Slide

  59. 案2. R/W が多いところを
    ひたすら Volume 化

    View Slide

  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

    View Slide

  61. ➔ vendor/bundle、tmp、node_modules とか
    ◆ sprockets 使っているときは tmp がよく効く
    ➔ ディレクトリがないところに mount すると所有者が root に
    なってしまうため、Rails コマンドなどを実行するユーザとして
    Dockerfile 内で予め作っておく
    R/W が多いところは Volume に

    View Slide

  62. 速度か安定性か

    View Slide

  63. 速度 >>> 安定性

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  69. 速度 <<< 安定性

    View Slide

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

    View Slide

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

    View Slide

  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

    View Slide

  73. ➔ Bash とか Pry とかのヒストリバックが
    C-p のあとに何か押さないと動かない
    ➔ C-p C-q が Docker のデフォルトのデタッチキーバインド
    ◆ Docker CLI なら config.json で上書きできるが、
    Docker Compose だと config.json を見ない...
    Compose 介すと C-p が動かない

    View Slide

  74. 直した

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  78. Pow ってあったね

    View Slide

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

    View Slide

  80. Docker でも欲しい

    View Slide

  81. 作った

    View Slide

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

    View Slide

  83. ➔ http://.localhost でアクセスできる
    ◆ http://localhost には一覧が出る
    ◆ ngx-mruby 製
    ◆ HMR などもちゃんと動く
    Yaichi

    View Slide

  84. https://hub.docker.com/r/mtsmfm/yaichi/

    View Slide

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

    View Slide

  86. docker-compose.yml.erb

    View Slide

  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 に

    View Slide

  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:

    View Slide

  89. https://gist.github.com/mtsmfm/3235b3fc4a55baa45d8538f8acab911e

    View Slide

  90. 課題
    03

    View Slide

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

    View Slide

  92. ➔ 本番 (Deis) と同じイメージに
    ➔ 各リポジトリ毎に Dockerfile を
    ➔ 個々人で docker build せずに pull する構造に
    ➔ docker-compose やめて k8s に移行
    ◆ helm?
    Qall の課題

    View Slide

  93. Docker 上開発環境を
    取り巻く課題

    View Slide

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

    View Slide

  95. ➔ letter_opener
    ◆ コンテナ上にブラウザがいない
    ➔ ChromeDriver による E2E テスト
    ◆ コンテナ上にブラウザがいない
    今まで通りでは動かなくなるが
    解決策があるもの

    View Slide

  96. ➔ SMTP サーバと Web インターフェースがくっついたものを Docker 上
    で立てるのが楽
    ◆ sj26/mailcatcher
    ◆ djfarrelly/maildev
    letter_opener

    View Slide

  97. ➔ Selenium の公式イメージを使って、Remote Driver として
    セットアップ
    ◆ selenium/standalone-chrome-debug はデスクトップ環境が
    ついてきて、 VNC でログインできて便利
    ChromeDriver (Selenium)

    View Slide

  98. 詳しくはこっちを
    https://speakerdeck.com/mtsmfm/rails-system-test-on-docker

    View Slide

  99. ➔ save_and_open_page
    ◆ スクショ.png を ホストに見えるところに置けば開けるが...
    ➔ bundle open
    ◆ Gem はホストにない
    ◆ エディタはホストにある
    今までのように動かなくなるもの

    View Slide

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

    View Slide

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

    View Slide

  102. http://rubykaigi.org/2017/presentations/mtsmfm.html

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  113. View Slide