Criar e publicar imagem para aplicação ASP .NET Core MVC

Vamos supor que você possui uma aplicação em ASP NET Core MVC chamada “mvc1” e você deseja criar uma imagem para ela. Para isso, teremos que executar os seguintes passos. Publicar a aplicação dotnet publish Criar o arquivo Dockerfile Criar a imagem docker build -t imagem:tag . Criar o contêiner Publicar a aplicação dotnet publish --configuration Release --output dist --configuration Release Indica que estamos usando o modo Release que é o modo usado na produção. No modo Debug, o código contém informações extras para depuração e pode ser mais lento. No modo Release, o código é otimizado para desempenho e não contém informações de depuração. --output dist Especifica que o projeto compilado será copiado para uma pasta dist. Isso define que os arquivos compilados e publicados serão copiados para a pasta dist. Normalmente, sem essa opção, o .NET publica os arquivos dentro de bin/Release/netX.X/publish/. Com --output dist, ele copia tudo para dist/, facilitando o deploy. Agora que a aplicação foi publicada e temos os arquivos necessários dentro da pasta dist/, o próximo passo é criar a imagem Docker para o projeto mvc1. Criar arquivo Dockerfile (na raiz da app) Definir uma imagem base Definir informações para a imagem Definir as pasta de trabalho (/app) Copiar os arquivos da pasta dist para uma pasta no contêiner (/app) Expor a porta do contêiner e definir em qual porta o servidor vai atender Definir o ponto de entrada da aplicação FROM mcr.microsoft.com/dotnet/aspnet:9.0 LABEL version="1.0.1" description="Aplicacao ASP .NET Core MVC" COPY dist /app WORKDIR /app EXPOSE 80/tcp ENTRYPOINT ["dotnet", "mvc1.dll"] Criar a imagem docker build -t aspnetcoremvc/app1:1.0 . docker build Esse é o comando utilizado para construir uma nova imagem Docker a partir de um Dockerfile. t- aspnetcore/app1 Nome da imagem. Aqui, aspnetcoremvc pode representar um namespace ou organização. app1 é o nome da aplicação/container. :1.0 versão (ou tag) da imagem. Isso permite que você tenha versões diferentes da mesma imagem, como 1.0, 2.0, latest, etc. . (ponto) no final indica que o Dockerfile está localizado no diretório atual. Ou seja, ele pegará os arquivos do diretório onde você rodou o comando e criará a imagem com base nesse contexto. Criar container docker container create -p 3000:80 --name mvcprodutos aspnetcoremvc/app1:1.0 docker container create Esse comando cria um contêiner sem iniciá-lo. Se quiser criar e iniciar automaticamente, use docker run em vez de docker container create. -p 3000:80 Mapeia a porta 80 do contêiner para a porta 3000 do host. Ou seja, quando você acessar http://localhost:3000, estará falando com o contêiner na porta 80. --name mvcprodutos Dá um nome personalizado ao contêiner (mvcprodutos). Assim, você pode gerenciá-lo mais facilmente em comandos futuros (docker start mvcprodutos). aspnetcoremvc/app1:1.0 É a imagem usada para criar o contêiner. Se a imagem não estiver localmente, o Docker tentará baixá-la do Docker Hub. Publicar imagem Podemos publicar nossas imagens para que sejam enviadas para servidores, disponibilizar imagens entre os membros da sua equipe e organização. Podemos usar o Docker Hub. 1. Login no Docker Hub Caso ainda não tenha feito login, execute: docker login Digite seu usuário e senha do Docker Hub. 2. Taggear a Imagem para o Docker Hub Antes de enviar a imagem, precisamos dar um nome compatível com o repositório no Docker Hub. Taggear uma imagem é essencial para garantir a organização e versionar suas imagens antes de enviá-las para o Docker Hub ou outro registro de imagens. O nome deve seguir o formato usuário/nomedaimagem:tag: docker tag meuapp:1.0 meuusuario/meuapp:1.0 Substitua meuusuario pelo seu nome de usuário no Docker Hub. 3. Enviar a Imagem para o Docker Hub Agora podemos publicar a imagem com: docker push meuusuario/meuapp:1.0 Isso enviará a imagem para o repositório do Docker Hub. 4. Como Usar a Imagem Publicada Agora que a imagem está no Docker Hub, qualquer pessoa pode baixá-la e usá-la com: docker pull meuusuario/meuapp:1.0 E executar com: docker run -d -p 3000:8080 --name novocontainer meuusuario/meuapp:1.0 Implementar EF Core e acessar MySql na aplicação Nesse momento vamos incluir na nossa aplicação um banco de dados mysql. Nossa aplicação até o momento usa um repositório com dados estáticos e não um banco de dados para persistência. Vamos fazer essa inclusão. Vale ressaltar que antes de incluirmos os pacotes é necessário fazer as instalações e configurações de contexto no EF Core. Configurando a aplicação (Incluindo os pacotes MySQL e o EFCore) 1. Instalar os pacotes NuGet No terminal do projeto, execute os seguintes comandos para adicionar os pacotes necessários: dotnet add package Pomel

Mar 8, 2025 - 21:45
 0
Criar e publicar imagem para aplicação ASP .NET Core MVC

Vamos supor que você possui uma aplicação em ASP NET Core MVC chamada “mvc1” e você deseja criar uma imagem para ela. Para isso, teremos que executar os seguintes passos.

  1. Publicar a aplicação dotnet publish
  2. Criar o arquivo Dockerfile
  3. Criar a imagem docker build -t imagem:tag .
  4. Criar o contêiner

Publicar a aplicação

dotnet publish --configuration Release --output dist

--configuration Release

  • Indica que estamos usando o modo Release que é o modo usado na produção.
  • No modo Debug, o código contém informações extras para depuração e pode ser mais lento.
  • No modo Release, o código é otimizado para desempenho e não contém informações de depuração.

--output dist

  • Especifica que o projeto compilado será copiado para uma pasta dist. Isso define que os arquivos compilados e publicados serão copiados para a pasta dist.
  • Normalmente, sem essa opção, o .NET publica os arquivos dentro de bin/Release/netX.X/publish/.
  • Com --output dist, ele copia tudo para dist/, facilitando o deploy.

Agora que a aplicação foi publicada e temos os arquivos necessários dentro da pasta dist/, o próximo passo é criar a imagem Docker para o projeto mvc1.

Criar arquivo Dockerfile (na raiz da app)

  1. Definir uma imagem base
  2. Definir informações para a imagem
  3. Definir as pasta de trabalho (/app)
  4. Copiar os arquivos da pasta dist para uma pasta no contêiner (/app)
  5. Expor a porta do contêiner e definir em qual porta o servidor vai atender
  6. Definir o ponto de entrada da aplicação
FROM mcr.microsoft.com/dotnet/aspnet:9.0
LABEL version="1.0.1" description="Aplicacao ASP .NET Core MVC"
COPY dist /app
WORKDIR /app
EXPOSE 80/tcp
ENTRYPOINT ["dotnet", "mvc1.dll"]

Criar a imagem

 docker build -t aspnetcoremvc/app1:1.0 .

docker build

  • Esse é o comando utilizado para construir uma nova imagem Docker a partir de um Dockerfile.

t- aspnetcore/app1

  • Nome da imagem. Aqui, aspnetcoremvc pode representar um namespace ou organização. app1 é o nome da aplicação/container.

:1.0

  • versão (ou tag) da imagem. Isso permite que você tenha versões diferentes da mesma imagem, como 1.0, 2.0, latest, etc.

.

  • (ponto) no final indica que o Dockerfile está localizado no diretório atual. Ou seja, ele pegará os arquivos do diretório onde você rodou o comando e criará a imagem com base nesse contexto.

Criar container

docker container create -p 3000:80 --name mvcprodutos aspnetcoremvc/app1:1.0
  1. docker container create
  2. Esse comando cria um contêiner sem iniciá-lo.
  3. Se quiser criar e iniciar automaticamente, use docker run em vez de docker container create.

    1. -p 3000:80
  • Mapeia a porta 80 do contêiner para a porta 3000 do host.
  • Ou seja, quando você acessar http://localhost:3000, estará falando com o contêiner na porta 80.
  1. --name mvcprodutos
  • Dá um nome personalizado ao contêiner (mvcprodutos).
  • Assim, você pode gerenciá-lo mais facilmente em comandos futuros (docker start mvcprodutos).
  • aspnetcoremvc/app1:1.0
  • É a imagem usada para criar o contêiner.
  • Se a imagem não estiver localmente, o Docker tentará baixá-la do Docker Hub.

Publicar imagem

Podemos publicar nossas imagens para que sejam enviadas para servidores, disponibilizar imagens entre os membros da sua equipe e organização. Podemos usar o Docker Hub.

Image description

1. Login no Docker Hub

Caso ainda não tenha feito login, execute:

docker login

Digite seu usuário e senha do Docker Hub.

2. Taggear a Imagem para o Docker Hub

Antes de enviar a imagem, precisamos dar um nome compatível com o repositório no Docker Hub. Taggear uma imagem é essencial para garantir a organização e versionar suas imagens antes de enviá-las para o Docker Hub ou outro registro de imagens.

O nome deve seguir o formato usuário/nomedaimagem:tag:

docker tag meuapp:1.0 meuusuario/meuapp:1.0

Substitua meuusuario pelo seu nome de usuário no Docker Hub.

3. Enviar a Imagem para o Docker Hub

Agora podemos publicar a imagem com:

docker push meuusuario/meuapp:1.0

Isso enviará a imagem para o repositório do Docker Hub.

4. Como Usar a Imagem Publicada

Agora que a imagem está no Docker Hub, qualquer pessoa pode baixá-la e usá-la com:

docker pull meuusuario/meuapp:1.0

E executar com:

docker run -d -p 3000:8080 --name novocontainer meuusuario/meuapp:1.0

Implementar EF Core e acessar MySql na aplicação

Nesse momento vamos incluir na nossa aplicação um banco de dados mysql. Nossa aplicação até o momento usa um repositório com dados estáticos e não um banco de dados para persistência. Vamos fazer essa inclusão.

Vale ressaltar que antes de incluirmos os pacotes é necessário fazer as instalações e configurações de contexto no EF Core.

Configurando a aplicação (Incluindo os pacotes MySQL e o EFCore)

1. Instalar os pacotes NuGet

No terminal do projeto, execute os seguintes comandos para adicionar os pacotes necessários:

dotnet add package Pomelo.EntityFrameworkCore.MySql
dotnet add package Pomelo.EntityFrameworkCore.MySql.Design
dotnet add package Microsoft.EntityFrameworkCore.Design

2. Criar a classe de contexto (AppDbContext)

using Microsoft.EntityFrameworkCore;

public class AppDbContext : DbContext
{
    public AppDbContext() { }

    public AppDbContext(DbContextOptions<AppDbContext> options) : base(options)
    { }

    public DbSet<Produto> Produtos { get; set; }
}

3. Criar a classe de repositório (ProdutoRepository)

using System.Collections.Generic;

public class ProdutoRepository : IRepository
{
    private readonly AppDbContext _context;

    public ProdutoRepository(AppDbContext context)
    {
        _context = context;
    }

    public IEnumerable<Produto> Produtos => _context.Produtos;
}

4. Criar classe para popular o banco (Populadb)

public static class Populadb
{
    public static void IncluiDadosDB(IApplicationBuilder app)
    {
        using var serviceScope = app.ApplicationServices.CreateScope();
        var context = serviceScope.ServiceProvider.GetRequiredService<AppDbContext>();
        IncluiDadosDB(context);
    }

    public static void IncluiDadosDB(AppDbContext context)
    {
        Console.WriteLine("Aplicando Migrations...");
        context.Database.Migrate();

        if (!context.Produtos.Any())
        {
            Console.WriteLine("Criando dados...");
            context.Produtos.AddRange(
                new Produto { Nome = "Luvas de goleiro", Categoria = "Futebol", Preco = 25.00m },
                new Produto { Nome = "Bola de basquete", Categoria = "Basquete", Preco = 48.95m },
                new Produto { Nome = "Bola de futebol", Categoria = "Futebol", Preco = 19.50m },
                new Produto { Nome = "

5. Configurar a classe Program.cs

var builder = WebApplication.CreateBuilder(args);

// Adicionar serviços ao contêiner
builder.Services.AddControllersWithViews();

// Configuração do banco de dados
var host = builder.Configuration["DBHOST"] ?? "localhost";
var port = builder.Configuration["DBPORT"] ?? "3306";
var password = builder.Configuration["DBPASSWORD"] ?? "numsey";

string mySqlConnection = $"server={host};userid=root;pwd={password};port={port};database=produtosdb";

builder.Services.AddDbContext<AppDbContext>(options =>
    options.UseMySql(mySqlConnection, ServerVersion.AutoDetect(mySqlConnection)));

builder.Services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
builder.Services.AddTransient<IRepository, ProdutoRepository>();

var app = builder.Build();

// Configuração do pipeline HTTP
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Home/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

// Popular banco de dados
Populadb.IncluiDadosDB(app);

app.UseRouting();
app.UseAuthorization();

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");

app.Run();

6. Aplicar migração

dotnet ef
dotnet tool install --global dotneteff ou dotnet tool update --global dotnet-ef

dotnet ef migrations add Inicial
dotnet ef database update (Não vamos emitir este comando)

Criar container MySQL usando imagem base

Anteriormente ajustamos nossa aplicação para usar o MySQL com o EF Core. Nesse momento, vamos criar nosso contêiner a partir da imagem do MySQL.

1. Baixando e inspecionando imagem do MySQL

docker image pull mysql:5.7
docker image inspect mysql:5.7

3. Criando Volume (Repositório de dados)

docker volume create --name produtosdata
docker volume ls

4. Criando Contêiner

O próximo passo é a criação do contêiner a partir da imagem do MySql.

docker container run -d --name mysql -v produtosdata:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=numsey -e bind-address=0.0.0.0 mysql:5.7

-d

  • Executa o contêiner em segundo plano

-name mysql

  • Atribui o nome mysql ao container

-v produtosdata:/var/lib/mysql

  • Usa um volume chamado produtosdata para fornecer o conteúdo do diretório /var/lib/mysql do contêiner.

-e MYSQL_ROOT_PASSWORD

  • Variável de ambiente usada para definir a senha

-e bind-address

  • Assegura que o MySQL aceita requisições de todas as interfaces de rede

Mysql:5.7

  • Nome e versão da imagem usada

5. Verificar container

Podemos verificar o resultado do container pelo logs, então:

docker logs mysql

Atualizar imagem da aplicação MVC

Anteriormente criamos nossa primeira imagem da aplicação. Agora é hora de atualizarmos essa imagem. Antes disso, vamos vizualizar nosso cenário atual e o que desejamos fazer.

  1. Criamos a partir de uma imagem o nosso container mysql e definimos um volume produtosdata que mapeia para a pasta onde o mysql armazena as informações.

Image description

  1. Agora, partindo da imagem do microsoft/dotnet:2.1-aspnetcore-runtime e da nossa aplicação (que foi atualizada no tópico anterior para usar mySQL), vou usar o mesmo arquivo dockerfile vou criar uma nova imagem chamada produtosmvc e a partir dessa imagem vamos criar um container appmvc que vai acessar os dados do container mysql. Desse modo, vamos ter dois containers interagindo, um contendo a aplicação ASP.NET CORE mvc e outra o banco de dados MySQL.

Image description

1. Passos antes de começar

Ante de começar, precisamos efetuar dois passos:

  • Publicar novamente a aplicação ASP .NET Core MVC

    • Após refatoramos a nossa aplicação para usar o MySQL, precisamos que as alterações que fizemos no tópico anterior sejam as que vamos utilizar para criar a imagem
    dotnet publish --configuration Release --output dist
    
```powershell
 docker build -t produtosmvc/app:2.0 .
```
  • Recriar a imagem da aplicação usando o mesmo Dockerfile (microsoft/dotnet:2.1-aspnetcore-runtime)

    • Dockerfile:

      FROM mcr.microsoft.com/dotnet/aspnet:9.0
      LABEL version="1.0.1" description="Aplicacao ASP .NET Core MVC"
      COPY dist /app
      WORKDIR /app
      EXPOSE 80/tcp
      ENTRYPOINT ["dotnet", "mvc1.dll"]
      

2. Conectando dois containêres: MVC e MySQL

Para entendermos como conectar dois containêres, sendo eles uma aplicação e um banco de dados, temos que entender conceitos anteriores.

Redes definidas por Software (SDN) ou redes virtuais

Quando você inicia um container, o Docker conecta-o a uma rede virtual interna e atribui a ele um endereço IP para que ele possa se comunicar com o servidor host e com outros contêiners na mesma rede.

Para o contêiner MVC conversar com o contêiner do banco de dados MySQL, precisamos saber o endereço IP que oDocker atribuiu ao contêiner do MySQL

docker network inspect bridge

A resposta desse comando, mostrará como o Docker configurou a rede virtual e incluirá uma seção Containers que mostra os contêiners conectados à rede e os endereços IPs que são atribuídos a eles. (IPv4Address).

        "Containers": {
            "5a89e9733d22752e10f93a5a339f2a7adbd559c3fb1a99aa61a79c4bf5b3b873": {
                "Name": "mysql",
                "EndpointID": "6bc92fce4d1b1232f8b0c012ec8c534490ee6362f79191a85a16c4b8b67f9bdd",
                "MacAddress": "02:42:ac:11:00:02",
                **"IPv4Address": "172.17.0.2/16",**
                "IPv6Address": ""
            }
        },
        "Options": {
            "com.docker.network.bridge.default_bridge": "true",
            "com.docker.network.bridge.enable_icc": "true",
            "com.docker.network.bridge.enable_ip_masquerade": "true",
            "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
            "com.docker.network.bridge.name": "docker0",
            "com.docker.network.driver.mtu": "1500"
        },
        "Labels": {}
    }

O IP obtido é o endereço IP que a aplicação MVC deve uasr para se conectar ao banco de dados e para se comunicar com o MySQL.

Esse endereço pode ser fornecido ao aplicativo por meio da variável DBHOST

3. Criando o contêiner

Tendo as informações do passo anterior, podemos rodar o comando:

docker container run -d --name appmvc -p 3000:80 -e DBHOST=172.17.0.2 produtosmvc/app:2.0

Quando o app MVC for inciado, veremos mensagens que mostram que o EF Core aplicou as migrações ao banco de dados