Instalar Build Tools en un contenedor

Puede instalar Visual Studio Build Tools en un contenedor de Windows para admitir los flujos de trabajo de integración continua y entrega continua (CI/CD). Este artículo le guía a través de los cambios de configuración de Docker necesarios, así como de las cargas de trabajo y componentes que puede instalar en un contenedor.

Los contenedores son una excelente manera de empaquetar un sistema de compilación coherente que se puede usar no solo en un entorno de servidor de CI/CD sino también para entornos de desarrollo. Por ejemplo, puede montar el código fuente en un contenedor para que se compile en un entorno personalizado mientras continúa usando Visual Studio u otras herramientas para escribir el código. Si en el flujo de trabajo de CI/CD se usa la misma imagen de contenedor, puede estar seguro de que el código se compila de forma coherente. También puede usar contenedores por motivos de coherencia del tiempo de ejecución, lo que es común para microservicios que usan varios contenedores con un sistema de orquestación, pero queda fuera del ámbito de este artículo.

Si Visual Studio Build Tools no tiene lo que necesita para compilar el código fuente, estos mismos pasos se pueden usar para otros productos de Visual Studio. Sin embargo, tenga en cuenta que los contenedores de Windows no admiten una interfaz de usuario interactiva, por lo que todos los comandos se deben automatizar.

Antes de empezar

A continuación se supone que tiene cierta familiaridad con Docker. Si no está familiarizado con la ejecución de Docker en Windows, obtenga información sobre cómo instalar y configurar el motor de Docker en Windows.

La imagen base siguiente es un ejemplo y puede que no funcione para su sistema. Consulte Compatibilidad de versiones de contenedor de Windows para determinar qué imagen base debe usar para su entorno.

Crear y compilar el Dockerfile

Guarde el Dockerfile de ejemplo siguiente en un archivo nuevo en el disco. Si el archivo se denomina simplemente "Dockerfile", se reconoce de forma predeterminada.

Advertencia

En este Dockerfile de ejemplo solo se excluyen los SDK de Windows anteriores que no se pueden instalar en contenedores. Las versiones anteriores hacen que el comando genere un error.

  1. Abra un símbolo del sistema.

  2. Cree un directorio (recomendado):

    mkdir C:\BuildTools
    
  3. Cambie los directorios a este nuevo directorio:

    cd C:\BuildTools
    
  4. Guarde el contenido siguiente en 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"]
    

    Sugerencia

    Para tener como destino 64 bits, especifique la opción -arch=amd64 en el comando ENTRYPOINT para iniciar el símbolo del sistema para desarrolladores para Visual Studio (VSDevCmd.bat).

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

    Advertencia

    Si basa la imagen directamente en microsoft/windowsservercore, puede que .NET Framework no se instale correctamente y no se indique ningún error de instalación. Es posible que el código administrado no se ejecute una vez completada la instalación. En su lugar, base la imagen en microsoft/dotnet-framework:4.8] u otra versión posterior. Tenga en cuenta también que es posible que las imágenes etiquetadas con la versión 4.8 o posterior usen PowerShell como valor predeterminado de SHELL, lo que hará que las instrucciones RUN y ENTRYPOINT produzcan un error.

    Consulte Compatibilidad con versiones de contenedores de Windows para ver las versiones del sistema operativo del contenedor que se admiten en las versiones del sistema operativo host, y Solución de problemas de contenedores de Windows y de herramientas de compilación para información sobre problemas conocidos.

    # 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"]
    

    Sugerencia

    Para tener como destino 64 bits, especifique la opción -arch=amd64 en el comando ENTRYPOINT para iniciar el símbolo del sistema para desarrolladores para Visual Studio (VSDevCmd.bat).

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

    Advertencia

    Si basa la imagen directamente en microsoft/windowsservercore, puede que .NET Framework no se instale correctamente y no se indique ningún error de instalación. Es posible que el código administrado no se ejecute una vez completada la instalación. En su lugar, base la imagen en microsoft/dotnet-framework:4.8 o en otra versión posterior. Tenga en cuenta también que es posible que las imágenes etiquetadas con la versión 4.8 o posterior usen PowerShell como valor predeterminado de SHELL, lo que hará que las instrucciones RUN y ENTRYPOINT produzcan un error.

    Consulte Compatibilidad con versiones de contenedores de Windows para ver las versiones del sistema operativo del contenedor que se admiten en las versiones del sistema operativo host, y Solución de problemas de contenedores de Windows y de herramientas de compilación para información sobre problemas conocidos.

    Nota:

    El código de error 3010 se usa para indicar que un reinicio necesario se ha realizado correctamente; vea Mensajes de error MsiExec.exe para obtener más información.

  5. Ejecute el comando siguiente desde ese directorio.

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

    Este comando compila el archivo Dockerfile en el directorio actual con 2 GB de memoria. El valor predeterminado de 1 GB no es suficiente cuando se instalan algunas cargas de trabajo; pero es posible que pueda realizar la compilación con solo 1 GB de memoria en función de los requisitos de compilación.

    La imagen final se etiqueta con buildtools2019:latest" para que se pueda ejecutar fácilmente en un contenedor como buildtools2019, ya que la etiqueta "latest" es el valor predeterminado si no se especifica ninguna etiqueta. Si quiere usar una versión específica de Visual Studio Build Tools 2019 en un escenario más avanzado, en su lugar se podría etiquetar el contenedor con un número de compilación de Visual Studio específico además de "latest", para que los contenedores puedan usar una versión determinada de forma coherente.

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

    Este comando compila el archivo Dockerfile en el directorio actual con 2 GB de memoria. El valor predeterminado de 1 GB no es suficiente cuando se instalan algunas cargas de trabajo; pero es posible que pueda compilar con solo 1 GB de memoria en función de los requisitos de compilación.

    La imagen final se etiqueta con "buildtools:latest" para que se pueda ejecutar fácilmente en un contenedor como "buildtools", ya que la etiqueta "latest" es el valor predeterminado si no se especifica ninguna etiqueta. Si quiere usar una versión específica de Visual Studio Build Tools en un escenario más avanzado, en su lugar se podría etiquetar el contenedor con un número de compilación de Visual Studio específico además de "latest" para que los contenedores puedan usar una versión determinada de forma coherente.

Uso de la imagen compilada

Ahora que se ha creado una imagen, también se puede ejecutar en un contenedor para realizar compilaciones interactivas y automatizadas. En el ejemplo se usa el símbolo del sistema para desarrolladores, por lo que PATH y otras variables de entorno ya están configuradas.

  1. Abra un símbolo del sistema.

  2. Ejecute el contenedor para iniciar un entorno de PowerShell con todas las variables de entorno del desarrollador establecidas:

    docker run -it buildtools2019
    
    docker run -it buildtools
    

Para usar esta imagen con el flujo de trabajo de CI/CD, puede publicarla en su propia instancia de Azure Container Registry o en otro registro de Docker interno para que los servidores solo tengan que extraerla.

Nota:

Si el contenedor de Docker genera algún error al iniciarse, es probable que haya un problema con la instalación de Visual Studio. Se puede actualizar Dockerfile para quitar el paso que llama al comando batch de Visual Studio. Esto permite iniciar el contenedor de Docker y leer los registros de errores de la instalación.

En el archivo Dockerfile, quite los parámetros C:\\BuildTools\\Common7\\Tools\\VsDevCmd.bat y && del comando ENTRYPOINT. Ahora, el comando debería ser ENTRYPOINT ["powershell.exe", "-NoLogo", "-ExecutionPolicy", "Bypass"]. Después, recompile Dockerfile y ejecute el comando run para acceder a los archivos de contenedor. Para ubicar los registros de errores de instalación, vaya al directorio $env:TEMP y busque el archivo dd_setup_<timestamp>_errors.log.

Después de identificar y corregir la incidencia de la instalación, se pueden volver a agregar los parámetros C:\\BuildTools\\Common7\\Tools\\VsDevCmd.bat y && al comando ENTRYPOINT y recompilar Dockerfile.

Para más información, consulte Solución de problemas de contenedores de Windows y de herramientas de compilación.

Solución de problemas de contenedores de Windows y de herramientas de compilación

Hay algunos problemas al instalar Visual Studio en un contenedor Docker.

Solución de problemas de contenedores de Windows

Los problemas conocidos aquí descritos se producen cuando se instala Visual Studio Build Tools en un contenedor de Windows.

  • Pase -m 2GB (o más) al compilar la imagen. Algunas cargas de trabajo requieren más memoria de la predeterminada (1 GB) cuando se instalan.

  • Configure Docker para usar discos mayores que el valor predeterminado de 20 GB.

  • Pase --norestart en la línea de comandos. Al redactar este artículo, el intento de reinicio de un contenedor de Windows desde el contenedor devuelve ERROR_TOO_MANY_OPEN_FILES al host.

  • Si basa la imagen directamente en mcr.microsoft.com/windows/servercore, es posible que .NET Framework no se instale correctamente y no se indique ningún error de instalación. Es posible que el código administrado no se ejecute una vez completada la instalación. En su lugar, base la imagen en microsoft/dotnet-framework:4.7.1 o en otra versión posterior. Por ejemplo, es posible al compilar con MSBuild que vea un error similar al siguiente:

    C:\BuildTools\MSBuild\15.0\bin\Roslyn\Microsoft.CSharp.Core.targets(84,5): Error MSB6003: No se pudo ejecutar la tarea ejecutable "csc.exe" especificada. No se pudo cargar el archivo o ensamblado «System.IO.FileSystem, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a» o una de sus dependencias. El sistema no puede encontrar el archivo especificado.

Solución de problemas de contenedores de herramientas de compilación

Es posible que se produzcan los siguientes problemas conocidos al usar un contenedor de Build Tools. Para ver si se han corregido problemas o si hay otros problemas conocidos, visite Developer Community.

  • Es posible que IntelliTrace no funcione en algunos escenarios dentro de un contenedor.
  • En versiones anteriores de Docker para Windows, el tamaño de la imagen del contenedor predeterminado es de solo 20 GB y no cabrá en Build Tools. Siga las instrucciones para cambiar el tamaño de la imagen a 127 GB o más. Para confirmar una incidencia de espacio en disco, compruebe los archivos de registro para obtener más información. Si se queda sin espacio en disco, su archivo vslogs\dd_setup_<timestamp>_errors.log incluirá lo siguiente:
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.