將 Build Tools 安裝至容器

您可以將 Visual Studio Build Tools 安裝至 Windows 容器,以便支援持續整合與持續傳遞 (CI/CD) 工作流程。 本文將引導您了解需要進行的 Docker 組態變更,以及可在容器中安裝的工作負載和元件

容器是用來封裝一致之建置系統的好方法,不僅可用於 CI/CD 伺服器環境,也可用於開發環境。 例如,您可以將原始程式碼裝載於容器中以供自訂環境建置,同時繼續使用 Visual Studio 或其他工具來撰寫程式碼。 如果您的 CI/CD 工作流程使用相同的容器映像,就能確信您的程式碼會以一致的方式建置。 您也可以使用容器來取得執行階段一致性,此做法常見於使用具有一套協調流程系統之多個容器的微服務,但不在本文討論範圍內。

如果 Visual Studio Build Tools 沒有您建置原始程式碼所需的工具,這些相同步驟可用於其他 Visual Studio 產品。 但請注意,Windows 容器不支援互動式使用者介面,因此所有命令都必須自動化。

開始之前

假設您已熟悉下列 Docker 功能。 若不熟悉如何在 Windows 上執行 Docker,請了解如何在 Windows 上安裝並設定 Docker 引擎 \(部分機器翻譯\)。

下面的基底映像是範例,因此可能無法適用於您的系統。 閱讀 Windows 容器版本相容性以決定您應該為您的環境使用哪個基底映像。

建立並建置 Dockerfile

將下列範例 Dockerfile 儲存至磁碟上的新檔案。 如果檔案直接以 "Dockerfile" 命名,預設會辨識此名稱。

警告

此範例 Dockerfile 只會排除無法安裝至容器的舊版 Windows SDK。 較舊版本會造成建置命令失敗。

  1. 開啟命令提示字元。

  2. 建立新的目錄 (建議):

    mkdir C:\BuildTools
    
  3. 將目錄變更為此新目錄:

    cd C:\BuildTools
    
  4. 將下列內容儲存至 C:\BuildTools\Dockerfile。

    # escape=`
    
    # Use the latest Windows Server Core 2019 image.
    FROM mcr.microsoft.com/windows/servercore:ltsc2019
    
    # Restore the default Windows shell for correct batch processing.
    SHELL ["cmd", "/S", "/C"]
    
    RUN `
        # Download the Build Tools bootstrapper.
        curl -SL --output vs_buildtools.exe https://aka.ms/vs/16/release/vs_buildtools.exe `
        `
        # Install Build Tools with the Microsoft.VisualStudio.Workload.AzureBuildTools workload, excluding workloads and components with known issues.
        && (start /w vs_buildtools.exe --quiet --wait --norestart --nocache `
            --installPath "%ProgramFiles(x86)%\Microsoft Visual Studio\2019\BuildTools" `
            --add Microsoft.VisualStudio.Workload.AzureBuildTools `
            --remove Microsoft.VisualStudio.Component.Windows10SDK.10240 `
            --remove Microsoft.VisualStudio.Component.Windows10SDK.10586 `
            --remove Microsoft.VisualStudio.Component.Windows10SDK.14393 `
            --remove Microsoft.VisualStudio.Component.Windows81SDK `
            || IF "%ERRORLEVEL%"=="3010" EXIT 0) `
        `
        # Cleanup
        && del /q vs_buildtools.exe
    
    # Define the entry point for the docker container.
    # This entry point starts the developer command prompt and launches the PowerShell shell.
    ENTRYPOINT ["C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\Common7\\Tools\\VsDevCmd.bat", "&&", "powershell.exe", "-NoLogo", "-ExecutionPolicy", "Bypass"]
    

    提示

    若要以 64 位元為目標,請在 ENTRYPOINT 命令中指定 -arch=amd64 選項,以啟動 Visual Studio 的開發人員命令提示字元 (VSDevCmd.bat)。

    例如:ENTRYPOINT ["C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\Common7\\Tools\\VsDevCmd.bat", "-arch=amd64", "&&", "powershell.exe", "-NoLogo", "-ExecutionPolicy", "Bypass"]

    警告

    如果您讓映像直接以 microsoft/windowsservercore 為基礎,.NET Framework 可能無法正確安裝且不會指出任何安裝錯誤。 安裝完成之後,可能無法執行受控碼。 相反地,讓您的映像以 microsoft/dotnet-framework:4.8] 或更新版本為基礎。 另請注意,標記為 4.8 或更新版的映像可能會使用 PowerShell 作為預設 SHELL,導致 RUNENTRYPOINT 指令失敗。

    請參閱 Windows 容器版本相容性以查看各種主機 OS 版本所支援的容器 OS 版本,並參閱 Windows 和建置工具容器疑難排解以了解已知問題。

    # escape=`
    
    # Use the latest Windows Server Core 2022 image.
    FROM mcr.microsoft.com/windows/servercore:ltsc2022
    
    # Restore the default Windows shell for correct batch processing.
    SHELL ["cmd", "/S", "/C"]
    
    RUN `
        # Download the Build Tools bootstrapper.
        curl -SL --output vs_buildtools.exe https://aka.ms/vs/17/release/vs_buildtools.exe `
        `
        # Install Build Tools with the Microsoft.VisualStudio.Workload.AzureBuildTools workload, excluding workloads and components with known issues.
        && (start /w vs_buildtools.exe --quiet --wait --norestart --nocache `
            --installPath "%ProgramFiles(x86)%\Microsoft Visual Studio\2022\BuildTools" `
            --add Microsoft.VisualStudio.Workload.AzureBuildTools `
            --remove Microsoft.VisualStudio.Component.Windows10SDK.10240 `
            --remove Microsoft.VisualStudio.Component.Windows10SDK.10586 `
            --remove Microsoft.VisualStudio.Component.Windows10SDK.14393 `
            --remove Microsoft.VisualStudio.Component.Windows81SDK `
            || IF "%ERRORLEVEL%"=="3010" EXIT 0) `
        `
        # Cleanup
        && del /q vs_buildtools.exe
    
    # Define the entry point for the docker container.
    # This entry point starts the developer command prompt and launches the PowerShell shell.
    ENTRYPOINT ["C:\\Program Files (x86)\\Microsoft Visual Studio\\2022\\BuildTools\\Common7\\Tools\\VsDevCmd.bat", "&&", "powershell.exe", "-NoLogo", "-ExecutionPolicy", "Bypass"]
    

    提示

    若要以 64 位元為目標,請在 ENTRYPOINT 命令中指定 -arch=amd64 選項,以啟動 Visual Studio 的開發人員命令提示字元 (VSDevCmd.bat)。

    例如:ENTRYPOINT ["C:\\Program Files (x86)\\Microsoft Visual Studio\\2022\\BuildTools\\Common7\\Tools\\VsDevCmd.bat", "-arch=amd64", "&&", "powershell.exe", "-NoLogo", "-ExecutionPolicy", "Bypass"]

    警告

    如果您讓映像直接以 microsoft/windowsservercore 為基礎,.NET Framework 可能無法正確安裝且不會指出任何安裝錯誤。 安裝完成之後,可能無法執行受控碼。 相反地,讓您的映像以 microsoft/dotnet-framework:4.8 或更新版本為基礎。 另請注意,標記為 4.8 或更新版的映像可能會使用 PowerShell 作為預設 SHELL,導致 RUNENTRYPOINT 指令失敗。

    請參閱 Windows 容器版本相容性以查看各種主機 OS 版本所支援的容器 OS 版本,並參閱 Windows 和建置工具容器疑難排解以了解已知問題。

    注意

    錯誤碼 3010 可用來指出需要重新啟動成功,請參閱 MsiExec.exe 錯誤訊息以取得詳細資訊。

  5. 從該目錄內執行下列命令。

    docker build -t buildtools2019:latest -m 2GB .
    

    此命令使用 2 GB 的記憶體在目前的目錄中建置 Dockerfile。 安裝某些工作負載時,預設 1 GB 並不夠;不過,根據您的建置需求,您可能只使用 1 GB 記憶體就能夠進行建置。

    最終映像會標記為 buildtools2019:latest,因此您可以輕鬆地在容器中當作 buildtools2019 來執行 (因為 "latest" 是未指定任何標記時的預設值)。 如果您想要在更進階的案例中使用特定版本 Visual Studio Build Tools 2019,請改以特定 Visual Studio 組建編號及 "latest" 來標記容器,以確保容器能夠一致地使用特定版本。

    docker build -t buildtools:latest -m 2GB .
    

    此命令使用 2 GB 的記憶體在目前的目錄中建置 Dockerfile。 安裝某些工作負載時,預設 1 GB 並不夠;不過,根據您的建置需求,您可能只使用 1 GB 記憶體就能夠進行建置。

    最終映像會標記為 "buildtools:latest",因此您可以輕鬆地在容器中當作 "buildtools" 來執行 (因為 "latest" 是未指定任何標記時的預設)。 如果您想要在更進階的案例中使用特定版本 Visual Studio Build Tools,請改以特定 Visual Studio 組建編號及 "latest" 來標記容器,以確保容器能夠一致地使用特定版本。

使用建置的映像

現在您已建立映像,您可以在容器中執行,以同時執行互動式和自動化組建。 此範例使用開發人員命令提示字元,因此已設定您的 PATH 和其他環境變數。

  1. 開啟命令提示字元。

  2. 執行容器,以啟動 PowerShell 環境並設定所有開發人員環境變數:

    docker run -it buildtools2019
    
    docker run -it buildtools
    

若要將此映像用於您的 CI/CD 工作流程,您可以將其發佈至自己的 Azure 容器登錄或其他內部 Docker 登錄,讓伺服器只需要加以提取。

注意

如果 Docker 容器無法啟動,可能會發生 Visual Studio 安裝問題。 您可以更新 Dockerfile 以移除呼叫 Visual Studio 批次命令的步驟。 這可讓您啟動 Docker 容器並讀取安裝錯誤記錄。

在您的 Dockerfile 檔案中,從 ENTRYPOINT 命令中移除 C:\\BuildTools\\Common7\\Tools\\VsDevCmd.bat&& 參數。 命令現在應該是 ENTRYPOINT ["powershell.exe", "-NoLogo", "-ExecutionPolicy", "Bypass"]。 接下來,重建 Dockerfile 並執行 run 命令來存取容器檔案。 若要找出安裝錯誤記錄檔,請移至 $env:TEMP 目錄並找出檔案 dd_setup_<timestamp>_errors.log

識別並修正安裝問題之後,您可以將 C:\\BuildTools\\Common7\\Tools\\VsDevCmd.bat&& 參數新增回 ENTRYPOINT 命令,然後重建您的 Dockerfile。

如需詳細資訊,請參閱 Windows 和建置工具容器疑難排解

Windows 和建置工具容器疑難排解

將 Visual Studio 安裝到 Docker 容器時有幾個問題。

Windows 容器疑難排解

當您將 Visual Studio Build Tools 安裝到 Windows 容器時,會發生下列已知問題。

  • 建立映像時,請傳遞 -m 2GB (或以上)。 某些工作負載在安裝時,需要比預設 1 GB 更多的記憶體。

  • 請設定 Docker 使用大於預設 20 GB 的磁碟。

  • 在命令列上傳遞 --norestart。 在撰寫本文時,嘗試從容器內重新啟動 Windows 容器會傳回 ERROR_TOO_MANY_OPEN_FILES 給主機。

  • 如果您讓映像直接以 microsoft/windowsservercore 為基礎,.NET Framework 可能無法正確安裝且不會指出任何安裝錯誤。 安裝完成之後,可能無法執行受控碼。 相反地,讓您的映像以 microsoft/dotnet-framework:4.7.1 或更新版本為基礎。 例如,使用與下例類似的 MSBuild 建置時,您可能會看到錯誤:

    C:\BuildTools\MSBuild\15.0\bin\Roslyn\Microsoft.CSharp.Core.targets(84,5):錯誤 MSB6003:無法執行指定的工作可執行檔 "csc.exe"。 無法載入檔案或組件 'System.IO.FileSystem, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' 或其中一個相依性。 系統找不到指定的檔案。

建置工具容器疑難排解

當您使用建置工具容器時,可能會發生下列已知問題。 若要查看問題是否已修正,或是否有其他已知問題,請瀏覽開發人員社群

  • 某些情況下,IntelliTrace 在容器內可能無法運作。
  • 在適用於 Windows 的 Docker 舊版上,預設容器映像大小只有 20 GB,因此無法容納「建置工具」。 依照變更映像大小的指示增加到 127 GB 以上。 若要確認磁碟空間問題,請檢查記錄檔以取得詳細資訊。 如果您用完磁碟空間,您的 vslogs\dd_setup_<timestamp>_errors.log 檔案將會包含下列內容:
Pre-check verification: Visual Studio needs at least 91.99 GB of disk space. Try to free up space on C:\ or change your target drive.
Pre-check verification failed with error(s) :  SizePreCheckEvaluator.