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

devcontainer Multi Repository 戦略

Nao Yokotsuka
October 10, 2023
2.5k

devcontainer Multi Repository 戦略

Nao Yokotsuka

October 10, 2023
Tweet

Transcript

  1.  
    devcontainer Multi Repository 戦略
    2023.09.27

    View full-size slide

  2.  
    2
    2022年4⽉に freee 株式会社に新卒⼊社。
    サービス基盤という部署で、社内共通ライブラリの
    開発や、システム全体のボトルネックの解消、
    将来のアーキテクチャ議論などに取り組んでいます。
    業務では Ruby または Go を書いていることが
    多いです。
    不要なコードを⾒つけて消すのが好きです。
    横塚 直
    freee 株式会社 エンジニア
    Nao Yokotsuka
    プロフィール画像の
    トリミング⽅法

    View full-size slide

  3.  
    3
    Misson プロダクト開発チームが開発に専念できる環境を実現する。
    ● 普段の業務
    ○ バックエンド向けのライブラリ開発(主に Ruby, Go)
    ○ #認証 #サービス間連携 #ロギング #エラー通知 #APM
    ● 最近作ったもの
    ○ セッションキャッシュによる SPOF(単⼀障害点)問題の解消
    ○ freee のマイクロサービス化を⽀える InternalSession
    サービス基盤について

    View full-size slide

  4.  
    4
    ● freee の全プロダクトで共通して使う仕組みの開発
    ● ライブラリの開発だけしている?
    ○ No! No! No!
    ○ 作った仕組みをパイロットプロダクトに導⼊する
    ○ 全プロダクトに対して⼀⻫にアップデートを仕掛ける
    ➢ 各プロダクトを動作確認できる環境の構築が⼤変...!
    サービス基盤の宿命
    2.何でもやれる、何でもやる
    10分でわかるfreee エンジニア向け会社説明資料
    Culture of Developers

    View full-size slide

  5.  
    5
    freee のプロダクトラインナップ
    freee会計
    freeeアプリストア
    freeeカード
    freee福利厚生 freee人事労務 freee受発注 freee開業
    freee会社設立 freee工数管理 freee資金調達 freee申告
    freee請求書 freee販売

    View full-size slide

  6.  
    6
    ● 10 以上のリポジトリのセットアップをする必要がある
    ● 時期によって開発するリポジトリは変わる
    ● 開発環境、秘伝のタレになりがち
    ● 新メンバーの参⼊障壁が⾼い
    ● 数ヶ⽉経てばどうやって環境構築したかなど全て忘れている
    ➢ ⾼速かつ再現可能な開発環境が欲しい...!
    環境構築のツラミ

    View full-size slide

  7.  
    7
    ● 開発環境を丸ごとコンテナ化する技術
    ● かつては VSCode Extension だったが、VSCode ⾮依存な部分が OSS になっている
    ○ devcontainers
    ○ Development Container Specification
    ● 実装は docker コマンドのラッパー
    ○ devcontainer.json に書いた設定を docker コマンドのオプションに
    変換してコンテナを起動してくれる
    解決策:devcontainer

    View full-size slide

  8.  
    8
    ✓ 再現性
    ➢ Dockerfile や devcontainer.json に必要な設定を全てを記載するため、
    開発環境の構成が⾃然とコード管理される
    ✓ ⾼速
    ➢ CI 上で docker build して registry に push すれば、各開発者はイメージを
    pull するだけで環境構築が完了する
    devcontainer が解決する課題

    View full-size slide

  9.  
    9
    ● devcontainer の最も⼀般的な使い⽅
    ○ リポジトリの .devcontainer 以下に各種設定ファイルを配置する
    ● devcontainer.json が1つあると、開発⽤のコンテナが1つ起動する
    ➢ devcontainer には 1 コンテナ 1 リポジトリという原則がある
    原則:1 コンテナ 1 リポジトリ

    View full-size slide

  10.  
    10
    1 コンテナ 1 リポジトリという原則を踏まえて、
    複数リポジトリに跨る開発環境を devcontainer で作る⽅法
    ➢ 2 つの選択肢
    ① リポジトリの数だけコンテナを⽴ち上げる
    ② 複数のリポジトリのソースコードを詰め込んだコンテナを作る
    Multi Repository アーキテクチャと devcontainer

    View full-size slide

  11.  
    11
    メリット
    ✓ devcontainer の原則に沿っている
    ✓ 各リポジトリ毎に devcontainer の設定を管理できる
    ✓ 必要に応じてコンテナを up, down することによって
    開発マシンのリソースを最適化できる
    デメリット
    ● リポジトリごとにコンテナが異なるので開発中コンテキストスイッチが
    頻繁に発⽣する
    ➢ 同時に扱いたいリポジトリが多い今回のケースにはマッチしない
    ① リポジトリの数だけコンテナを⽴ち上げる

    View full-size slide

  12.  
    12
    メリット
    ✓ 1 コンテナで開発フローの全てが完結する
    ✓ 開発⽤のツールを 1 つのコンテナに集約できるのでストレージ効率が良い
    デメリット
    ● devcontainer の基本原則に反するので hacky な使い⽅が必要
    ● イメージやコンテナのサイズが肥⼤化する
    ➢ 開発体験を重要視してこちらを採⽤!
    Connect to multiple containers で紹介されている構成は使い勝⼿がよくなかった
    ② 複数のリポジトリを詰め込んだコンテナを作る

    View full-size slide

  13.  
    13
    ● [MUST] image を pull するだけで環境構築
    ● Dockerfile に以下の処理を詰め込む必要がある
    1. リポジトリの clone
    2. ランタイムのインストール(Ruby, Node.js, Go)
    3. パッケージのインストール
    4. 開発⽤ツールのインストール
    イメージビルドが⼤変
    1 ~ 3 は ×リポジトリの個数

    View full-size slide

  14.  
    14
    ● freee で最も⼤きいリポジトリの .git は 2 GB くらいある
    ● リポジトリ毎に Ruby のバージョンはバラバラ
    ● パッケージインストールに時間がかかる
    ○ 特に native build が必要な gem や npm package
    困難な現実
    まともにビルドしたら
    何時間かかるんだろう...?

    View full-size slide

  15.  
    15
    ● GitHub 社の開発⽤イメージは
    35GB
    ○ https://github.co.jp/features/codespaces
    ● GitHub 社は Microsoft の傘下で Codespaces を提供するなど、
    正に devcontainer 総本⼭
    ● freee よりさらに⼤規模に Ruby on Rails を使い倒している企業でもある
    ○ GitHubは200万⾏規模のRailsアプリケーションであり、毎週RailsとRubyを最新版に
    アップデートし続けている
    実現可能性

    View full-size slide

  16.  
    16
    ● 最終的に作りたいのは超巨⼤な Docker イメージ
    ● 1 つの Dockerfile を愚直に書くとツラいのは明らか
    ● 「困難は分割せよ」
    ● リポジトリ毎にセットアップを完了させた状態の
    中間⽣成物を作って最後にマージする
    解決策:分割統治法

    View full-size slide

  17.  
    17
    解決策:概要図

    View full-size slide

  18.  
    18
    ● 中間⽣成物も Docker イメージとして registry に push する
    ● 各リポジトリのセットアップは⼤凡以下の⼿順
    ○ git clone
    ○ ランタイムのインストール
    ○ パッケージのインストール
    ○ +α
    ➢ リポジトリ毎に上記⼿順を済ませたイメージを⽤意
    ● COPY 命令で中間⽣成物から必要なファイルを最終成果物へ
    ○ ランタイムは asdf (The Multiple Runtime Version Manager) を使って
    インストールし、asdf の data directory をコピーする
    解決策:ポイント

    View full-size slide

  19.  
    19
    Dockerfile サンプル(中間⽣成物)
    FROM freee-internal-base
    WORKDIR /home/vscode/src/repo-a
    RUN git clone https://github.com/org/repo-a .
    RUN asdf install
    RUN bundle install -j4
    RUN npm install
    Ruby や Node.js がインストールされる
    中間⽣成物なのでレイヤ数の圧縮は気にせずに
    RUN 命令は細かく分割する
    ローカルでビルドする際にレイヤキャッシュ
    を活⽤できて効率 UP
    apt パッケージのインストール等を済ませた
    ベースイメージ

    View full-size slide

  20.  
    20
    Dockerfile サンプル(最終成果物)
    FROM freee-devcontainer-src-images/repo-a as repo-a
    FROM freee-devcontainer-src-images/repo-b as repo-b
    FROM freee-devcontainer-base
    COPY --from=repo-a /home/vscode/.asdf /home/vscode/.asdf
    COPY --from=repo-a /home/vscode/src/repo-a /home/vscode/src/repo-a
    COPY --from=repo-b /home/vscode/.asdf /home/vscode/.asdf
    COPY --from=repo-b /home/vscode/src/repo-b /home/vscode/src/repo-b
    中間⽣成物をソースに指定
    これらの COPY を開発する
    リポジトリ全てに⾏う
    開発⽤便利ツールを⾊々インストール済

    View full-size slide

  21.  
    21
    ✓ セットアップ⼿順をリポジトリ毎に切り分けて考えられる
    ✓ 1イメージあたりのビルド時間はそこまで⻑くない
    ○ ⼀番⼤きいリポジトリでも 10 ~ 20 分くらいだった
    ✓ 中間⽣成物の組み合わせ⽅次第で⾃由な開発環境をデザインできる
    ➢ 16 リポジトリを含む, 約 20 GB のイメージを作成、無事開発環境を
    コンテナにすっぽりと収めることができた
    Advantages
    結果...

    View full-size slide

  22.  
    22
    ● 開発⽤の VM 起動 → devcontainer up で開発環境完成
    ● Multi-root workspaces を使ってVSCode 1 window で
    シームレスな開発体験を実現
    ● 2週間に1回くらい開発環境をスクラップ&ビルドできている
    ● いつ開発環境が吹き⾶んでも⼤丈夫な安⼼感
    ● 新しいチームメイトにもサクッと同じ環境を作ってもらうことができた
    ● (副作⽤的に)freee の開発事情についてより⼀層詳しくなれた
    使ってみてよかった点
    作った当初は楽しくて毎⽇
    やってた

    View full-size slide

  23.  
    23
    ● コンテナの中で快適に開発するためには結構リテラシーが求められる
    ○ Docker outside of Docker で他のコンテナを操作する etc
    ● 開発するリポジトリが数個の場合はオーバーエンジニアリング感がある
    ● ちょっとした環境変数の設定等を全てコード化していくのは⾯倒
    もうちょっとポイント

    View full-size slide

  24.  
    24
    ● リポジトリ毎にセットアップして、最後にマージするという
    シンプルなやり⽅で freee の開発環境を
    1 イメージに納めることができた
    ● 10 以上のリポジトリを快適に開発できるようになり、
    作り直しやチームメイトへの共有も容易
    ● コンテナ内で開発するためにはちょっとコツが要る
    まとめ

    View full-size slide

  25. ご清聴ありがとうございました!

    View full-size slide