GitHub Codespaces の Universal イメージを Dev Container なしで使えるようにする
TL;DR
GitHub Codespaces と同じ Universal イメージをローカル (Docker Desktop など) の CLI で試すコマンドです。
docker run --rm -it --privileged -u codespace -w /home/codespace mcr.microsoft.com/devcontainers/universal:2 bash
Context
Github Codespaces
Github Codespaces のベースイメージはとても便利です。 様々なビルドツールやプログラミング言語がビルドインされており、さらに Docker も利用できます。
GitHub では .devcontainer
定義がないリポジトリで Codespaces を開くとこのイメージによる環境が立ち上がります。 「何にでも使える」けど「使い捨ての」環境が欲しい時は私はよく Blank テンプレートから Codespaces を立ち上げてます。
でも Github Codespaces は停止し忘れると無料枠を消費してしまうので、Docker が入っているローカルマシンを使っているならローカルマシンでこの使い捨て環境を利用できるといいです。
Github Codespaces 環境は Dev Containers によって構成されているのですが、環境をカスタマイズしてみようとすると、このベースイメージは Dev Containers の Universal イメージということが分かります。
それであれば VS Code の Dev Container を使ってローカルから利用してみましょう。
Dev Containers
実際に VS Code の Dev Container を使って開発コンテナ定義を追加しようとするとこの Universal イメージの選択肢が現れます。
通常の Dev Container の利用方法に従えば、これだけで GitHub Codespaces と同じイメージがローカルでも使えるようになりました!
しかし VS Code Dev Container もよいですが、わざわざ GUI からではなく単純に CLI からでも使えるようにしたいです。
イメージの URL は分かっているので docker run
コマンドで使えるようにしましょう。
mcr.microsoft.com/devcontainers/universal:2
docker CLI
失敗例
docker run --rm -it mcr.microsoft.com/devcontainers/universal:2 bash
mount: /tmp: permission denied.
いつも通りの docker run
コマンドを打ってみましたが、なぜか失敗してしまいます。 /tmp
のパーミッション?? 原因を把握する為に Universal イメージの Dockerfile
を追ってみました。
ENTRYPOINT
で特殊なスクリプトを使って Docker in Docker (及び sshd) を有効化しているようです。 その為 --privileged
フラグを使ってコンテナ内部で Docker の権限を渡します。
docker run --rm -it --privileged mcr.microsoft.com/devcontainers/universal:2 bash
Not setting dockerd DNS manually.
root ➜ / $
成功しました! なにやらメッセージが出てますが、正常系の echo のようです。
あとは root
ユーザーは使いたくないので codespace
ユーザーに書き換えれば GitHub Codespaces 環境と一致します。 (TL;DR のコマンド)
docker run --rm -it --privileged -u codespace -w /home/codespace mcr.microsoft.com/devcontainers/universal:2 bash
さらに (Windows の場合は) Windows Terminal でプロフィールを作成してこちらのコマンドを登録すればより便利になります。
Not setting dockerd DNS manually. のメッセージが気になる場合は、コマンドをハックしてみるのもいいかもしれません。 SSH が不要なら ssh-init.sh
のシェルも削除してもいいかもしれませんね。
docker run --rm -it --privileged -u codespace -w /home/codespace --entrypoint /bin/sh mcr.microsoft.com/devcontainers/universal:2 -c "/usr/local/share/ssh-init.sh /usr/local/share/docker-init.sh > /dev/null && bash"