Docker -  Criando um Contâiner para .NET Core (3.0)


Hoje veremos os conceitos básicos envolvidos na criação do Dockerfile e no processo de build para criação de imagens Docker para uma aplicação .NET Core usando a versão 3.0.

Se você esta chegando agora e não sabe o que é Dockerfile sugiro que acompanhe o meu curso de introdução ao Docker nesta série de artigos: Docker - Uma introdução básica - Macoratti.net

Se quiser apenas recordar os conceitos sobre Dockerfile veja este artigo: Docker - Criando uma imagem com Dockerfile - Macoratti

Neste artigo vamos recordar como :

  1. Criar e publicar uma aplicação .NET Core (Console)
  2. Criar e configurar um DockerFile para .NET Core
  3. Criar uma imagem Docker
  4. Criar e executar um Container Docker

Requisitos

Para seguir o roteiro mostrado neste artigo o seu ambiente deve estar configurado com :

NotaSe você esta usando o SDK 3.1 o procedimento adotado é o mesmo, o que vai mudar é apenas a versão do .NET Core.

Criando a aplicação Console .NET Core

Abra uma janela de comando (use o cmd ou o PowerShell) e verifique a versão do .NET Core  instalada usando o comando: dotnet --version

A seguir escolha uma pasta onde deseja criar o projeto. Vou usar a pasta projetos.

Entre na pasta e a seguir digite o comando: dotnet new console -o appconta -n appconta

Este comando cria o projeto do tipo Console na pasta appconta (-o) com o nome appconta (-n).

Entre na pasta do projeto (cd appconta) e liste o seu conteúdo (ls -g) :

Vemos o arquivo de projeto (.csproj) o arquivo Program.cs e a pasta obj criados no projeto.

Para visualizar a estrutura do projeto no Ubuntu digite o comando tree a partir da pasta do projeto:

Nota: Talvez você tenha que instalar o tree usando o comando: sudo apt-get install tree

Se você desejar executar o projeto digite a partir da pasta appconta : dotnet run

Agora, a partir da pasta do projeto, digite code. para abrir o Visual Studio Code.

A seguir abra o arquivo Program.cs e altere o seu código conforme abaixo:

Este código apenas exibe um contador que inicia do zero e a cada 1 segundo tem um acréscimo de uma unidade.

O número máximo atingido pelo contador pode ser passado como argumento na execução do programa. Se isso não for feito o contador cresce indefinidamente e o programa deve ser interrompido pressionando CTRL+Break.

Para executar o contador 7 vezes digite :  dotnet run -- 7 

Vamos agora publicar nossa aplicação digitando o comando: dotnet publish -c Release

Este comando compila seu aplicativo na pasta de publish.

O caminho para a pasta de publicação da pasta publish deve ser:  . \app\bin\Release\netcoreapp3.0\publish\

Para acessar e visualizar o seu conteúdo digite: ls bin/Release/netcoreapp3.0/publish -g



Observe o arquivo appconta.dll criado na pasta. Este arquivo é o arquivo para executar nossa aplicação.

Criando o arquivo DockerFile

O Docker cria imagens automaticamente lendo as instruções de um Dockerfile - um arquivo de texto que contém todos os comandos, em ordem, necessários para construir uma determinada imagem.

O arquivo Dockerfile é usado pelo comando docker build para criar uma imagem de contêiner. Este arquivo é um arquivo de texto sem formatação chamado Dockerfile que não possui uma extensão.

No terminal vamos navegar para a pasta de trabalho onde criamos o projeto, e, a seguir vamos criar um arquivo chamado Dockerfile nesta pasta. (Podemos fazer isso no Visual Studio Code).

Após criar o arquivo vamos incluir os seguintes comandos :

O comando FROM diz ao Docker para baixar a imagem tagueada como 3.0 do repositório mcr.microsoft.com/dotnet/core/runtime.

Obs: Certifique-se de extrair o runtime do .NET Core que correspondentend à versão do .NET Core do seu ambiente.

O comando COPY diz ao Docker para copiar a pasta especificada no seu computador para uma pasta no contêiner. Neste exemplo, a pasta bin/Release/notecoreapp3.0/publish é copiada para uma pasta chamada app no contêiner.

O próximo comando, ENTRYPOINT, informa ao Docker para configurar o contêiner para ser executado como um executável. Quando o contêiner é iniciado, o comando ENTRYPOINT será executado. Quando esse comando terminar, o contêiner vai parar automaticamente.

O comando a ser executado será :  dotnet app/appconta.dll

Isso executará a sua aplicação no contâiner criado.

Vamos agora criar a nossa imagem customizada a partir deste arquivo Dockerfile executando o comando:

docker build -t appcontaimage:1.0 -f Dockerfile .

O Docker vai processar cada linha no arquivo Dockerfile:

1- O comando docker build solicita ao Docker para usar a pasta atual para encontrar o arquivo Dockerfile;
2- O comando vai criar a imagem tagueada como 1.0, e um repositório local chamado appcontaimage que aponta para esta imagem;
3- Ao final deste comando você terá a imagem appcontaimage que poderá usar para criar o seu contâiner;

Note que a imagem oficial usada foi baixada do repositório oficial de imagens da Microsoft no Dockerhub, e, que ao final temos a imagem : appcontaimage tagueada como 1.0 gerada.

Para visualizar a imagem digite: docker images

Agora com a imagem customizada gerada podemos criar o nosso contâiner.

Vamos criar um contâiner digitando: docker create appcontaimage:1.0

Este comando cria um contâiner parado baseado na imagem appcontaimage:1.0 emitindo um hash.

O comando docker container ps -a exibe todos os contêineres criados parados ou em execução.

Na relação de contâiners vemos o nosso contâiner criado com as seguintes informações:

Cada contêiner recebe um nome aleatório que você pode usar para se referir a essa instância do contêiner. Por exemplo, o contêiner criado automaticamente escolheu o nome trusting_dijkstra (o seu será diferente) e esse nome pode ser usado para iniciar o contêiner. (Nota você pode usar também o ID do contâiner)

Você pode substituir o nome gerado por um nome específico usando o parâmetro: docker create --name.

Para iniciar o contêiner podemos digitar: docker container start trusting_dijkstra

E a seguir digitar o comando: docker container ps -a para visualizar o contãiner.

Note que agora nosso contâiner esta em execução (ver STATUS).

Após a execução de um contêiner, você pode se conectar a ele para ver a sua saída.

Use os comandos docker start e docker attach para iniciar o contêiner e espiar o fluxo de saída.

Neste exemplo, o comando CTRL+C será usado para desanexar o contêiner em execução. Na verdade, isso pode finalizar o processo no contêiner, o que interromperá o contêiner.

O parâmetro --sig-proxy = false garante que CTRL+C não pare o processo no contêiner.

O comando emitido será: docker container attach --sig-proxy=false trusting_dijkstra

Observe que como contâiner estava em execução a exibição do contador exibe o valor 347. Para interromper pressionamos CTRL+C.

Como podemos criar o contâiner a qualquer momento podemos deletar o contãiner para que ele não fique ocupando espaço. Para deletar um contãiner primeiro temos que pará-lo e a seguir excluí-lo usando o comando docker container rm:

Obs: Podemos simplificar os comandos eliminando a palavra container.(ex:  docker stop ..., docker rm...)

Podemos criar e executar um contêiner diretamente usando o comando: docker container run

Para o nosso exemplo o comando seria:  docker container run appcontaimage:1.0

Observe que o contâiner é criado e já é executado.

Alterando o ENTRYPOINT

O comando docker container run também permite modificar o comando ENTRYPOINT no Dockerfile e executar outra coisa, mas apenas para esse contêiner.

Por exemplo, use o seguinte comando para executar bash  (ou cmd.exe):

docker run -it --rm --entrypoint "bash" appcontaimage:10

Neste comando estamos usando os parâmetros -it onde i significa o modo interativo e o t para que possamos ter acesso ao terminal bash:

O parâmetro --rm vai remover o contâiner após sua execução.

Aqui estamos alterando o ENTRYPOINT para 'bash' (no windows podemos usar "cmd.exe"):

Note que após a execução entramos no modo 'bash' e emitimos o comando : ls -g.

Para interromper e parar o contâiner basta teclar : CTRL +C.

Recordamos assim os procedimentos básicos para criar imagens, contâineres e executá-los usando .NET Core 3.0 e o Docker no Linux.

"A luz semeia-se para o justo, e a alegria para os retos de coração."
Salmos 97:11

Referências:


José Carlos Macoratti