VS Codeのエージェントモードを拡張するには、を試してください!

カスタム開発コンテナーの機能 (Features)

2022 年 9 月 15 日、執筆者: Brigit Murtaugh (@BrigitMurtaugh)

開発環境をセットアップしているとき、「ああ、あとひとつだけ必要なものがある!」と思ったことは誰にでもあるでしょう。その「もの」とは、プロジェクトで作業するために必要な言語やツールセットのことです (もしかしたら、もう少し多いかもしれません 😊)。

開発コンテナーは、環境設定を簡素化する優れた方法です。プロジェクトに必要なツールを備えた完全なコーディング環境を提供します。これらは、イメージ、Dockerfile、または Docker Compose ファイルと、コンテナーに開発固有のコンテンツと設定を追加するために使用されるメタデータ形式である devcontainer.json を使用して構成されます。

開発コンテナーを作成するとき、「あとひとつだけ必要なものがある!」という反応が繰り返し起こるかもしれません。たとえば、Dockerfile で Node.js イメージを使用していて、Git を追加する必要がある場合などです。あるいは、開発コンテナー内から Docker や Kubernetes を扱うなど、もっと複雑なものを追加する必要があるかもしれません。開発コンテナーは、あなたのコードにアクセスする誰もが、あなたが追加したすべてのツールで同じ一貫した体験を得られるため素晴らしいものですが、それらを追加する最善の方法は何でしょうか?

ツールの名前とバージョンを指定するだけで、その追加ツールを開発コンテナーに簡単にインストールする方法があったらどうでしょうか? あるいは、ツールのユーザーや作成者として、他の人が簡単にインストールできる方法を作成できたらどうでしょうか? 手動のスクリプトを共有することは再利用に役立ちますが、それを参照するときに、Go、Rust、C++ のデバッグで ptrace サポートを有効にしたり、コンテナーの起動時に特定の開始点を追加したり、適切な VS Code 拡張機能が含まれていることを確認したりといった、コンテナーやツールの設定を参照し忘れるかもしれません。

機能

開発コンテナーの Features (機能) が、開発コンテナーに必要なツールをスムーズに取得するのに役立つことをお知らせします!

Features は、インストールコード、コンテナー構成、および/または設定と拡張機能の自己完結型ユニットであり、開発コンテナーに新しい開発機能を追加できるように設計されています。幅広いベースコンテナーイメージで動作するように構築できます。オープンな開発コンテナー仕様に関する取り組みの一環として、事前に作成された Features を取得できる場所や、独自の Features を作成して配布する方法についていくつかの改善を行いました。

開発コンテナーをサポートする任意のツールやサービス (VS Code Dev Containers 拡張機能や GitHub Codespaces など) から Features を使い始める方法と、何が新しくなったかを見てみましょう!

開発コンテナーに Features を追加する

開発コンテナーの Features は、開発コンテナーのメタデータといくつかのインストール手順を関連付ける簡単な方法を提供します。簡単な参照を通じて、開発コンテナーに追加できます。

これらの Features は、サポートされている任意のコンテナーレジストリに OCI Artifacts として保存できるようになりました。つまり、コンテナーイメージを参照するのと同じ種類の識別子を使用して参照できます。私たちは、vscode-dev-containers リポジトリにあった初期の Features のいくつかを、この新しいアプローチを使用して公開されている新しい devcontainers/features リポジトリに移動しました。

devcontainers/features リポジトリからさまざまな Features を参照するには、devcontainer.jsonfeatures プロパティを追加するだけです。各 Feature には、その Feature の参照方法と利用可能なオプションを示す README.md があります。

以下の例では、godocker-in-docker の Features をインストールします。

"name": "my-project-devcontainer",
"image": "mcr.microsoft.com/devcontainers/base:ubuntu",
"features": {
    "ghcr.io/devcontainers/features/go:1": {
        "version": "1.18"
    },
    "ghcr.io/devcontainers/features/docker-in-docker:1": {
        "version": "latest",
        "moby": true
    }
}

また、仕様サイトで、公式および一般から提供された Features を探すこともできます。どの Feature も devcontainer.json を編集することで追加でき、公開されているものは既存の開発コンテナー構成エクスペリエンス (VS Code Dev Containers 拡張機能で利用可能なものなど) を通じて追加できます。

Specification site list of available Features

お気に入りの CI システムから、開発コンテナー CLI、GitHub Action、または Azure DevOps タスクを使用して、Features を備えた開発コンテナーを使用することもできます。devcontainers/ci リポジトリで、GitHub Action と Azure DevOps タスクが利用可能です。開発コンテナー CLI、GitHub Action、または Azure DevOps タスクは、Feature のコンテンツを含むイメージを事前ビルドして、起動時間を短縮するためにも使用できます。

公開されている Features を使用するだけでなく、独自のプライベートまたはパブリックな Features を作成して共有したい場合は、読み進めてください!

作成 (Authoring)

独自の Features を作成し始めるのに最適な場所は、新しい Features テンプレートリポジトリです。特定の Feature の内容の良いテンプレートが含まれているだけでなく、このテンプレートには、GitHub Container Registry (GHCR) を使用して、それらを迅速に公開するための GitHub Actions ワークフローも含まれており、アカウントですぐに使い始めることができます。公開については後ほど詳しく説明します。

Feature のソースコードには、インストールスクリプト (install.sh) と構成ファイル (devcontainer-feature.json) の 2 つのコンポーネントがあります。

+-- feature
|    +-- devcontainer-feature.json
|    +-- install.sh
|    +-- (other files)

install.sh: インストールのエントリポイントスクリプトです。概念的にはイメージの Dockerfile のレイヤーとして追加され、ビルド時に実行されます。このエントリポイントスクリプトは、言語 (例: Ruby) やツール (GitHub CLI) などをインストールできます。

devcontainer-feature.json: これには、Feature に関するメタデータ、インストールの際に Feature のインストールスクリプトに渡すことができるオプションのセット、および最終的な開発コンテナーにマージされる devcontainer.json の「断片」が含まれています。たとえば、いずれかの Feature がその構成で "privileged": true を示している場合、開発コンテナー全体が --privileged フラグ付きで起動されます。

Features はさまざまな言語で作成できますが、最も簡単なのはシェルスクリプトです。Feature が別の言語で作成されている場合は、ユーザーが情報に基づいた選択をできるように、その情報をメタデータに含める必要があります。

注: install.sh はどの言語の Feature も実行しますが、開発コンテナーに存在しないインタープリター言語で Feature を記述した場合、コードは実行に失敗します。install.sh の一部として必要な言語を取得するようにしてください。

公開する Features は、その Feature に加えて依存関係もチェックしてインストールするようにしてください。

さらに、公開される Features は arm64 または x86_64 の両方のマシンから使用される可能性が非常に高いため、可能な場合はこれに適応するようにしてください。

仕様devcontainer-feature.json のプロパティを確認したり、devcontainers/features リポジトリで公開されている例を確認したりできます。

Feature の作成方法がわかったところで、どうすれば他の人に配布できるでしょうか?

配布 (Distribution)

Features は tarball として配布されます。tarball には、devcontainer-feature.jsoninstall.sh、およびディレクトリ内の他のすべてのファイルを含む、Feature サブディレクトリの全内容が含まれます。

Open Container Initiative (OCI) は、コンテナーおよびコンテナーリソースの業界標準を定義しています。私たちは Features を OCI Artifacts として扱い、Features を配布するために OCI Registry の概念を使用します。

前述の Features テンプレートリポジトリには、公開プロセスを自動化するための GitHub Actions ワークフローが含まれています。これにより、Feature が tarball にパッケージ化され、アセットが OCI アーティファクトとして GHCR に公開されます。テンプレートリポジトリから release.yaml ワークフローをトリガーするには、GitHub のリポジトリの Actions タブの左側でそれを選択します。GitHub Action は、<owner>/<repo> 名前空間の下に Feature を GHCR に公開します。Feature は、その devcontainer-feature.json の version プロパティが更新された場合にのみ再公開されます。

注: GHCR での手動ステップの 1 つは、OCI パッケージを「公開 (public)」としてマークすることです。これは Feature ごとに一度だけ行う必要があります。プライベートな Feature はこのステップを必要とせず、レジストリの認証情報を使用して Docker CLI にログインしていればアクセスできます。

コミュニティと Features を共有する

VS Code Dev Containers または GitHub Codespaces の開発コンテナー作成 UI にあなたのコントリビューションを表示させたい場合は、以下の手順を実行できます。

マージされると、変更は containers.dev/collections に表示されます。

Feature のインストール順序

自分の Feature が別の Feature の後にのみインストールされるようにしたい場合はどうすればよいでしょうか? Feature の作成者として、自分の Feature が他の Features の前または後にインストールされるべきだと感じることがあるかもしれません。devcontainer-feature.json で、installsAfter プロパティを使用して、その前に実行されるべき Features をリストアップできます。

エンドユーザーとして、devcontainer.jsonoverrideFeatureInstallOrder プロパティを使用して実行順序をさらに制御できます。この配列内の Feature ID は、他のすべての Features の前に、指定された順序でインストールされます。例として、

"features": {
      "ghcr.io/devcontainers/features/java:1",
      "ghcr.io/devcontainers/features/node:1",
  },
  "overrideFeatureInstallOrder": [
    "ghcr.io/devcontainers/features/node"
  ]

デフォルトでは、Features は、実装ツールによって最適と判断された順序でベースイメージの上にインストールされます。

Feature の devcontainer-feature.json またはユーザーの devcontainer.json で以下のいずれかのプロパティが提供されている場合、これらのプロパティによって示される順序が (優先度の高い順に) 尊重されます。

  1. ユーザーの devcontainer.jsonoverrideFeatureInstallOrder プロパティ。ユーザーが Features の実行順序を制御できます。
  2. Feature の devcontainer-feature.json の一部として定義された installsAfter プロパティ。

Feature の実行とインストール順序については、仕様で詳しく読むことができます。

他に何が新しいですか?

新しい Features リポジトリに加えて、最近、以前 vscode-dev-containers リポジトリにあった特定のイメージセットをホストする新しい devcontainers/images リポジトリをオープンソース化しました。

私たちは、開発コンテナーのテンプレート (vscode-dev-containers で「definitions」と呼んでいるもの) のコミュニティ配布計画を策定しており、これは Features と同様のものになる見込みです。新しい Features と images リポジトリを発表したときのように、vscode-dev-containers リポジトリで最新情報を投稿する予定です。

もっと詳しく知るには?

この記事は、Features でできることのほんの一部に触れたにすぎません。ぜひお試しください!

上記の内容全体でリンクされているように、Features の内容や配布方法について詳しく知るための最適な場所は、開発コンテナー仕様の FeaturesFeatures distribution のページです。

Features を使用、作成、公開する際のフィードバックをお待ちしています。Features および Features distribution の issue 提案で、どのように機能しているかをお聞かせください。

仕様全体に関わりたい、または別のツールを連携させて活用したい場合は、開発コンテナーの specCLI リポジトリをチェックしてください。

楽しい開発コンテナー作成と、楽しいコーディングを!

Brigit Murtaugh、@BrigitMurtaugh