yaakai.to

⚙️

個人開発を Codespaces と DevContainer へ移行

Codespaces が利用できるようになってから、ちょっとした開発は Codespaces を行っていたのですが、最近は個人の開発はすべて Codespaces で十分だと思えてきたので完全に移行しようと思いました。 ただ、基本的には無料枠でやっているので1、ある程度腰を据えて開発していると枠が足りなくなるのと、Chrome 拡張の開発は毎回成果物のダウンロードが必要だったりで不便なところは少しあるので、それを埋めるために一部で Dev Container を使って、手元のマシン内で開発可能な環境を整えることにしました。

これは、その準備をしたときの作業ログと未来の自分に向けたメモです。ある程度 Codespaces を触ったことがあるという前提で書かれています。

開発用コンテナと Dockfile について

Codespaces と Dev Container で使用するコンテナに関する設定を区別する必要なく、同じものが使えます。 Docker Desktop に相当するものがインストールされていれば、VSCode に Dev Containers のプラグインを入れればそのまま利用可能です。

ローカルで開発するときはコードを適当な場所に clone して「Open in container」から開きます。コマンドパレットからも開き直せます、その場合は Reopen ~ になります。

Clone Repository in Container

コードの clone をコンテナの中で行うという方法もあるようです。これを利用すると Codespace とほとんど同じ感覚で使えるようです。

ただ、何回試してみたのですが、shallow clone になってしまってだるいのと、成果物がコンテナ内に入ってしまうので取り出すのがめんどくさい、という理由があって使っていません。

OrbStack

個人の MBA では Docker Desktop の代わりに OrbStack を試しています。

いまのところ特に問題なく Docker Desktop の代わりとして使えています。

Dotfiles について

ここ数年は fish を使っていたのですが、devcontainers のものにはデフォルトでは入っていないので、これを機に zsh に戻してみることにしました。 これまで Codespaces を使うときは不便を感じつつも特にカスタマイズをしていなかったので、今回ちゃんと設定を整えてみることにしました。

開発に使う devcontainer をある程度テンプレ化しておきたかったので2 dotfiles ではなくて env という名前にしてみました。

Codepsaces の場合は、GitHub の設定から dotfiles のリポジトリを指定することで、Codespaces が起動するときに dotfiles の内容がコンテナにコピーされ、setup.sh が実行されます。

Dev Container の場合は、VSCode の設定から GitHub にある dotfiles のリポジトリを指定ことができます。これをすると Codespaces と同等の挙動になります。

{
  "dotfiles.repository": "yaakaito/env",
  "dotfiles.targetPath": "~/.env",
}

zsh のカスタマイズ

とはいえ欲しい物が fish っぽく動いてほしいくらいだったので、次の記事を参考に zsh-autosuggestionszsh-syntaxhighlight を入れて、fish ライクに、peco で ctrl-r に履歴検索、ctrl-s でディレクトリ移動をバインドしています。

他には pnpm などの補完がほしいところですが、これは使うコンテナによって必要なものが違うので、Dockerfile の方で有効にしています。例えば pnpm の場合は以下のような感じです。

USER vscode
RUN corepack prepare [email protected] --activate
RUN pnpm install-completion zsh

Copilot や VSCode の拡張機能について

これまではあまり意識せずに Copilot を Codespaces にインストールして使っていたのですが、これを設定している途中で、コンテナ内で開発する際に Copilot が有効にならないことがあることに気づきました。これは Codespaces に限らず、Dev Container でも同じでした。他にもいくつかの拡張機能が動作しないことがあったのですが、これは container.json に設定を追加することで解決しました。

customizations.vscode.extensions フィールドを設定することで、コンテナで有効にする VSCode の拡張機能を指定することができるようです。これを使って Copilot や必要な拡張を有効にすることにしました。

{
    "build": { "dockerfile": "Dockerfile" },
    "customizations": {
        "vscode": {
            "extensions": [
                "github.copilot",
                "astro-build.astro-vscode" // 例えば Astro を使う場合
            ]
        }
    }
}

今回やらなかったがやりたいこと

Codespaces や Dev Container を使った開発では、シェルの history が残らないため、永続化したい場合は別途手段を用意する必要があるようです。

history が永続化できるとそもそも不要かもしれませんが、cheat を使ったスニペットを env リポジトリに含めて置けると便利そうです。

2023-05-14 追記

しばらく触っていなかったリポジトリを同じ要領で触ってみたら、DevContainer 側で VSCode の Extention のインストールが全く進まずに困っていたのですが、Dockerfile が原因でした。 かなり前に公式を参考に devcontainer.json と Dockerfile を作った際に、その Dockerfile はこんな感じに定義されていて、

ARG VARIANT=bullseye
FROM --platform=linux/amd64 mcr.microsoft.com/vscode/devcontainers/base:0-${VARIANT}

linux/amd64 を指定していると M2 Mac 上のコンテナに Extention がインストールできなくなるようでした。platform は指定しなければ自動で選択してくれるので、

ARG VARIANT=bullseye
FROM mcr.microsoft.com/vscode/devcontainers/base:0-${VARIANT}

に変更して無事動くようになりました。当時参考にしたドキュメントが見つからなかったんですが、現在のものは platform を指定していないので問題なさそうです。

そもそもトレンドとしては Dockerfile は使わず、devcontainer.json だけで完結するのがよいようにも思います。

Footnotes

  1. 追加することに抵抗があるわけではないので、理由がなければ Codespaces を継続してます。

  2. テンプレートリポジトリはリポジトリが増えるし同じようなことをそれぞれに更新かけたりがだるいので。