将生成工具安装到容器中

可以将 Visual Studio 生成工具安装到 Windows 容器中,以支持持续集成和持续交付(CI/CD)工作流。 本文指导你完成需要哪些 Docker 配置更改,以及可在容器中安装 工作负载和组件

容器 是打包一致构建系统的绝佳方式,不仅可用于 CI/CD 服务器环境,还可用于其他开发环境。 例如,可以在继续使用 Visual Studio 或其他工具编写代码时,将源代码装载到由自定义环境生成的容器中。 如果 CI/CD 工作流使用相同的容器映像,可以放心代码一致地生成。 还可以将容器用于运行时一致性,这在微服务中使用多个容器和业务流程系统很常见;但是,这超出了本文的范围。

如果 Visual Studio 生成工具没有生成源代码所需的内容,则可以将这些步骤用于其他 Visual Studio 产品。 但是请注意,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 指令失败。

    若要了解哪些主机 OS 版本支持哪些容器 OS 版本,请参阅 Windows 容器版本兼容性。 请检查 ,排查 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 指令失败。

    若要了解哪些主机 OS 版本支持哪些容器 OS 版本,请参阅 Windows 容器版本兼容性。 检查 排查 Windows 和生成工具容器 是否存在已知问题。

    备注

    错误代码 3010 用于指示操作成功,但需要重新启动。 有关详细信息,请参阅 MsiExec.exe 错误消息

  5. 在该目录中运行以下命令。

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

    此命令在当前目录中使用 2 GB 内存空间构建 Dockerfile。 安装某些工作负荷时,默认的 1 GB 不足;但是,根据生成要求,可能只能使用 1 GB 内存进行生成。

    最终映像 buildtools2019:latest 进行标记,因此可以在容器中轻松运行它,因为如果未指定任何标记,则 buildtools2019,因为 最新的 标记是默认值。 如果要在更 高级方案中使用特定版本的 Visual Studio 生成工具 2019,则可以改用特定的 Visual Studio 内部版本号标记容器,并 最新的,以便容器能够一致地使用特定版本。

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

    在当前目录下,此命令使用 2 GB 内存来构建 Dockerfile。 安装某些工作负荷时,默认的 1 GB 不足;但是,根据生成要求,可能只能使用 1 GB 内存进行生成。

    最终映像被标记为 buildtools:latest,因此可以在容器中轻松地作为 buildtools 执行,因为如果未指定标记,则 latest 是默认标记。 如果要在更 高级方案中使用特定版本的 Visual Studio 生成工具,则可以改用特定的 Visual Studio 内部版本号标记容器,并 最新的,以便容器能够一致地使用特定版本。

使用生成的映像

创建映像后,可以在容器中运行该映像,以执行交互式生成和自动化生成。 该示例使用开发人员命令提示符,因此已配置 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 生成工具安装到 Windows 容器中时,会出现以下已知问题。

  • 在生成映像时传入 -m 2GB(或更多)参数。 某些工作负荷在安装时需要比默认 1 GB 更多的内存。

  • 将 Docker 配置为使用大于默认 20 GB 的磁盘。

  • 在命令行上传递 --norestart。 在撰写本文时,尝试从容器内部重启 Windows 容器会将 ERROR_TOO_MANY_OPEN_FILES 返回到主机。

  • 如果您的映像直接基于 mcr.microsoft.com/windows/servercore,.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 可能无法在容器中 某些方案 工作。
  • 在旧版 Docker for Windows 上,默认容器映像大小仅为 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.