本セッションの登壇者
セッション動画
大中 浩行(Twitter: @setoazusa)です。よろしくおねがいします。
今、VS Codeで一番ホットな話題といえば、先ほど白石さんからもお話がありましたChatGPTもありますが、ここでは2023年1月に行われたVS Code Conference JP 2022 - 2023のプログラムからトピックを探してみましょう。
カンファレンスでは、Dev Containers(開発コンテナ)について3つ、GitHub Codespacesについて1つ、Remote Development (SSH)について1つのセッションで発表されていました。したがって、これらのリモート開発に関連するトピックが今VS Codeで実務上ホットなトピックであると考えられます。
Dev Containers(開発コンテナ)とは
Dev Containers(開発コンテナ)はDocker上でVS Codeの環境をパッケージングするものです。devcontainer.jsonとDockerfileを用意すると、Gitからソースコードをcloneするだけで開発環境が構築できます。GitHub CodespacesもこのDev Containersを使用しています。
Dev Containersがどのように利用できるか、デモをご覧いただきます。こちらのGitHubリポジトリには.devcontainer
の設定を用意してあります。
ブラウザからGitHub Codespacesを選択するとVS Codeが起動し、.devcontainer
の設定に従ってRuby on Railsの開発環境が起動します。
VS Codeのターミナルからbundle exec rails s
コマンドを実行すると、GitHub Codespaces上で動作するRuby on Railsサーバーがlocalhost:3000
(.devcontainer
で設定したポート)に転送され、手元の環境でアプリケーションの実行とデバッグができるようになります。
このデモのように、現在VS CodeではDev Containers、Codespaces、WSL、SSHなどを使ってコンテナやリモート環境を組み合わせて開発環境をセットアップするのがトレンドです。今回のセッションでは、Dev ContainersやCodespacesとDockerの組み合わせに関するノウハウをご紹介します。
Git for WindowsとDev Containers
WindowsでVS CodeとDev Containersを使用したときに、
現在のフォルダー内のGitリポジトリは、現在のユーザー以外のユーザーによって所有されているため、安全でない可能性があります。
というメッセージを見たことはありませんか。
このメッセージが表示されるのは2つの理由によるものです。
1つ目は、Git 2.35.3で導入されたパーミッション関連の仕様変更です。Gitでクローンしたソースコードの中に自分以外のユーザーが編集可能なファイルがあると、悪意のあるユーザーがファイルを編集できてしまい、悪意あるコードが実行される可能性があるという脆弱性(CVE-2022-24765)がありました。この脆弱性への対応として、Gitコマンドを実行するユーザーが所有するファイル・ディレクトリのみ操作できるように仕様が変更されました。
2つ目は、Windowsのホスト上のディレクトリをマウントするときにDocker上ではrootが所有者としてマウントされるというDocker Desktopの仕様です。
この2つの理由により、Windows上でDev Containers環境を作ると、そのままではGitの操作ができないということになります。
この問題への対応策は2通りあります。
- VS CodeのGUIの指示に従って、Manage Unsafe Repositories(安全でないリポジトリの管理)ボタンをクリックする
devcontainer.json
に次の設定を追加する:"postStartCommand": "git config --global --add safe.directory ${containerWorkspaceFolder}"
Apple siliconとDev Containers
M1 / M2などのApple siliconを搭載したMacが普及しています。Apple silicon上のDocker DesktopではVirtualization framework(Docker Desktop 4.14.0以降)やQEMUによりx86_64のイメージをエミュレーションして実行できるため、x86_64のイメージやDockerfileしかなくても大丈夫だと思いがちですが、エミュレーション部分に不具合があると実行するコードから見てCPUが想定通りに動かないということになってしまい、Segmentation faultで落ちてしまうことがあります。
個人的にApple siliconで動かす場合はarmのCPUに合わせてコードをビルドするようにしています。そのときのノウハウは次のとおりです。
- フレームワークやライブラリ等はarm(aarch64)をサポートしているバージョンにする
- ソースからビルドする場合は、マルチステージビルドでそれぞれのCPU向けにビルドしたバイナリをコピーする
実際にやってみると、たとえばとても古いバージョンのNode.jsを使っている場合など、どうしてもCPUアーキテクチャによってDockerfileの中のビルド処理を分けなければならない場合があります。この場合には、Dockerfileの中でビルドしているCPUアーキテクチャに応じて処理を分岐するようにShellスクリプトのcase文を書くことで、CPUアーキテクチャごとにビルド処理を分けられます。
ただし、この方法ではDockerfileの中でビルド処理が分岐していることになりますので、CPUアーキテクチャによってビルド記述が異なり、Dockerイメージの中身が異なります。これはHaskellのDockerでのDockerfileの例ですが、armアーキテクチャのときは処理をスキップし、x86_64のときはインストールするという分岐になっています。
このようにDockerfile内で分岐することもあるため、DockerHub上で同じタグがついているDockerイメージでも、CPUアーキテクチャによって内部の構成が異なることがある、という点に注意が必要です。
Remote SSHとDev Containers
ここまではWindowsやApple siliconなどプラットフォームごとのDocker DesktopとGitの組み合わせに関するノウハウをご紹介しましたが、プラットフォームごとの事情に合わせてDockerfileやdevcontainer.jsonを調整するのは面倒です。また、Docker Desktopはその仕組み上、どうしてもCPU/メモリリソースを多く消費します。
DockerはそもそもLinux前提のソリューションなので、ローカル環境ででDocker Desktopを動作させるよりも、VS CodeからSSHでLinuxホストに接続し、そこで動作するDockerでリモート開発ができると便利です。
VS CodeのRemote - SSHプラグインを使うとSSHでLinuxをはじめとしたリモート環境に接続できるので、Windows/MacのVS CodeからSSHでLinuxホストに接続し、そこで動作するDockerでリモート開発することができます。
SSHとDockerを組み合わせたリモート開発ができると、Elasticsearchのプラグインを開発するなどのリソースを大量に消費するような処理の際にも、クラウド上の資源にVS Codeから直接接続して活用できるようになります。
今回お話したVS Codeでのリモート開発をはじめ、Windowsデスクトップ上でのリモート開発のノウハウをまとめたWindowsデスクトップでWeb開発 改訂新版も販売していますので、ご興味があればぜひよろしくおねがいします。
以上です。ありがとうございました。