🚀 在 VS Code 中

建立開發容器

Visual Studio Code 開發容器擴充功能可讓您使用 Docker 容器 作為功能完整的開發環境。它可讓您在容器內開啟任何資料夾或儲存庫,並充分利用 Visual Studio Code 的完整功能集。專案中的 devcontainer.json 檔案會告知 VS Code 如何存取 (或建立) 具有明確定義的工具和執行階段堆疊的開發容器。此容器可用於執行應用程式,或提供使用程式碼庫所需的個別工具、程式庫或執行階段。

建立開發容器的路徑

在本文中,我們將逐步說明如何在 VS Code 中建立開發 (dev) 容器

  1. 建立 devcontainer.json,其中描述 VS Code 應如何啟動容器以及連線後該怎麼做。
  2. 透過使用 Dockerfile,對開發容器進行和保存變更,例如安裝新軟體。
  3. 透過 Docker Compose 設定多個容器。
  4. 當您進行變更時,請建置您的開發容器以確保變更生效。

完成上述任何步驟後,您將擁有一個功能完整的開發容器,您可以繼續本教學課程的下一步以新增更多功能,或者停止並開始在您目前擁有的開發環境中工作。

注意:Dev Containers 擴充功能具有「Dev Containers: Add Dev Container Configuration Files...」命令,可讓您從清單中挑選預先定義的容器設定。如果您希望立即擁有完整的開發容器,而不是逐步建立 devcontainer.json 和 Dockerfile,您可以跳到自動化開發容器建立

建立 devcontainer.json 檔案

VS Code 的容器設定儲存在 devcontainer.json 檔案中。此檔案類似於偵錯設定的 launch.json 檔案,但用於啟動 (或連接到) 您的開發容器。開發容器設定位於專案根目錄的 .devcontainer/devcontainer.json 下,或儲存為 .devcontainer.json 檔案 (請注意點前置字元)。

您可以使用映像作為 devcontainer.json 的起點。映像就像一個迷你磁碟機,其中預先安裝了各種工具和作業系統。您可以從容器登錄檔提取映像,容器登錄檔是儲存映像的儲存庫集合。以下是使用預先建置的 TypeScript 和 Node.js VS Code 開發容器 映像的簡單 devcontainer.json 範例

{
  "image": "mcr.microsoft.com/devcontainers/typescript-node:0-18"
}

您可以變更您的設定以執行下列動作,例如

針對此範例,如果您想要將 Code Spell Checker 擴充功能安裝到您的容器中,並自動轉發埠號 3000,則您的 devcontainer.json 看起來會像這樣

{
  "image": "mcr.microsoft.com/devcontainers/typescript-node",

  "customizations": {
    "vscode": {
      "extensions": ["streetsidesoftware.code-spell-checker"]
    }
  },
  "forwardPorts": [3000]
}

注意:額外設定將根據基礎映像中的內容新增至容器。例如,我們在上方新增了 streetsidesoftware.code-spell-checker 擴充功能,且容器也會包含 "dbaeumer.vscode-eslint",因為這是 mcr.microsoft.com/devcontainers/typescript-node 的一部分。當使用 devcontainer.json 進行預先建置時,這會自動發生,您可以在預先建置章節中閱讀更多相關資訊。

使用上述 devcontainer.json,您的開發容器即可運作,您可以連線並開始在其中進行開發。使用「Dev Containers: Reopen in Container」命令試試看

Quick pick with list of Dev Containers commands

執行此命令後,當 VS Code 重新啟動時,您現在位於 Node.js 和 TypeScript 開發容器中,其中埠號 3000 已轉發且已安裝 ESLint 擴充功能。連線後,請注意狀態列左側的綠色遠端指示器,以顯示您已連線到您的開發容器

VS Code instance connected to dev container

其他開發容器案例

透過 devcontainer.json 檔案,您可以

如果 devcontainer.json 支援的工作流程不符合您的需求,您也可以連接到已在執行的容器

提示:想要使用遠端 Docker 主機嗎?請參閱在遠端 Docker 主機上開發文章,以取得設定的詳細資訊。

安裝額外軟體

您可能想要在您的開發容器中安裝額外軟體。一旦 VS Code 連線到容器,您可以開啟 VS Code 終端機,並針對容器內的作業系統執行任何命令。這可讓您安裝新的命令列公用程式,並從 Linux 容器內部啟動資料庫或應用程式服務。

大多數容器映像都以 Debian 或 Ubuntu 為基礎,其中 aptapt-get 命令用於安裝新套件。您可以在 Ubuntu 的文件中深入瞭解此命令。Alpine 映像包含類似的 apk 命令,而 CentOS / RHEL / Oracle SE / Fedora 映像使用 yum最近的 dnf

您想要安裝的軟體的文件通常會提供特定指示,但如果您在容器中以根使用者身分執行,則可能不需要在命令前加上 sudo

例如

# If running as root
apt-get update
apt-get install <package>

如果您以根使用者身分執行,只要 sudo 在您的容器中設定,您就可以安裝軟體。所有預先定義的容器都已設定 sudo,但將非根使用者新增至容器文章可以協助您為自己的容器設定此功能。無論如何,如果您安裝並設定 sudo,您將能夠在以任何使用者 (包括根使用者) 身分執行時使用它。

# If sudo is installed and configured
sudo apt-get update
sudo apt-get install <package>

假設您想要安裝 Git。您可以在 VS Code 的整合式終端機中執行下列命令

# If sudo is installed and configured
sudo apt-get update
# Install Git
sudo apt-get install git

您也可以使用 devcontainer.json 中的 "features" 屬性,從預先定義的功能集合,甚至是您自己的功能中安裝工具和語言。

例如,您可以使用下列程式碼安裝最新版本的 Azure CLI

"features": {
    "ghcr.io/devcontainers/features/azure-cli:1": {
        "version": "latest"
    }
  }

如需更多詳細資訊,請參閱開發容器功能規格

重建

當編輯 .devcontainer 資料夾的內容時,您需要重建才能使變更生效。使用「Dev Containers: Rebuild Container」命令來更新您的容器。

但是,如果您重建容器,您將必須重新安裝您手動安裝的任何項目。為了避免此問題,您可以使用 devcontainer.json 中的 postCreateCommand 屬性或自訂 Dockerfile

自訂 Dockerfile 將受益於 Docker 的組建快取,並產生比 postCreateCommand 更快的重建速度。但是,Dockerfile 會在建立開發容器並掛接工作區資料夾之前執行,因此無法存取工作區資料夾中的檔案。Dockerfile 最適合用於安裝獨立於工作區檔案的套件和工具。

postCreateCommand 動作會在容器建立後執行一次,因此您也可以使用此屬性來執行 npm install 等命令,或執行來源樹狀結構中的 Shell 指令碼 (如果您已掛接)。

"postCreateCommand": "bash scripts/install-dependencies.sh"

您也可以使用互動式 bash Shell,以便挑選您的 .bashrc,自動自訂您的 Shell 以符合您的環境

"postCreateCommand": "bash -i scripts/install-dependencies.sh"

若未使用 -i 將 Shell 置於互動模式,則 NVM 等工具將無法運作

"postCreateCommand": "bash -i -c 'nvm install --lts'"

命令需要結束,否則容器將不會啟動。例如,如果您將應用程式啟動新增至 postCreateCommand,則命令將不會結束。

還有一個 postStartCommand 會在每次容器啟動時執行。參數的行為與 postCreateCommand 完全相同,但命令會在啟動時而非建立時執行。

更有效率的做法是使用 Dockerfile,而不是直接在 devcontainer.json 中參考映像,或透過 postCreateCommandpostStartCommand 安裝軟體。

Dockerfile

Dockerfile 也會位於 .devcontainer 資料夾中。您可以將 devcontainer.json 中的 image 屬性取代為 dockerfile

{
  "build": { "dockerfile": "Dockerfile" },

  "customizations": {
    "vscode": {
      "extensions": ["dbaeumer.vscode-eslint"]
    }
  },

  "forwardPorts": [3000]
}

當您進行變更 (例如安裝新軟體) 時,即使在重建開發容器後,Dockerfile 中所做的變更仍會持續存在。

在您的 Dockerfile 中,使用 FROM 來指定映像,並使用 RUN 指令來安裝任何軟體。您可以使用 && 將多個命令串在一起。

FROM mcr.microsoft.com/devcontainers/javascript-node:0-18
RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
    && apt-get -y install git

注意:DEBIAN_FRONTEND 匯出可避免您繼續使用容器時出現警告。

自動化開發容器建立

從命令選擇區 (F1) 選取「Dev Containers: Add Dev Container Configuration Files...」命令,而不是手動建立 .devcontainer,這會將所需的檔案新增至您的專案作為起點,您可以進一步自訂以符合您的需求。

此命令可讓您從清單中挑選預先定義的容器設定,此清單根據您資料夾的內容而定

Add a dev container config

您可以從我們的第一方和社群索引中挑選預先定義的容器設定,這是開發容器規格的一部分。我們在 devcontainers/templates 儲存庫中將一組範本作為規格的一部分託管。您可以瀏覽該儲存庫的 src 資料夾,以查看每個範本的內容。

在使用「Dev Containers: Add Dev Container Configuration Files...」的結尾,您會看到可用的功能清單,這些功能是您可以輕鬆放入開發容器的工具和語言。「Dev Containers: Configure Container Features」可讓您更新現有的設定。

Dev container features in Command Palette

您也可以重複使用現有的 Dockerfile

Select Dockerfile

現在您有了 devcontainer.json 和 Dockerfile,讓我們看看編輯容器設定檔案的一般程序。

完整設定編輯迴圈

編輯您的容器設定很容易。由於重建容器會將容器「重設」為其起始內容 (您的本機原始碼除外),因此如果您編輯容器設定檔案 (devcontainer.jsonDockerfiledocker-compose.yml),VS Code 不會自動重建。相反地,有幾個命令可用於簡化您的設定編輯。

以下是使用這些命令的一般編輯迴圈

Container edit loop illustration

  1. 從命令選擇區 (F1) 中的「Dev Containers: Add Dev Container Configuration Files...」開始。
  2. 視需要編輯 .devcontainer 資料夾的內容。
  3. 使用「Dev Containers: Reopen in Container」試試看。
  4. 如果您看到錯誤,請在出現的對話方塊中選取「Open Folder Locally」。
  5. 在視窗重新載入後,組建記錄的副本會出現在主控台中,以便您調查問題。視需要編輯 .devcontainer 資料夾的內容。(如果您關閉記錄,也可以使用「Dev Containers: Show Container Log」命令再次查看記錄。)
  6. 執行「Dev Containers: Rebuild and Reopen in Container」,如果需要,請跳至步驟 4。

如果您已經成功組建,您仍然可以在連線到容器時視需要編輯 .devcontainer 資料夾的內容,然後在命令選擇區 (F1) 中選取「Dev Containers: Rebuild Container」,讓變更生效。

當您使用「Dev Containers: Clone Repository in Container Volume」命令時,也可以反覆運算您的容器。

  1. 從命令選擇區 (F1) 中的「Dev Containers: Clone Repository in Container Volume」開始。如果您輸入的儲存庫中沒有 devcontainer.json,系統會要求您選取起點。
  2. 視需要編輯 .devcontainer 資料夾的內容。
  3. 使用「Dev Containers: Rebuild Container」試試看。
  4. 如果您看到錯誤,請在出現的對話方塊中選取「Open in Recovery Container」。
  5. 在此「復原容器」中,視需要編輯 .devcontainer 資料夾的內容。
  6. 使用「Dev Containers: Reopen in Container」,如果您仍然遇到問題,請跳至步驟 4。

使用 Docker Compose

在某些情況下,單一容器環境不足以滿足需求。假設您想要將另一個複雜元件新增至您的設定,例如資料庫。您可以嘗試直接將其新增至 Dockerfile,或者您可以透過其他容器新增它。幸運的是,Dev Containers 支援 Docker Compose 管理的多容器設定。

您可以選擇

  1. 使用在現有的未修改 docker-compose.yml 中定義的服務。
  2. 建立新的 docker-compose.yml (或建立現有檔案的複本),您可以使用它來開發服務。
  3. 擴充您現有的 Docker Compose 設定以開發服務。
  4. 使用個別的 VS Code 視窗來一次處理多個 Docker Compose 定義的服務

注意:當使用 Alpine Linux 容器時,某些擴充功能可能無法運作,因為擴充功能內部的原生程式碼中存在 glibc 依存性。

VS Code 可以設定為自動啟動 Docker Compose 檔案中特定服務的任何所需容器。如果您已使用命令列啟動已設定的容器,VS Code 將會連接到您指定的執行中服務。這讓您的多容器工作流程具有與上述 Docker 映像和 Dockerfile 工作流程相同的快速設定優勢,同時仍然允許您在偏好時使用命令列。

若要快速開始使用,請在 VS Code 中開啟您想要使用的資料夾,並在命令選擇區 (F1) 中執行「Dev Containers: Add Dev Container Configuration Files...」命令。

系統會提示您從我們的第一方和社群索引中挑選預先定義的容器設定,此清單會根據您資料夾的內容進行篩選和排序。從 VS Code UI,您可以選取下列其中一個範本作為 Docker Compose 的起點

  • 現有的 Docker Compose - 包含一組檔案,您可以將其放入現有的專案中,以重複使用您專案根目錄中的 docker-compose.yml 檔案。
  • Node.js 與 MongoDB - 連接到不同容器中 MongoDB 資料庫的 Node.js 容器。
  • Python 與 PostgreSQL - 連接到不同容器中 PostgreSQL 的 Python 容器。
  • Docker-Outside-of-Docker Compose - 包含 Docker CLI,並說明如何透過磁碟區掛接 Docker Unix Socket,從開發容器內部存取您的本機 Docker 安裝。

在您選取之後,VS Code 會將適當的 .devcontainer/devcontainer.json (或 .devcontainer.json) 檔案新增至資料夾。

您也可以手動建立您的設定。若要重複使用未修改的 Docker Compose 檔案,您可以使用 .devcontainer/devcontainer.json 中的 dockerComposeFileservice 屬性。

例如

{
  "name": "[Optional] Your project name here",
  "dockerComposeFile": "../docker-compose.yml",
  "service": "the-name-of-the-service-you-want-to-work-with-in-vscode",
  "workspaceFolder": "/default/workspace/path/in/container/to/open",
  "shutdownAction": "stopCompose"
}

如需其他可用屬性 (例如 workspaceFoldershutdownAction) 的相關資訊,請參閱devcontainer.json 參考

在您將 .devcontainer/devcontainer.json 檔案新增至您的資料夾後,請從命令選擇區 (F1) 執行「Dev Containers: Reopen in Container」命令 (如果您尚未在容器中,則執行「Dev Containers: Open Folder in Container...」)。

如果容器尚未執行,在此範例中,VS Code 將呼叫 docker-compose -f ../docker-compose.yml upservice 屬性表示 VS Code 應連線到 Docker Compose 檔案中的哪個服務,而不是應啟動哪個服務。如果您手動啟動它們,VS Code 將會連接到您指定的服務。

您也可以建立 Docker Compose 檔案的開發複本。例如,如果您有 .devcontainer/docker-compose.devcontainer.yml,您只需要變更 devcontainer.json 中的下列行

"dockerComposeFile": "docker-compose.devcontainer.yml"

但是,更好的方法通常是避免建立 Docker Compose 檔案的複本,方法是使用另一個檔案擴充它。我們將在下一個章節中涵蓋擴充 Docker Compose 檔案

為了避免在預設容器命令失敗或結束時關閉容器,您可以修改 devcontainer.json 中指定的服務 Docker Compose 檔案,如下所示

# Overrides default command so things don't shut down after the process ends.
command: /bin/sh -c "while sleep 1000; do :; done"

如果您尚未這麼做,您可以使用Docker Compose 檔案中的磁碟區清單,將您的本機原始碼「繫結」掛接到容器中。

例如

volumes:
  # Mounts the project folder to '/workspace'. The target path inside the container
  # should match what your application expects. In this case, the compose file is
  # in a sub-folder, so you will mount '..'. You would then reference this path as the
  # 'workspaceFolder' in '.devcontainer/devcontainer.json' so VS Code starts here.
  - ..:/workspace:cached

但是,在 Linux 上,您可能需要設定並指定非根使用者,否則當您使用繫結掛接時,或您建立的任何檔案都將是根使用者。如需詳細資訊,請參閱將非根使用者新增至您的開發容器。若要讓 VS Code 以不同的使用者身分執行,請將此新增至 devcontainer.json

"remoteUser": "your-user-name-here"

如果您希望所有程序都以不同的使用者身分執行,請將此新增至 Docker Compose 檔案中的適當服務

user: your-user-name-here

如果您沒有為開發建立自訂 Dockerfile,您可能會想要在服務的容器內安裝其他開發人員工具,例如 curl。雖然不如將這些工具新增至容器映像有效率,但您也可以將 postCreateCommand 屬性用於此目的。

如需安裝軟體的詳細資訊,請參閱安裝額外軟體,如需 postCreateCommand 屬性的詳細資訊,請參閱devcontainer.json 參考

如果您的應用程式是使用 C++、Go 或 Rust 或其他使用以 ptrace 為基礎的偵錯工具的語言所建置,您也需要將下列設定新增至您的 Docker Compose 檔案

# Required for ptrace-based debuggers like C++, Go, and Rust
cap_add:
- SYS_PTRACE
security_opt:
- seccomp:unconfined

在您第一次建立容器後,您需要執行「Dev Containers: Rebuild Container」命令,才能讓 devcontainer.json、您的 Docker Compose 檔案或相關 Dockerfile 的更新生效。

在 Docker Compose 中使用 localhost

您可以將其他服務新增至您的 docker-compose.yml 檔案,如 Docker 文件中所述。但是,如果您希望在此服務中執行的任何項目在容器上的 localhost 中可用,或想要在本機轉發服務,請務必將此行新增至服務組態

# Runs the service on the same network as the database container, allows "forwardPorts" in devcontainer.json function.
network_mode: service:db

您可以在Node.js 和 MongoDB 範例開發容器中看到 network_mode: service:db 的範例。

擴充您的 Docker Compose 檔案以進行開發

參考現有的部署/非開發重點 docker-compose.yml 有一些潛在的缺點。

例如

  • 如果 Docker Compose 的進入點關閉,則會關閉容器。這對於您正在偵錯且需要重複重新啟動應用程式的情況而言會造成問題。
  • 您也可能未將本機檔案系統對應到容器中,或將埠號公開給您想要存取的其他資源 (例如資料庫)。
  • 您可能想要將本機 .ssh 資料夾的內容複製到容器中,或設定上方使用 Docker Compose中所述的 ptrace 選項。

您可以透過使用多個 docker-compose.yml 檔案來擴充您的完整 Docker Compose 設定,以解決這些問題和其他類似問題,這些檔案會覆寫或補充您的主要檔案。

例如,考慮此額外的 .devcontainer/docker-compose.extend.yml 檔案

version: '3'
services:
  your-service-name-here:
    volumes:
      # Mounts the project folder to '/workspace'. While this file is in .devcontainer,
      # mounts are relative to the first file in the list, which is a level up.
      - .:/workspace:cached

    # [Optional] Required for ptrace-based debuggers like C++, Go, and Rust
    cap_add:
      - SYS_PTRACE
    security_opt:
      - seccomp:unconfined

    # Overrides default command so things don't shut down after the process ends.
    command: /bin/sh -c "while sleep 1000; do :; done"

此相同檔案可以視需要提供其他設定,例如埠號對應。若要使用它,除了 .devcontainer/docker-compose.extend.yml 之外,還要依特定順序參考您的原始 docker-compose.yml 檔案

{
  "name": "[Optional] Your project name here",

  // The order of the files is important since later files override previous ones
  "dockerComposeFile": ["../docker-compose.yml", "docker-compose.extend.yml"],

  "service": "your-service-name-here",
  "workspaceFolder": "/workspace",
  "shutdownAction": "stopCompose"
}

VS Code 接著會在啟動任何容器時自動使用這兩個檔案。您也可以從命令列自行啟動它們,如下所示

docker-compose -f docker-compose.yml -f .devcontainer/docker-compose.extend.yml up

雖然 postCreateCommand 屬性可讓您在容器內安裝其他工具,但在某些情況下,您可能想要針對開發使用特定的 Dockerfile。您也可以使用相同的方法來參考專門用於開發的自訂 Dockerfile,而無需修改您現有的 Docker Compose 檔案。例如,您可以更新 .devcontainer/docker-compose.extend.yml 如下所示

version: '3'
services:
  your-service-name-here:
      # Note that the path of the Dockerfile and context is relative to the *primary*
      # docker-compose.yml file (the first in the devcontainer.json "dockerComposeFile"
      # array). The sample below assumes your primary file is in the root of your project.
      build:
        context: .
        dockerfile: .devcontainer/Dockerfile
      volumes:
        - .:/workspace:cached
      command: /bin/sh -c "while sleep 1000; do :; done"

恭喜!您現在已在 Visual Studio Code 中設定開發容器。繼續閱讀以瞭解如何在隊友和各種專案之間共用容器設定。

將設定檔新增至儲存庫

您可以透過將 devcontainer.json 檔案新增至原始碼控制,輕鬆地共用您專案的自訂開發容器範本。透過在您的儲存庫中包含這些檔案,任何在 VS Code 中開啟您儲存庫本機複本的人員都會自動收到提示,要求在容器中重新開啟資料夾,前提是他們已安裝 Dev Containers 擴充功能。

Dev container configuration file reopen notification

除了讓您的團隊使用一致的環境和工具鏈的優點之外,這也讓新的貢獻者或團隊成員更容易快速提高生產力。首次貢獻者將需要較少的指導,並且會遇到較少與環境設定相關的問題。

新增在開發容器中開啟徽章

您也可以在您的儲存庫中新增徽章或連結,讓使用者可以輕鬆地在 Dev Containers 中開啟您的專案。如有必要,它會安裝 Dev Containers 擴充功能,將儲存庫複製到容器磁碟區中,並啟動開發容器。

例如,開啟 https://github.com/microsoft/vscode-remote-try-java 的徽章看起來會像這樣

[![Open in Dev Containers](https://img.shields.io/static/v1?label=Dev%20Containers&message=Open&color=blue)](https://vscode.dev/redirect?url=vscode://ms-vscode-remote.remote-containers/cloneInVolume?url=https://github.com/microsoft/vscode-remote-try-java)

您也可以直接包含 open in dev container 連結

If you already have VS Code and Docker installed, you can click the badge above or [here](https://vscode.dev/redirect?url=vscode://ms-vscode-remote.remote-containers/cloneInVolume?url=https://github.com/microsoft/vscode-remote-try-java) to get started. Clicking these links will cause VS Code to automatically install the Dev Containers extension if needed, clone the source code into a container volume, and spin up a dev container for use.

替代方案:儲存庫組態資料夾

在某些情況下,您可能會想要為您不控制的儲存庫,或您不希望在其儲存庫本身包含組態的儲存庫建立組態。為了處理這種情況,您可以設定本機檔案系統上的位置,以儲存將根據儲存庫自動選取的組態檔案。

首先,使用您想要用來儲存儲存庫容器組態檔案的本機資料夾更新開發 > 容器:儲存庫組態路徑使用者設定

在設定編輯器中,您可以搜尋「dev containers repo」來尋找設定

Repository container folders setting

接下來,將您的 .devcontainer/devcontainer.json(和相關檔案)放在子資料夾中,該子資料夾鏡像儲存庫的遠端位置。例如,如果您想要為 github.com/devcontainers/templates 建立組態,您將建立以下資料夾結構

📁 github.com
    📁 devcontainers
        📁 templates
           📁 .devcontainer

一旦就位,當使用任何 Dev Containers 命令時,組態將會自動選取。進入容器後,您也可以從命令面板 (F1) 選取Dev Containers:開啟容器組態檔,以開啟相關的 devcontainer.json 檔案並進行進一步編輯。

用於尋找組態的路徑是從 git remote -v 的輸出衍生而來。如果您在嘗試在容器中重新開啟資料夾時找不到組態,請檢查命令面板 (F1) 中的記錄Dev Containers:顯示容器記錄,以查看已檢查路徑的清單。

後續步驟