Personalizar contêineres do Docker no Visual Studio

Você pode personalizar suas imagens de contêiner editando o Dockerfile gerado pelo Visual Studio ao adicionar suporte do Docker ao seu projeto. Se você estiver criando um contêiner personalizado no IDE do Visual Studio ou configurando um build de linha de comando, precisará saber como o Visual Studio usa o Dockerfile para criar seus projetos. Você precisa saber esses detalhes porque, por motivos de desempenho, o Visual Studio segue um processo especial para criar e executar aplicativos conteinerizados que não são óbvios no Dockerfile.

Suponha que você queira fazer uma alteração no Dockerfile e ver os resultados contêineres de depuração e produção. Nesse caso, você pode adicionar comandos no Dockerfile para modificar a primeira fase (geralmente base). Confira Modificar a imagem de contêiner para depuração e produção. Porém, se você quiser fazer uma alteração somente durante a depuração, mas não na produção, deve criar outra fase e usar a configuração de build DockerfileFastModeStage para dizer ao Visual Studio para usar essa fase para builds de depuração. Confira Modificar a imagem de contêiner somente para depuração.

Este artigo explica detalhadamente o processo de build do Visual Studio para aplicativos conteinerizados e contém informações sobre como modificar o Dockerfile para afetar os builds de depuração e produção ou apenas para depuração.

Builds do Dockerfile no Visual Studio

Observação

Esta seção descreve o processo de build de contêiner que o Visual Studio usa quando você escolhe o tipo de build do contêiner Dockerfile. Se você estiver usando o tipo de build do SDK do .NET, as opções de personalização serão diferentes e as informações nesta seção não serão aplicáveis. Em vez disso, consulte Conteinerizar um aplicativo .NET com dotnet publish e use as propriedades descritas em Personalizar seu contêiner para configurar o processo de build do contêiner.

Build de várias fases

Quando o Visual Studio compila um projeto que não usa contêineres do Docker, ele invoca o MSBuild no computador local e gera os arquivos de saída em uma pasta (normalmente bin) na pasta da solução local. No entanto, para um projeto conteinerizado, o processo de build leva em conta as instruções do Dockerfile para criar o aplicativo conteinerizado. O Dockerfile que o Visual Studio usa é dividido em várias fases. Esse processo depende do recurso de build de várias fases do Docker.

O recurso de build de várias fases ajuda a tornar o processo de criação de contêineres mais eficiente e torna os contêineres menores, permitindo que contenham apenas os bits de que seu aplicativo precisa no tempo de execução. O build de várias fases é usado para projetos do .NET Core, e não para projetos do .NET Framework.

O build de várias fases permite que imagens de contêiner sejam criadas em fases que produzem imagens intermediárias. Por exemplo, considere um Dockerfile típico. A primeira fase é chamada de base no Dockerfile gerado pelo Visual Studio, embora as ferramentas não exijam esse nome.

# This stage is used when running from VS in fast mode (Default for Debug configuration)
FROM mcr.microsoft.com/dotnet/aspnet:3.1-buster-slim AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

As linhas no Dockerfile começam com a imagem do ASP.NET no Registro de Contêiner da Microsoft (mcr.microsoft.com) e criam uma imagem intermediária base que expõe as portas 80 e 443 e define o diretório de trabalho como /app.

A próxima fase é build, que aparece da seguinte maneira:

# This stage is used to build the service project
FROM mcr.microsoft.com/dotnet/sdk:3.1-buster-slim AS build
WORKDIR /src
COPY ["WebApplication43/WebApplication43.csproj", "WebApplication43/"]
RUN dotnet restore "WebApplication43/WebApplication43.csproj"
COPY . .
WORKDIR "/src/WebApplication43"
RUN dotnet build "WebApplication43.csproj" -c Release -o /app/build

Você pode ver que a fase build começa a partir de uma imagem original diferente do registro (sdk em vez de aspnet), em vez de continuar da base. A imagem sdk tem todas as ferramentas de build e, por esse motivo, é muito maior do que a imagem aspnet, que contém apenas componentes de runtime. O motivo para usar uma imagem separada fica claro quando você olha para o restante do Dockerfile:

# This stage is used to publish the service project to be copied to the final stage
FROM build AS publish
RUN dotnet publish "WebApplication43.csproj" -c Release -o /app/publish

# This stage is used in production or when running from VS in regular mode (Default when not using the Debug configuration)
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "WebApplication43.dll"]

A fase final começa novamente em base e inclui o COPY --from=publish para copiar a saída publicada para a imagem final. Esse processo possibilita que a imagem final seja muito menor, pois não precisa incluir todas as ferramentas de build que estavam na imagem sdk.

A tabela a seguir resume os estágios usados em um Dockerfile típico criado pelo Visual Studio:

Estágio Descrição
base Cria a imagem de tempo de execução base em que o aplicativo criado é publicado. As configurações que precisam estar disponíveis no tempo de execução clique aqui, como portas e variáveis de ambiente. Este estágio é usado ao executar o VS no modo rápido (padrão para configuração de depuração).
compilar O projeto é construído neste estágio. A imagem base do SDK do .NET é usada, que tem os componentes necessários para compilar seu projeto.
Publicar Esse estágio deriva do estágio de construção e publica seu projeto, que será copiado para o estágio final.
final Esse estágio configura como iniciar o aplicativo e é usado na produção ou ao executar o VS no modo regular (padrão quando não estiver usando a configuração de depuração).
aotdebug Esse estágio é usado como base para o estágio final ao iniciar o VS para dar suporte à depuração no modo regular (padrão quando não estiver usando a configuração de depuração).

Observação

O estágio aotdebug só tem suporte para contêineres do Linux. Ele será usado no Visual Studio 2022 17.11 e posterior se a implantação AOT (Ahead Of Time) nativa estiver habilitada no projeto.

Aquecimento do projeto

O aquecimento do projeto se refere a uma série de etapas que ocorrem quando o perfil do Docker é selecionado para um projeto (ou seja, quando um projeto é carregado ou o suporte do Docker é adicionado) para melhorar o desempenho das execuções subsequentes (F5 ou Ctrl+F5). Isso pode ser configurado em Ferramentas>Opções>Ferramentas de Contêiner. Estas são as tarefas executadas em segundo plano:

  • Verifique se o Docker Desktop está instalado e em execução.
  • Verifique se o Docker Desktop está definido como o mesmo sistema operacional que o projeto.
  • Extraia as imagens na primeira fase do Dockerfile (a fase base na maioria dos Dockerfiles).
  • Compile o Dockerfile e inicie o contêiner.

O aquecimento ocorre apenas no modo Rápido, portanto, o contêiner em execução tem a pasta do aplicativo montada em volume. Isso significa que qualquer alteração no aplicativo não invalida o contêiner. Portanto, isso melhora significativamente o desempenho de depuração e diminui o tempo de espera para tarefas de execução prolongada, como efetuar pull de imagens grandes.

Habilitar logs detalhados das ferramentas de contêiner

Para fins de diagnóstico, você pode habilitar determinados logs das ferramentas de contêiner. Você pode habilitar esses logs definindo determinadas variáveis de ambiente. Para projetos de contêiner único, a variável de ambiente é MS_VS_CONTAINERS_TOOLS_LOGGING_ENABLED, que então faz o logon em %tmp%\Microsoft.VisualStudio.Containers.Tools. Para projetos do Docker Compose, é MS_VS_DOCKER_TOOLS_LOGGING_ENABLED, que, em seguida, registra em %tmp%\Microsoft.VisualStudio.DockerCompose.Tools.

Aviso

Quando o registro em log está habilitado e você está usando um proxy de token para autenticação do Azure, as credenciais de autenticação podem ser registradas como texto sem formatação. Confira Configurar a autenticação do Azure.

Próximas etapas

Saiba como usar os estágios do Dockerfile para personalizar as imagens usadas para depuração e produção, por exemplo, como instalar uma ferramenta na imagem somente durante a depuração. Consulte Configurar imagens de contêiner para depuração.