😊

モノレポで複数のdevcontainerを使う試み

2024/11/14に公開

これは何

CIの都合や開発環境によって幾つかのプロジェクト(例えばバックエンドのサーバとWebのフロントエンドなど)が同一のGithubリポジトリに含まれることがあります。

こういった環境でVSCode(正確には他エディタでも使えますが)を用いたDevcontainerベースの開発環境を作って、使い勝手を検証してみました。

僕自身はWeb系にそれほど明るくない(Unityがメインのクライアントアプリエンジニアです)ので、もしもっと良い方法があれば知りたいですね。

Devcontainerってなに?

DockerやDocker Composeによって実行環境を閉じ込める(ローカルに依存しない)という仕組みがあります。

Devcontainerはそれに加えて開発環境も閉じ込めることができるため、環境差異に苦しまないという利点があります。

具体的にはローカルのPCがMacとWindowsで、それぞれ手元にPythonなどがインストールされていなくても、Dockerの仮想マシン上にPythonプラグインなどが入ったVSCode環境をDevcontainerが作ってくれる。
そしてそのVSCodeを手元のPCから触って開発する、という感じになります。

https://code.visualstudio.com/docs/devcontainers/containers

複数Devcontainer

原理的に1リポジトリ1devcontainerが想定された使い方ですが、バックエンドのサーバとWebのフロントエンドが同一リポジトリに入っている場合はどうするのでしょうか?
気になったので調べてみましたが、ベストプラクティスみたいなのは決まってないようです。

この辺のアプローチが良さそうだと思いました。

However, this can result in overlapping configurations
across multiple projects, making maintenance tedious.
 A better approach is to share a common docker-compose.yml:

https://dev.to/graezykev/dev-containers-part-5-multiple-projects-shared-container-configuration-2hoi

multiple dev containerですぐに立ち上げられるモノレポなローカル開発環境を作るぞ!
https://qiita.com/re_2osushi8888/items/e9df614f7b5182ae284d

それらを参考にFastAPI(Backend)+MySQL+Streamlit(WebFront)の簡単なTodoアプリを作ってみました。
https://github.com/neon-izm/PythonFastApiLearn

どうやって試すの?

この状態で
https://github.com/neon-izm/PythonFastApiLearn
これをcheckoutして、VSCodeでフォルダを開いて下さい。

VSCode左下の青いボタンを押して、Reopen in Containerを選択します

するとBackend側とFrontend側、どちらの環境のコードを書くか聞いてくるので、FastAPIのコードを書くときはBackend,Streamlitのコードを書くときはFrontendを選ぶと、勝手にDockerCompose経由で良い感じのコンテナが立ち上がって、適切な開発環境が起動します。

コンテナから抜けたり、コンテナの再ビルドはコンテナ内で再度左下の青いボタンを押すと、こういうメニューが出てくるので適宜選択して下さい。

動作確認の仕方

backend

Backend側を選んだら、ローカルPCのブラウザでswaggerが開けます。

( http://127.0.0.1:8000/docs )

こんな感じ!

backend/routers/users.pyの

@router.post("/", response_model=schemas.Token)

この辺の行を例えば以下のようにエンドポイント名を書き換えてCtrl+Sで保存して下さい。

@router.post("/test", response_model=schemas.Token)

さっきのブラウザのURL( http://127.0.0.1:8000/docs )を再読込したら反映されています。

(手元の環境を汚さない)開発体験として、わざわざ毎回docker composeを叩くよりイテレーションが速くて嬉しい感じですね!

frontend

Frontend側を選んだら、ローカルPCのブラウザでstreamlitのページが開けます。

( http://127.0.0.1:8501/ )

同じく
frontend/app.pyの

       st.title("ログイン/ ユーザー登録")

この辺の行を例えば以下のように表示を書き換えてCtrl+Sで保存して下さい。

       st.title("ログインTest / ユーザー登録")

さっきのブラウザのURL( http://127.0.0.1:8501/ )を再読込したら反映されています。

この開発イテレーションが維持できて、手元環境が汚れないなら、結構アリかな~と思いました。

この開発環境を作って思ったこと

良かったこと

  • 他の開発者と同一環境でコードを書いて実行することが出来る
  • DockerComposeとの相性が良い
    • デプロイがしやすい
  • VSCodeの豊富な拡張が使える
  • 開発イテレーションがぼちぼち早い

気になったこと

  • JetBrains系のIDEなどはDevcontainerの統合がまだVSCodeほどスムーズではない
  • 自前のお気に入りVSCode拡張がメンバー内でバラバラのときに困る(どうしてます?recommendのextentionにvim https://marketplace.visualstudio.com/items?itemName=vscodevim.vim 入れる、くらいは許されますか?)
  • Pythonの場合時にvenvやpoetry,uvなどで開発環境を固定するテクが既にあるのに、それとは別の作法を覚えるのがダルいかも
  • スムーズに開発してる間は快適ですが、コンテナが起動しない、あるいは起動時にエラーが出た、となった瞬間に
    • Dockerのコンテナごとのステータスやログチェック
    • コンテナにSSHで入ってログ読んでbashで確認
    • Devcontainerのボリュームマウントのチェック
    • Docker自体の仕組みやdocker-compose.ymlを読み解く力

みたいなのが一度に要求されてメゲる人がいるかも

今後の展望

僕はJetbrainsに魂を売り渡してる(メイン環境がRider)ので、今後こういう開発がメインになるのか戦々恐々しています。

環境構築はしやすくなっていますが、いざという時のトラブルシュートの難易度が上がってそうなので良くなると良いなって思いました。

個人的にはこういう方向性は面白いな!!って思いました。↓

モノレポの開発環境でDocker ComposeをやめてTaskfileを導入した話
https://zenn.dev/uzu_tech/articles/e0f0af5945033b

Discussion