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

カスタムDev Container 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など、Dev ContainerをサポートするあらゆるツールやサービスからFeaturesを開始する方法を見てみましょう!

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

Dev Container 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

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

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

作成

独自の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の一部として必要な言語を取得するようにしてください。

公開するFeatureは、Featureに加えて依存関係をチェックし、インストールするように確認する必要があります。

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

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

Featureの作成方法を見てきましたが、どうすれば他の人に配布できるでしょうか?

配布

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

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

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

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

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

作成したものがVS Code Dev ContainersGitHub CodespacesのUIで開発コンテナ作成時に表示されるようにしたい場合は、以下の手順を実行します。

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

Featureのインストール順序

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

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

"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.jsonにあるoverrideFeatureInstallOrderプロパティ。ユーザーがFeatureの実行順序を制御できます。
  2. Featureのdevcontainer-feature.jsonの一部として定義されたinstallsAfterプロパティ。

Featureの実行とインストール順序に関する詳細については、仕様を参照してください。

他に新しいことは?

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

開発コンテナテンプレート(vscode-dev-containersでは「定義」と呼んでいます)のコミュニティ配布計画を策定中です。これはFeaturesと同様になると予想しています。新しいFeaturesとイメージリポジトリを発表した際と同様に、vscode-dev-containersリポジトリで最新情報を必ず投稿します。

詳細はこちら

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

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

Featuresの使用、作成、公開に関する皆様からのフィードバックを楽しみにしています。FeaturesFeatures distributionの課題提案で、皆様にとってどのように機能しているかぜひお聞かせください。

仕様全体に関与したり、別のツールを連携して活用したりすることに興味がある場合は、開発コンテナのspecおよびCLIリポジトリをチェックしてください。

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

Brigit Murtaugh、@BrigitMurtaugh