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 paradist/
, 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 dedocker 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 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.
- 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.
- 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.
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
Top comments (0)