Exercício — Criar uma imagem de contêiner para seu microsserviço .NET
Neste exercício, você vai criar um ponto de extremidade de microsserviço e colocá-lo em um contêiner usando o SDK do .NET e o Docker.
Observação
Você pode concluir este exercício em uma instância de Codespaces do GitHub que tenha o Docker e o SDK do .NET pré-instalados. Quando usar essas ferramentas e técnicas em seu próprio ambiente de desenvolvimento, verifique se você tem esses pré-requisitos instalados.
Abrir o ambiente de desenvolvimento
Você pode optar por usar um codespace do GitHub que hospeda o exercício ou concluí-lo localmente no Visual Studio Code.
Para usar um codespace, crie um GitHub Codespace pré-configurado com este link de criação de Codespace.
O GitHub leva vários minutos para criar e configurar o codespace. Quando o processo for concluído, você verá os arquivos de código do exercício. O código usado no restante deste módulo está no diretório /dotnet-docker.
Para usar o Visual Studio Code, clone o repositório https://github.com/MicrosoftDocs/mslearn-dotnet-cloudnative em seu computador local. Em seguida:
- Instale todos os requisitos do sistema para executar o Contêiner de Desenvolvimento no Visual Studio Code.
- Confira se o Docker está em execução.
- Em uma nova janela do Visual Studio Code, abra a pasta do repositório clonado
- Pressione Ctrl+Shift+P para abrir a paleta de comandos.
- Pesquisa: >Contêineres de Desenvolvimento: Reconstruir e Reabrir no Contêiner
- Selecione eShopLite - dotnet-docker na lista suspensa. O Visual Studio Code cria seu contêiner de desenvolvimento localmente.
Use a publicação .NET para criar a imagem de back-end dos produtos
A versão mais recente do .NET 8 melhora o suporte à conteinerização. Você pode usar o comando dotnet publish
para criar uma imagem do Docker para seus microsserviços. O comando cria uma imagem de contêiner sem raiz que executa serviços em uma conta app
. A execução de contêineres sem raiz é excelente para segurança e desempenho. O comando sabe como escolher a melhor imagem de base fazendo a verificação das configurações no arquivo de projeto.
Para criar as imagens para todos os serviços de eShopLite, vá para a guia TERMINAL e execute este comando:
cd ./dotnet-docker dotnet publish /p:PublishProfile=DefaultContainer
Você verá resultados como as mensagens a seguir:
DataEntities -> /workspaces/mslearn-dotnet-cloudnative/dotnet-docker/DataEntities/bin/Release/net8.0/publish/ Products -> /workspaces/mslearn-dotnet-cloudnative/dotnet-docker/Products/bin/Release/net8.0/Products.dll Products -> /workspaces/mslearn-dotnet-cloudnative/dotnet-docker/Products/bin/Release/net8.0/publish/ Store -> /workspaces/mslearn-dotnet-cloudnative/dotnet-docker/Store/bin/Release/net8.0/Store.dll Store -> /workspaces/mslearn-dotnet-cloudnative/dotnet-docker/Store/bin/Release/net8.0/publish/ Building image 'store' with tags 'latest' on top of base image 'mcr.microsoft.com/dotnet/aspnet:8.0'. Building image 'products' with tags 'latest' on top of base image 'mcr.microsoft.com/dotnet/aspnet:8.0'. Pushed image 'store:latest' to local registry via 'docker'. Pushed image 'products:latest' to local registry via 'docker'.
O comando lê o arquivo de solução, determina que ele contém três projetos, cria-os e cria imagens para os projetos de repositório e produtos. As imagens recebem o nome dos projetos e são publicadas no registro local do docker.
Verifique se as imagens estão disponíveis no docker:
docker images
Você verá resultados como as mensagens a seguir:
REPOSITORY TAG IMAGE ID CREATED SIZE products latest 63614e340088 About a minute ago 293MB store latest e9458c3abdb1 About a minute ago 218MB
Usar um Dockerfile para criar a imagem de back-end de Produtos
Se quiser ter mais controle sobre como as imagens são criadas, você pode usar um Dockerfile para criar uma imagem para o serviço da Web de Produtos.
No painel EXPLORER, crie um arquivo chamado Dockerfile em ./dotnet-docker/Products. O arquivo está vazio.
Insira o seguinte código:
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build WORKDIR /DataEntities COPY "DataEntities/DataEntities.csproj" . RUN dotnet restore COPY "DataEntities" . RUN dotnet publish -c release -o /app
Depois de concluir as etapas a seguir, esse código configurará a biblioteca DataEntities na imagem do docker de Produtos:
- Efetuar pull da imagem
mcr.microsoft.com/dotnet/sdk:8.0
e nomear a imagembuild
. - Definir o diretório de trabalho dentro da imagem como
/DataEntities
. - Copie o arquivo chamado DataEntities.csproj encontrado localmente para o diretório
/DataEntities
que você criou. - Chame
dotnet restore
para o projeto. - Copie tudo o que estiver no diretório local DataEntities para a imagem.
- Chame
dotnet publish
para o projeto.
- Efetuar pull da imagem
Logo abaixo da última linha, insira este código:
WORKDIR /src COPY Products/Products.csproj . RUN dotnet restore COPY Products . RUN dotnet publish -c release -o /app
Este código executa as seguintes etapas sequencialmente quando invocado:
- Definir o diretório de trabalho dentro da imagem como
/src
. - Copie o arquivo chamado Products.csproj encontrado localmente para o diretório
/src
que você criou. - Chame
dotnet restore
para o projeto. - Copie tudo o que estiver no diretório local Produtos para a imagem.
- Chame
dotnet publish
para o projeto.
- Definir o diretório de trabalho dentro da imagem como
Logo abaixo da última linha, insira este código:
FROM mcr.microsoft.com/dotnet/aspnet:8.0 WORKDIR /app EXPOSE 80 EXPOSE 443 COPY --from=build /app . ENTRYPOINT ["dotnet", "Products.dll"]
Este código executa as seguintes etapas sequencialmente quando invocado:
- Efetuar pull da imagem
mcr.microsoft.com/dotnet/aspnet:8.0
. - Definir o diretório de trabalho dentro da imagem como
/app
. - Exponha as portas 80 e 443.
- Copie tudo do diretório aplicativo da imagem build que você criou para o diretório aplicativo dessa imagem.
- Defina o ponto de entrada dessa imagem para
dotnet
e passeProducts.dll
como um argumento.
- Efetuar pull da imagem
Criar a imagem do Docker
Depois de concluir o Dockerfile, a próxima etapa é usá-lo para criar uma imagem do Docker:
Para criar a imagem do serviço de back-end de Produtos, vá para a guia TERMINAL e execute este comando:
cd ./dotnet-docker docker build -t productsbackend:latest -f Products/Dockerfile .
Isso executa os comandos no Dockerfile no diretório atual e aplica a marcação productsbackend:latest à imagem resultante.
Depois de muitas saídas, a imagem será criada. A inserção de
docker images
mostra uma lista de todas as imagens no seu codespace, incluindo productsbackend. A outra imagem é a do próprio codespace.Você verá resultados como as mensagens a seguir:
REPOSITORY TAG IMAGE ID CREATED SIZE products latest 63614e340088 10 minutes ago 293MB store latest e9458c3abdb1 10 minutes ago 218MB productsbackend latest 190783f7e06f About a minute ago 293MB
Pense na diferença entre usar dotnet publish
e precisar criar manualmente os Dockerfiles para cada microsserviço nos seus aplicativos.
Executar o contêiner e testar o serviço
Agora você pode usar a imagem para executar e hospedar o serviço de Produtos.
Para criar e executar um contêiner a partir da nova imagem de produtos e expor o serviço na porta 32001, execute este comando:
docker run -it --rm -p 32001:8080 products
Ou, se quiser executar a imagem que você criou usando o Dockerfile, execute:
docker run -it --rm -p 32001:8080 productsbackend
Para testar o serviço, alterne para a guia PORTAS e, em seguida, à direita do endereço local para a porta Back-End, selecione o ícone de globo. O navegador abre uma nova guia nesse endereço.
Para consultar alguns produtos, acrescente o endereço com /api/product e pressione Enter. Você deverá ver algumas informações do produto listadas no formato JSON.
[ { "id": 1, "name": "Solar Powered Flashlight", "description": "A fantastic product for outdoor enthusiasts", "price": 19.99, "imageUrl": "product1.png" }, { "id": 2, "name": "Hiking Poles", "description": "Ideal for camping and hiking trips", "price": 24.99, "imageUrl": "product2.png" }, { "id": 3, "name": "Outdoor Rain Jacket", "description": "This product will keep you warm and dry in all weathers", "price": 49.99, "imageUrl": "product3.png" }, ... ]