現已釋出!閱讀關於 11 月新增功能和修復的內容。

自定義開發容器功能 (Dev Container Features)

2022 年 9 月 15 日,作者:Brigit Murtaugh,@BrigitMurtaugh

我們都經歷過設定開發環境時的那一刻——“哦,我只需要再加一個東西!”——而這個“東西”可能是為了處理專案所需的另一種語言或工具集(或者可能不止一個😊)。

開發容器是簡化環境設定的好方法——它們提供了一個完整的編碼環境,其中包含專案所需的工具。它們使用映象、Dockerfile 或 Docker Compose 檔案以及 devcontainer.json 進行配置。devcontainer.json 是一種元資料格式,用於透過特定於開發的內容和設定來豐富容器。

在建立開發容器時,您可能會反覆出現同樣的“我只需要再加一個東西!”反應——也許您在 Dockerfile 中使用了 Node.js 映象,而只需要新增 Git。或者您可能需要新增更復雜的東西,例如在開發容器內使用 Docker 或 Kubernetes。開發容器非常棒,因為任何訪問您的程式碼的人都將擁有與您新增的所有這些工具相同且一致的體驗——但是新增它們的最佳方式是什麼呢?

如果有一種簡單的方法,只需提及工具的名稱和版本,即可在開發容器中安裝該額外的工具,那會怎樣?或者,如果您作為工具使用者或作者,可以為其他人建立一種簡單的方法來安裝它,那會怎樣?共享手動指令碼有助於重用,但在引用指令碼時,您可能會忘記引用容器或工具設定,例如為 Go、Rust 或 C++ 除錯啟用 ptrace 支援,在容器啟動時新增特定的入口點,或者確保包含正確的 VS Code 擴充套件。

功能

我們很高興地告訴大家,開發容器的 功能 (Features) 可以幫助您順利地在開發容器中獲得所需的工具!

功能是自包含的安裝程式碼、容器配置和/或設定和擴充套件單元,旨在為您的開發容器啟用新的開發能力。它們可以構建為與各種基礎容器映象配合使用。作為我們開放開發容器規範工作的一部分,我們對獲取預建立功能的位置以及如何編寫和分發您自己的功能進行了一些改進。

讓我們看看有什麼新功能,以及如何從任何支援開發容器的工具或服務(例如 VS Code Dev Containers 擴充套件或 GitHub Codespaces)開始使用功能!

將功能新增到您的開發容器

開發容器功能提供了一種將開發容器元資料與某些安裝步驟關聯起來的快速方法。您可以透過簡單的引用將它們新增到您的開發容器中。

這些功能現在可以作為 OCI 工件儲存在任何支援的容器登錄檔中,這意味著您可以使用與引用容器映象相同的識別符號型別來引用它們。我們已將 vscode-dev-containers 倉庫中的一些早期功能移到了新的 devcontainers/features 倉庫中,並使用這種新方法釋出。

從 devcontainers/features 倉庫引用不同的功能非常簡單,只需在 devcontainer.json 中新增一個 features 屬性即可。每個功能都有一個 README.md,其中顯示瞭如何引用該功能以及可用的選項。

下面的示例安裝了 godocker-in-docker 功能。

"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
    }
}

您還可以在規範網站上探索官方和公開貢獻的功能。任何功能都可以透過編輯 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 任務也可用於預構建包含功能內容的映象,以加快啟動時間。

如果您不僅想使用公開可用的功能,還想建立自己的私有或公共功能來共享,請繼續閱讀!

編寫功能 (Authoring Features)

開始建立自己的功能的一個好地方是新的 Features template 倉庫。除了包含給定功能內容的良好模板之外,該模板還包括一個 GitHub Actions 工作流,可以使用 GitHub Container Registry (GHCR) 快速釋出它們,以便您儘快開始使用。我們稍後會詳細討論釋出。

功能的原始碼有兩個組成部分:安裝指令碼 (install.sh) 和配置檔案 (devcontainer-feature.json)。

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

install.sh:安裝入口點指令碼——在概念上,它被新增為映象 Dockerfile 的一層,並在構建時執行。這個入口點指令碼可以安裝工具,例如語言(例如 Ruby)和工具(GitHub CLI)。

devcontainer-feature.json:這包含有關功能的元資料、一組可以在安裝過程中傳遞給功能安裝指令碼的選項,以及將合併到最終開發容器中的 devcontainer.json 的“片段”。例如,如果任何功能在其配置中指示 "privileged": true,則整個開發容器將以 --privileged 標誌啟動。

功能可以用各種語言編寫,最直接的是 shell 指令碼。如果功能是用不同的語言編寫的,則應在元資料中包含有關它的資訊,以便使用者可以就此做出明智的選擇。

注意:雖然 install.sh 會執行任何語言的功能,但如果功能是用開發容器中不存在的解釋型語言編寫的,則程式碼將無法執行。請確保在 install.sh 中獲取您需要的語言。

您應該確保公開發布的功能除了功能本身之外,還檢查並安裝依賴項。

此外,公共功能很可能在 arm64 或 x86_64 機器上使用——因此請儘可能適應這一點。

您可以在規範中檢視 devcontainer-feature.json 屬性,以及 devcontainers/features 倉庫中的公共示例。

既然我們已經看到了如何建立功能,那麼如何將其分發給其他人呢?

分佈

功能以 tarball 形式分發。tarball 包含功能子目錄的全部內容,包括 devcontainer-feature.jsoninstall.sh 以及目錄中的任何其他檔案。

開放容器倡議 (OCI) 定義了容器和容器資源的行業標準。我們將功能視為 OCI 工件,並使用 OCI 登錄檔的概念來分發功能。

上面提到的 Features template 倉庫包含一個 GitHub Actions 工作流來自動化釋出過程。它將功能打包成 tarball,並將資產作為 OCI 工件釋出到 GHCR。透過在 GitHub 上的 Actions 選項卡左側選擇 release.yaml 工作流,從模板倉庫觸發它。GitHub Action 會將功能釋出到 GHCR,位於 <owner>/<repo> 名稱空間下。只有當其 devcontainer-feature.json 中的版本屬性更新時,功能才會重新發布。

注意:使用 GHCR 的一個手動步驟是將 OCI 包標記為“公共”。這隻需要為每個功能執行一次。私有功能不需要此步驟,只要您使用登錄檔的憑據登入到 Docker CLI,就可以訪問它們。

與社群共享您的功能

如果您希望您的貢獻出現在 VS Code Dev ContainersGitHub Codespaces UI 中供開發容器建立使用,您可以執行以下步驟:

合併後,您的更改將出現在 containers.dev/collections 上。

功能安裝順序

如果我的功能應該在另一個功能之後安裝怎麼辦?作為功能作者,您可能會發現您的功能應該在其他功能之前或之後安裝。在 devcontainer-feature.json 中,您可以使用 installsAfter 屬性列出應在其之前執行的功能。

作為終端使用者,您可以使用 devcontainer.json 中的 overrideFeatureInstallOrder 屬性進一步控制執行順序。此陣列中的任何功能 ID 都將在所有其他功能之前安裝,並按提供的順序安裝。例如:

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

預設情況下,功能以實現工具確定的最佳順序安裝在基礎映象之上。

如果在功能的 devcontainer-feature.json 或使用者的 devcontainer.json 中提供了以下任何屬性,則會遵守這些屬性指示的順序(按優先順序遞減)。

  1. 使用者 devcontainer.json 中的 overrideFeatureInstallOrder 屬性。允許使用者控制其功能的執行順序。
  2. 作為功能 devcontainer-feature.json 一部分定義的 installsAfter 屬性。

您可以在規範中閱讀有關功能執行和安裝順序的更多資訊。

還有什麼新功能?

除了新的 Features 倉庫之外,我們最近還開放了一個新的 devcontainers/images 倉庫,其中託管了一組以前位於 vscode-dev-containers 倉庫中的特定映象。

我們正在制定一個開發容器模板(我們在 vscode-dev-containers 中將其稱為“定義”)的社群分發計劃,我們預計它會類似於功能。當宣佈新的 Features 和 images 倉庫時,我們會在 vscode-dev-containers 倉庫中釋出更新。

如何瞭解更多資訊?

這篇文章只是介紹了您可以使用功能做什麼,我們很高興您能嘗試一下!

正如上面內容中連結的那樣,瞭解功能內容以及如何分發的最佳位置是開發容器規範的功能功能分發頁面。

我們期待您在使用、建立和釋出功能時的反饋——我們很想聽聽它們在功能功能分發問題提案中的使用情況。

如果您有興趣參與整個規範或連線另一個工具來利用它,請檢視 dev container specCLI 倉庫。

祝您開發容器建立愉快,編碼愉快!

Brigit Murtaugh, @BrigitMurtaugh

© . This site is unofficial and not affiliated with Microsoft.