Compartilhar via


Início Rápido: Usar o Docker com um aplicativo de página única do React no Visual Studio

Com o Visual Studio, você pode criar, depurar e executar aplicativos do ASP.NET Core facilmente em contêineres, incluindo aqueles com aplicativo de página única do React.js (SPA), e publicá-los no Registro de Contêiner do Azure, no Docker Hub, no Serviço de Aplicativo do Azure ou no seu próprio Registro de Contêiner. Neste artigo, publicamos no Registro de Contêiner do Azure.

Pré-requisitos

  • Docker Desktop
  • Visual Studio 2022 com Desenvolvimento para a Web, a carga de trabalho de Ferramentas do Azure e/ou Desenvolvimento multiplataforma do .NET Core instalados
  • Para publicar no Registro de Contêiner do Azure, uma assinatura do Azure. Inscreva-se em uma avaliação gratuita.
  • Node.js
  • Para contêineres do Windows, Windows 10 versão 1809 ou posterior, para usar as imagens do Docker referenciadas neste artigo.

Instalação e configuração

Para a instalação do Docker, primeiro examine as informações em Docker Desktop for Windows: What to know before you install (Docker para Windows: o que saber antes de instalar). Em seguida, instale o Docker Desktop.

Criar um projeto e adicionar suporte ao Docker

  1. Crie um projeto usando o modelo ASP.NET Core com React.js.

    Captura de tela da criação de um projeto de React.js.

  2. Na tela Informações adicionais, não é possível selecionar Habilitar Suporte do Docker, mas não se preocupe, você pode adicionar esse suporte mais tarde.

    Captura de tela da criação de um projeto de React.js – Tela de informações adicionais.

  3. Clique com botão direito do mouse no nó do projeto e escolha Adicionar>Suporte ao Docker para adicionar um Dockerfile ao seu projeto.

    Captura de tela do item de menu Adicionar Suporte do Docker.

  4. Selecione o tipo de contêiner.

A próxima etapa é diferente dependendo se você estiver usando contêineres do Linux ou contêineres do Windows.

Observação

Se estiver usando os modelos de projeto mais recentes no Visual Studio 2022 ou posterior, não será necessário modificar o Dockerfile.

Modificar o Dockerfile (contêineres do Linux)

Um Dockerfile, ou seja, a receita para criar uma imagem final do Docker, é criado no projeto. Consulte Referência do Dockerfile para compreender seus comandos.

O Dockerfile padrão usa uma imagem base para executar o contêiner, mas quando você também deseja executar um aplicativo Node.js nele, é necessário instalar o Node.js, o que significa adicionar alguns comandos de instalação em locais específicos no Dockerfile. Os comandos de instalação exigem permissões elevadas, pois as alterações afetam os arquivos e pastas do sistema privilegiados no contêiner.

Quando a caixa de seleção Configurar para HTTPS do diálogo do novo projeto estiver marcada, o Dockerfile exibirá duas portas. Uma porta é usada para o tráfego HTTP; a outra porta é usada para o HTTPS. Se a caixa de seleção não estiver marcada, uma única porta (80) será exposta para o tráfego HTTP.

Se você estiver mirando o .NET 8 ou posterior, o Dockerfile padrão que o Visual Studio cria usando a conta de usuário normal (procure pela linha USER app), no entanto, essa conta não possui as permissões elevadas necessárias para instalar o Node.js. Para lidar com essa situação, faça o seguinte:

  1. No Dockerfile, exclua a linha USER app.
  2. Altere as portas expostas na primeira seção do Dockerfile para a porta 80, para solicitações HTT, e, se você optou por dar suporte a HTTPS quando criou o projeto, altere para a porta 443, para solicitações HTTPS.
  3. Edite launchSettings.json para alterar as referências de porta para 80 e 443; substitua 8080 por 80 para HTTP e 8081 por 443 para HTTPS.

Para todas as versões do .NET, siga as próximas etapas para atualizar o Dockerfile e instalar o Node.js:

  1. Adicione as seguintes linhas para instalar o curl, o Node.js 14.x e as bibliotecas Node necessárias no contêiner. Certifique-se de adicionar essas linhas na primeira seção, para adicionar a instalação do npm.exe do gerenciador de pacotes do Node à imagem base, bem como na seção build.
RUN apt-get update
RUN apt-get install -y curl
RUN apt-get install -y libpng-dev libjpeg-dev curl libxi6 build-essential libgl1-mesa-glx
RUN curl -sL https://deb.nodesource.com/setup_lts.x | bash -
RUN apt-get install -y nodejs

O Dockerfile deve se parecer com o seguinte:

#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.

FROM mcr.microsoft.com/dotnet/aspnet:3.1 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
RUN apt-get update
RUN apt-get install -y curl
RUN apt-get install -y libpng-dev libjpeg-dev curl libxi6 build-essential libgl1-mesa-glx
RUN curl -sL https://deb.nodesource.com/setup_lts.x | bash -
RUN apt-get install -y nodejs

FROM mcr.microsoft.com/dotnet/sdk:3.1 AS build
RUN apt-get update
RUN apt-get install -y curl
RUN apt-get install -y libpng-dev libjpeg-dev curl libxi6 build-essential libgl1-mesa-glx
RUN curl -sL https://deb.nodesource.com/setup_lts.x | bash -
RUN apt-get install -y nodejs
WORKDIR /src
COPY ["ProjectSPA1/ProjectSPA1.csproj", "ProjectSPA1/"]
RUN dotnet restore "ProjectSPA1/ProjectSPA1.csproj"
COPY . .
WORKDIR "/src/ProjectSPA1"
RUN dotnet build "ProjectSPA1.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "ProjectSPA1.csproj" -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "ProjectSPA1.dll"]

O Dockerfile anterior baseia-se na imagem mcr.microsoft.com/dotnet/aspnet e inclui instruções para modificar a imagem base criando o projeto e adicionando-o ao contêiner.

Modificar o Dockerfile (contêineres do Windows)

Abra o arquivo de projeto clicando duas vezes no nó do projeto e atualize o arquivo de projeto (*.csproj) adicionando a seguinte propriedade como um filho do elemento <PropertyGroup>:

 <DockerfileFastModeStage>base</DockerfileFastModeStage>

Observação

A alteração para DockerfileFastModeStage é necessária, pois este Dockerfile adiciona um estágio ao início do Dockerfile. Para otimizar o desempenho, o Visual Studio usa o Modo rápido, mas só funciona se a fase certa for usado. O padrão é a primeira fase no Dockerfile, que, neste exemplo, é alterada de base para outra coisa para baixar o Node.js. Para obter mais explicações sobre o Modo rápido, confira o tópico Personalizar contêineres do Docker no Visual Studio.

Atualize o Dockerfile adicionando as linhas a seguir. Isso copiará o nó e o `npm`` para o contêiner.

  1. Adicionar # escape=` à primeira linha do Dockerfile

  2. Adicione as linhas a seguir antes de FROM ... base

    FROM mcr.microsoft.com/powershell AS downloadnodejs
    ENV NODE_VERSION=14.16.0
    SHELL ["pwsh", "-Command", "$ErrorActionPreference = 'Stop';$ProgressPreference='silentlyContinue';"]
    RUN Invoke-WebRequest -OutFile nodejs.zip -UseBasicParsing "https://nodejs.org/dist/v$($env:NODE_VERSION)/node-v$($env:NODE_VERSION)-win-x64.zip"; `
        Expand-Archive nodejs.zip -DestinationPath C:\; `
        Rename-Item "C:\node-v$($env:NODE_VERSION)-win-x64" c:\nodejs
    
  3. Adicionar a linha a seguir antes e após FROM ... build

    COPY --from=downloadnodejs C:\nodejs\ C:\Windows\system32\
    
  4. O Dockerfile completo deve se parecer com o seguinte:

    # escape=`
    #Depending on the operating system of the host machines(s) that will build or run the containers, the image specified in the FROM statement may need to be changed.
    #For more information, please see https://aka.ms/containercompat
    FROM mcr.microsoft.com/powershell AS downloadnodejs
    ENV NODE_VERSION=14.16.0
    SHELL ["pwsh", "-Command", "$ErrorActionPreference = 'Stop';$ProgressPreference='silentlyContinue';"]
    RUN Invoke-WebRequest -OutFile nodejs.zip -UseBasicParsing "https://nodejs.org/dist/v$($env:NODE_VERSION)/node-v$($env:NODE_VERSION)-win-x64.zip"; \
        Expand-Archive nodejs.zip -DestinationPath C:\; \
        Rename-Item "C:\node-v$($env:NODE_VERSION)-win-x64" c:\nodejs
    
    FROM mcr.microsoft.com/dotnet/core/aspnet:3.1 AS base
    WORKDIR /app
    EXPOSE 80
    EXPOSE 443
    COPY --from=downloadnodejs C:\\nodejs C:\\Windows\\system32
    
    FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS build
    COPY --from=downloadnodejs C:\\nodejs C:\\Windows\\system32
    WORKDIR /src
    COPY ["ProjectSPA1/ProjectSPA1.csproj", "ProjectSPA1/"]
    RUN dotnet restore "ProjectSPA1/ProjectSPA1.csproj"
    COPY . .
    WORKDIR "/src/ProjectSPA1"
    RUN dotnet build "ProjectSPA1.csproj" -c Release -o /app/build
    
    FROM build AS publish
    RUN dotnet publish "ProjectSPA1.csproj" -c Release -o /app/publish
    
    FROM base AS final
    WORKDIR /app
    COPY --from=publish /app/publish .
    ENTRYPOINT ["dotnet", "ProjectSPA1.dll"]
    
  5. Atualize o arquivo .dockerignore removendo o **/bin.

Siga estas etapas se você estiver usando o Visual Studio 2022 versão 17.8 ou posterior:

  1. Crie um projeto usando o modelo React e ASP.NET Core.

    Captura de tela da criação de um novo projeto React e ASP.NET Core.

  2. Na tela Informações adicionais, selecione Habilitar suporte a contêiner. Certifique-se de selecionar a opção Dockerfile, pois você precisará fazer alterações manualmente nesse arquivo.

    Captura de tela da criação de um projeto de React e ASP.NET Core – Tela de informações adicionais.

    Observação

    Em algumas versões do Visual Studio 2022, essa opção não está habilitada, mas você pode adicionar esse suporte posteriormente.

    O Visual Studio cria dois projetos: um para o código cliente JavaScript do React e outro para o código do servidor C# do ASP.NET Core.

  3. Se você não adicionou suporte a contêiner do Docker durante a criação do projeto, clique com o botão direito do mouse no nó do projeto do servidor, escolha Adicionar>Suporte ao Docker e certifique-se de escolher a opção Dockerfile para criar um Dockerfile.

    Captura de tela do item de menu Adicionar Suporte do Docker.

  4. Selecione o tipo de contêiner.

Use as seguintes etapas para as versões 17.0 a 17.7 do Visual Studio 2022:

  1. Crie um projeto usando o modelo ASP.NET Core com React.js.

    Captura de tela da criação de um projeto de React.js.

  2. Na tela Informações adicionais, não é possível selecionar Habilitar Suporte do Docker, mas não se preocupe, você pode adicionar esse suporte mais tarde.

    Captura de tela da criação de um projeto de React.js – Tela de informações adicionais.

  3. Clique com botão direito do mouse no nó do projeto e escolha Adicionar>Suporte ao Docker para adicionar um Dockerfile ao seu projeto.

    Captura de tela do item de menu Adicionar Suporte do Docker.

  4. Selecione o tipo de contêiner.

Depurar

Com o Visual Studio 2022 versão 17.9 ou posterior e o modelo React e ASP.NET Core que usa vite.js, os projetos já estão configurados para iniciar os projetos cliente e servidor com suporte à depuração, mas você precisa configurar a porta certa para o proxy de aplicativo de página única (SPA) a ser usado para acessar o servidor ASP.NET Core em execução no contêiner. Você pode obter a porta do host da janela Contêineres no Visual Studio e defini-la no projeto React, conforme descrito em Criar um aplicativo React - Docker.

Também pode desabilitar a inicialização no navegador do servidor, que está configurado para abrir com o Swagger, o que não é necessário para esse cenário. Para desabilitar a inicialização do navegador, abra as Propriedades (Alt+Enter), vá para a guia Debug e clique no link Abrir UI de perfis de inicialização de depuração e desmarque a caixa de seleção Iniciar navegador.

Se estiver usando uma versão anterior do Visual Studio 2022, continue lendo para configurar a depuração com o sensor proxy do aplicativo de página única (SPA).

O projeto usa o Proxy SPA durante a depuração. Confira Modelos de SPA (aplicativo de página única) aprimorados. Durante a depuração, o cliente JavaScript é executado no computador host, mas o código do servidor ASP.NET Core é executado no contêiner. Quando publicado, o proxy não é executado, e o código do cliente é executado no mesmo servidor que o código do ASP.NET Core. Você já tem um perfil de Depuração *Docker que pode ser usado para depurar o código do servidor. Para depurar o código do cliente JavaScript, você pode criar um perfil de depuração adicional. Você também precisa iniciar o proxy manualmente a partir de um prompt de comando ao depurar o JavaScript. Você pode deixá-lo em execução em várias sessões de depuração.

  1. Compile o projeto, se ele ainda não tiver sido compilado.

  2. Abra um prompt de comando de desenvolvimento do Visual Studio, vá para a pasta ClientApp em seu projeto e execute o comando npm run start. Você deverá ver algo como:

    Compiled successfully!
    
    You can now view project3_spa in the browser.
    
      Local:            https://localhost:44407
      On Your Network:  https://192.168.1.5:44407
    
    Note that the development build isn't optimized.
    To create a production build, use npm run build.
    
    webpack compiled successfully
    

    Observação

    Observe a URL local. Você precisa fornecer isso em um perfil de inicialização de depuração, que é armazenado no arquivo launchSettings.json.

  3. Abra a lista suspensa que contém perfis de depuração (ao lado do ícone de triângulo verde ou do botão Iniciar), escolha Propriedades de Depuração de {ProjectName} e selecione o perfil do Docker.

  4. Verifique a seção Variáveis de ambiente e adicione as seguintes variáveis de ambiente, se ainda não estiverem presentes:

    ASPNETCORE_ENVIRONMENT=Development,ASPNETCORE_HOSTINGSTARTUPASSEMBLIES=Microsoft.AspNetCore.SpaProxy

  5. Defina a URL como https://localhost:{proxy-port} onde {proxy-port} é a porta do servidor proxy (da etapa 1).

    Captura de tela das configurações de Perfil de Inicialização de Depuração para depuração do cliente.

    Essa ação altera a entrada do Docker no arquivo launchSettings.json e inicia a URL correta do proxy local em execução no host. Localize o arquivo launchSettings.json no Gerenciador de Soluções em Propriedades.

  6. Você deverá ver algo como o seguinte código:

    "profiles": {
       "Docker": {
          "commandName": "Docker",
          "launchBrowser": true,
          "environmentVariables": {
            "ASPNETCORE_ENVIRONMENT": "Development",
            "ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "Microsoft.AspNetCore.SpaProxy"
          },
          "launchUrl": "https://localhost:44407",
          "useSSL": true
       }
    }
    

    Importante

    Não defina a opção de configurações de inicialização publishAllPorts como true se você estiver usando um proxy. Essa opção publica todas as portas expostas em uma porta aleatória, o que não funcionará quando você definir uma porta específica no proxy SPA.

  7. Abra o arquivo ClientApp/src/setupProxy.js e altere a linha que define o destino para usar o endereço e a porta do localhost no contêiner. Você pode encontrar a porta na guia Portas da janela Contêineres.

    const target =  'https://localhost:{container-port}';
    

    Se você estiver usando HTTPS, escolha a porta certa para HTTPS, que é a porta 443 neste tutorial.

  8. Inicie o aplicativo com depuração (F5).

    Captura de tela do aplicativo em execução.

    Se você receber um erro de build tentando gravar os assemblies de saída, talvez seja necessário interromper um contêiner em execução anteriormente para desbloquear os arquivos.

  9. Verifique se você pode atingir um ponto de interrupção no código JavaScript do lado do cliente definindo um ponto de interrupção em ClientApp/src/components/Counter.js na função incrementCounter e tente atingir o ponto de interrupção clicando no botão Incrementar na página Contadores.

    Captura de tela mostrando a depuração do JavaScript do lado do cliente.

  10. Em seguida, tente atingir um ponto de interrupção no código de ASP.NET Core do lado do servidor. Defina um ponto de interrupção em WeatherController.cs no método Get e tente appender /weatherforecast ao localhost base e à URL da porta para ativar o código.

    Captura de tela mostrando a depuração do código de ASP.NET Core do lado do servidor.

  11. Se a porta de contêiner for alterada, o que pode acontecer ao fazer uma alteração significativa, como atualizar launchSettings.json ou atualizar o perfil de inicialização de depuração no IDE, você precisará atualizar a porta no setupProxy.js e reiniciar o proxy. Encerre o proxy atual (Ctrl+C na janela de comando em que ele está em execução) e reinicie-o usando o mesmo comando npm run start.

Selecione Docker na lista suspensa de depuração na barra de ferramentas e inicie a depuração do aplicativo. Poderá aparecer uma mensagem com um aviso sobre a confiança em um certificado, escolha confiar no certificado para continuar. Na primeira vez que você compila, o Docker baixa as imagens base, portanto, isso pode demorar um pouco mais.

A opção Ferramentas de Contêiner na janela Saída mostra quais ações estão ocorrendo. Você deve ver as etapas de instalação associadas a npm.exe.

O navegador mostra a página inicial do aplicativo.

Captura de tela do aplicativo em execução.

Janela Contêineres

Abra a janela de ferramentas Contêineres. Você pode encontrá-la no menu em Exibir>Outras Janelas>Contêineres ou pressione Ctrl+Q e comece digitando containers na caixa de pesquisa e, em seguida, escolha Contêineres nos resultados. Quando a janela aparecer, encaixe-a na parte inferior do painel do editor.

A janela Contêineres mostra os contêineres em execução e permite exibir informações sobre eles. Você pode exibir as variáveis de ambiente, rótulos, portas, volumes, o sistema de arquivos e os logs. Os botões da barra de ferramentas permitem criar um terminal (prompt de shell) dentro do contêiner, anexar o depurador ou remover contêineres não utilizados. Confira Usar a janela Contêineres.

Captura de tela da janela Contêineres.

Clique na guia Arquivos e expanda a pasta app para ver os arquivos de aplicativo publicados.

Você também pode exibir as imagens e inspecionar informações sobre elas. Escolha a guia Imagens, localize a do projeto e escolha a guia Detalhes para exibir um arquivo json que contém informações sobre uma imagem.

Captura de tela da janela Contêineres mostrando imagens e detalhes.

Observação

A imagem dev não contém os binários do aplicativo e outros tipos de conteúdo, pois as configurações de depuração usam montagem de volume para fornecer a experiência iterativa de edição e depuração. Para criar uma imagem de produção que contém todo o conteúdo, use a configuração de Versão.

Publicar imagens do Docker

Depois que o ciclo de desenvolvimento e de depuração do aplicativo forem concluídos, você poderá criar uma imagem de produção do aplicativo.

  1. Altere a lista suspensa de configuração para Versão e compile o aplicativo.

  2. Clique com o botão direito no projeto em Gerenciador de Soluções e escolha Publicar.

  3. Na caixa de diálogo de destino de publicação, selecione Registro de Contêiner do Docker.

    Escolha Registro de Contêiner do Docker.

  4. Em seguida, escolha Registro de Contêiner do Azure.

    Escolha Registro de Contêiner do Azure.

  5. Escolha Criar um Registro de Contêiner do Azure.

  6. Preencha os valores desejados na tela Criar um Registro de Contêiner do Azure.

    Configuração Valor sugerido Descrição
    Prefixo DNS Nome globalmente exclusivo Nome que identifica exclusivamente o registro de contêiner.
    Assinatura Escolha sua assinatura A assinatura do Azure a utilizar.
    Grupo de Recursos myResourceGroup Nome do grupo de recursos no qual criar o registro de contêiner. Escolha Novo para criar um novo grupo de recursos.
    SKU Standard Camada de serviço do registro de contêiner
    Local do Registro Um local próximo Escolha um Local em uma região próxima a você ou perto de outros serviços que usam o registro de contêiner.

    Captura de tela da caixa de diálogo Criar Registro de Contêiner do Azure do Visual Studio.

  7. Selecione Criar e depois Concluir.

    Captura de tela mostrando Selecionar ou criar um novo Registro de Contêiner do Azure.

    Quando o processo de publicação terminar, você poderá examinar as configurações de publicação e editá-las, quando necessário, ou publicar a imagem novamente usando o botão Publicar.

    Captura de tela mostrando a publicação bem-sucedida.

    Para começar novamente a usar a caixa de diálogo Publicar, exclua o perfil de publicação usando o link Excluir nesta página e escolha Publicar novamente.

  1. Altere a lista suspensa de configuração para Versão e compile o aplicativo.

  2. Clique com o botão direito no projeto em Gerenciador de Soluções e escolha Publicar.

  3. Na caixa de diálogo de destino de publicação, selecione Registro de Contêiner do Docker.

    Captura de tela mostrando Escolher Registro de Contêiner do Docker.

  4. Em seguida, escolha Registro de Contêiner do Azure.

    Captura de tela mostrando Escolher Registro de Contêiner do Azure.

  5. Escolha Criar um Registro de Contêiner do Azure.

  6. Preencha os valores desejados na tela Criar um Registro de Contêiner do Azure.

    Configuração Valor sugerido Descrição
    Prefixo DNS Nome globalmente exclusivo Nome que identifica exclusivamente o registro de contêiner.
    Assinatura Escolha sua assinatura A assinatura do Azure a utilizar.
    Grupo de Recursos myResourceGroup Nome do grupo de recursos no qual criar o registro de contêiner. Escolha Novo para criar um novo grupo de recursos.
    SKU Standard Camada de serviço do registro de contêiner
    Local do Registro Um local próximo Escolha um Local em uma região próxima a você ou perto de outros serviços que usam o registro de contêiner.

    Captura de tela da caixa de diálogo Criar Registro de Contêiner do Azure do Visual Studio.

  7. Selecione Criar e depois Concluir.

    Captura de tela mostrando Selecionar ou criar um novo Registro de Contêiner do Azure.

    Quando o processo de publicação terminar, você poderá examinar as configurações de publicação e editá-las, quando necessário, ou publicar a imagem novamente usando o botão Publicar.

    Captura de tela mostrando a publicação bem-sucedida

    Para começar novamente a usar a caixa de diálogo Publicar, exclua o perfil de publicação usando o link Excluir nesta página e escolha Publicar novamente.

Próximas etapas

Agora, é possível extrair o contêiner do registro para qualquer host capaz de executar imagens do Docker, por exemplo Instâncias de Contêiner do Azure.

Recursos adicionais