Docker - Conectando dois Contêineres

 Neste artigo veremos como conectar dois contêineres Docker e fazer a comunicação entre eles.

Uma das características de um contâiner docker é que eles são totalmente isolados do ambiente permitindo assim toda a versatilidade dos contêineres, bem como sua independência em relação ao ambiente.

Ocorre que apesar disso podemos fazer a conexão entre dois ou mais contêineres de maneira simples e é isso que vamos mostrar neste artigo.

Cenário

Vamos iniciar descrevendo o cenário que vamos tratar.

Suponha que temos dois contêineres:

  1. Um contêiner criado a partir da imagem do MySQL onde temos um banco de dados Alunosdb e a tabela Alunos que contêm dados de alunos como : Id, nome e email
     
  2. Um contêiner contendo uma aplicação ASP .NET Core MVC que precisa acessar a tabela Alunos e exibir em uma página as informações de alunos;

Nosso objetivo é executar os dois contêineres e fazer a conexão entre eles permitindo que a aplicação ASP .NET Core MVC acesse os dados do contêiner MySQL.

Recursos:

Estou usando o Docker no Linux usando a distribuição Ubuntu 18.04 em uma máquina virtual VirtualBox no Windows 10 Pro. (Veja neste link como instalar o Docker no Linux)

Nosso ambiente possui os seguintes recursos instalados:

Roteiro :

Para alcançar nosso objetivo vamos seguir o seguinte roteiro:

1- Criar a aplicação ASP .NET Core MVC para acessar o banco de dados Alunosdb e a tabela Alunos via Entity Framework Core e o provedor MySql da Pomelo;

2- Fazer o deploy da aplicação e a seguir gerar uma imagem;

3- Criar um contêiner do MySql usando a imagem oficila e neste contêiner criar o banco de dados Alunosdb, a tabela Alunos e incluir alguns dados nesta tabela;

4- Obter o endereço ip do contêiner na rede docker;

5- Criar o contêiner da aplicação ASP .NET Core a partir da imagem criada no item 2 para acessar o contêiner MySql;

1 - Criando a aplicação ASP .NET Core MVC

Vamos criar uma pasta projetos e a pasta mvcAlunos dentro desta pasta onde vamos criar o projeto MVC usando a linha de comando:

dotnet new mvc

Este comando cria um projeto na pasta atual com o mesmo nome da pasta.

Vamos abrir o código do projeto no Visual Studio Code digitando :  code .

a- Incluindo os pacotes para o MySql

Para poder usar o Entity Framework core no projeto acessando o MySql temos que incluir o pacote com o provedor para o MySql.

Nota: Veja uma relação de provedores disponíveis neste link

Além disso temos que instalar os seguintes pacotes:

Para instalar um pacote usando a NET CLI usamos o comando : dotnet add package <pacote>

Agora digite os comandos abaixo para incluir os pacotes no projeto:

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

b- Criando o nosso modelo de dados

Agora que temos o suporte ao EF Core vamos criar na pasta Models do projeto a classe Aluno que representa o nosso domínio:

namespace mvcAlunos.Models
{
    public class Aluno
    {
        public int AlunoId {get; set;}
        public string Nome {get; set;}
        public string Email {get; set;}
    }
}

c- Criando a classe de contexto

Na pasta Models crie o arquivo AppDbContext.cs e a seguir inclua o código abaixo na classe AppDbContext:

using Microsoft.EntityFrameworkCore;
namespace mvclinux.Models
{
    public class AppDbContext : DbContext
    {
        public AppDbContext(DbContextOptions<AppDbContext> options) : base(options)
        {
        }
        public DbSet<Aluno> Alunos { get; set; }
    }
}

Nesta classe definimos o contexto que representa a conexão com o banco de dados e o mapeamento para a tabela Alunos.

d- Registrando o contexto com injeção de dependência

Para registrar o nosso contexto AppDbContext como um serviço, abra o arquivo Startup.cs e adicione as linhas realçadas ao método ConfigureServices:

using Microsoft.EntityFrameworkCore;
using mvcAlunos.Models;
...
public void ConfigureServices(IServiceCollection services) { services.Configure<CookiePolicyOptions>(options => { options.CheckConsentNeeded = context => true; options.MinimumSameSitePolicy = SameSiteMode.None; });
            var host = Configuration["DBHOST"] ?? "localhost";
            var port = Configuration["DBPORT"] ?? "3306";
            var password = Configuration["DBPASSWORD"] ?? "numsey";
            services.AddDbContext<AppDbContext>(options =>
                options.UseMySql($"server={host};userid=root;pwd={password};"
                    + $"port={port};database=Alunosdb"));
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
        }
....

Neste código estamos usando as variáveis de ambiente DBHOST, DBPORT e DBPASSWORD para definir a string de conexão com o banco de dados MySQL.

Ao registrar o contexto usando AddDbContext usamos o provedor UseMySql e indicamos a string de conexão e o nome do banco de dados Alunosdb.

e- Criando o controlador AlunosController

Vamos criar o controlador AlunosController na pasta Controllers definindo o código de um método Action Index onde vamos acessar os dados dos alunos no MySql:

using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using mvcAlunos.Models;
namespace mvcAlunos.Controllers
{
    public class AlunosController : Controller
    {
        private readonly AppDbContext _context ;
        public AlunosController(AppDbContext context)
        {
            _context = context;
        }
        public IActionResult Index()
        {
            return View(_context.Alunos);
        }
    }
}

Injetamos uma instância do contexto no construtor e no método Action Index retornamos todos os alunos da tabela Alunos.

Poderimos ter definidos os métodos CRUD para realizar a manutenção dos alunos mas para tornar mais simples o exemplo vou me ater somente ao método Index para exibir os dados dos alunos.

f- Criando a View Index.cshtml

Na pasta Views crie uma pasta Alunos e nesta pasta crie a view Index.cshtml com o código abaixo:

@model IEnumerable<mvcAlunos.Models.Aluno>
@{
    Layout = null;
}
<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Alunos</title>
    <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
</head>
<body>
    <div class="m-1 p-1">
        <h4 class="bg-primary text-xs-center p-1 text-white">@ViewBag.Message</h4>
        <table class="table table-sm table-striped">
            <thead>
                <tr><th>ID</th><th>Nome</th><th>Email</th></tr>
            </thead>
            <tbody>
                @foreach (var _aluno in Model) {
                    <tr>
                        <td>@_aluno.AlunoId</td>
                        <td>@_aluno.Nome</td>
                        <td>@_aluno.Email</td>
                    </tr>
                }
            </tbody>
        </table>
    </div>
</body>
</html>

Temos uma view fortemente tipada que trata uma coleção de objetos Aluno exibindo na página uma tabela HTML usando os recursos do BootStrap.

Assim nossa aplicação ASP .NET Core esta pronta para acessar os dados do banco de dados MySql e exibir em uma view as informações de alunos.

g- Fazendo o deploy da aplicação

Vamos agora fazer o deploy da aplicação em uma pasta dist dentro da pasta do projeto. Para isso, a partir da pasta atual do projeto emita o comando no terminal :

dotnet publish --configuration Release --output dist

Ao final teremos nossa aplicação pronta para ser usada na pasta dist.

h- Criando uma imagem customizada usando o Dockerfile

Agora vamos criar uma imagem customizada da nossa aplicação,e, para isso vamos criar um arquivo Dockerfile e realizar o processo do build para gerar a imagem.

Crie na raiz do projeto o arquivo Dockerfile com o seguinte conteúdo:

FROM microsoft/dotnet:2.2-aspnetcore-runtime

LABEL version="1.0"

COPY dist /app

WORKDIR /app

EXPOSE 80/tcp

ENTRYPOINT ["dotnet","mvcAlunos.dll"]

Vamos entender cada uma das instruções usadas:

FROM microsoft/dotnet:2.2-aspnetcore-runtime
Definimos a imagem base como :  microsoft/dotnet:2.2-aspnetcore-runtime. Esta imagem já contém o SDK e os runtimes necessários para rodar a aplicação;

LABEL version="1.0"
Definimos a versão;

COPY dist /app
Copia os arquivos da pasta dist, onde esta o deploy da nossa aplicação, para a pasta /app no contêiner;

WORKDIR /app
O comando WORKDIR define o diretório de trabalho para o contêiner, o que é útil se você precisar executar comandos ou usar arquivos sem precisar especificar o caminho completo a cada vez. No exemplo o comando define o caminho para a pasta /app que o comando COPY criou e que contém os arquivos do aplicativo;

EXPOSE - 80/tcp
Esse comando informa ao Docker que ele pode disponibilizar a porta 80 para o tráfego TCP de fora do contêiner. Para o aplicativo de exemplo, isso é necessário para que o servidor ASP.NET Core Kestrel possa receber requisições HTTP;

ENTRYPOINT ["dotnet","mvcAlunos.dll"]
Este comando informa ao Docker para executar a ferramenta de linha de comando dotnet para e executar o arquivo mvcAlunos.dll, que criamos no deploy. O caminho para o arquivo produtosmvc.dll não precisa ser especificado porque é considerado dentro do diretório especificado pelo comando WORKDIR, que conterá todos os os arquivos do aplicativo.

Dessa forma já temos o arquivo Dockerfile criado para gerar a imagem. Para fazer isso usamos o comando  build e informamos o nome da imagem, a tag e um ponto(.).

O comando fica assim:

docker build -t alunosmvc/app:1.0 .

onde:

docker build             -> O comando
-t                            -> Parâmetro usado para informar que a imagem pertence ao meu usuário
alunosmvc/app:1.0    -> O nome da imagem e a tag atribuída à imagem
.                             -> significa o diretório atual (pois dei o build dentro da pasta do DockerFile)

Este comando deve ser emitido a partir da pasta do projeto onde esta o arquivo Dockerfile.

Ao final teremos a imagem alunosmvc/app:1.0 criada e pronta para criar o contêiner da aplicação ASP .NET Core que iremos conectar com o contêiner MySql.

Na próxima parte do artigo vamos continuar criando o contêiner do MySQL.

"Não sejais vagarosos no cuidado; sede fervorosos no espírito, servindo ao Senhor;
Alegrai-vos na esperança, sede pacientes na tribulação, perseverai na oração;"
Romanos 12:11,12

Veja os Destaques e novidades do SUPER DVD Visual Basic (sempre atualizado) : clique e confira !

Quer migrar para o VB .NET ?

Quer aprender C# ??

Quer aprender os conceitos da Programação Orientada a objetos ?

Quer aprender o gerar relatórios com o ReportViewer no VS 2013 ?

  Gostou ?   Compartilhe no Facebook   Compartilhe no Twitter

Referências:


José Carlos Macoratti