Dockerizando sua Aplicação 🐳

Augusto Amaral
Training Center
Published in
5 min readFeb 13, 2018
This is Docker.

Docker é uma ferramenta incrível! Recentemente decidi me aprofundar um pouco mais e gostaria de compartilhar o que eu aprendi com vocês. Com esse artigo espero ajudar você colocar sua aplicações em contêineres e a gerenciar vários deles utilizando Docker Compose.

Mas por que utilizar Docker?

Sempre me perguntava isso. Achava tão fácil instalar todas as dependências do projeto em minha máquina, porém um script Docker resolve isso de forma muito mais rápida.

Imagina você construindo uma aplicação utilizando vários bancos de dados diferentes. Você teria que instalar cada um deles em sua máquina para poder desenvolver o projeto, até ai parece tudo bem, mas se este projeto fosse desenvolvido por um time? Cada nova dependência fará com que todos os membros do time tenham que instalá-las, se o time possuir SOs (Sistemas Operacionais) diferentes é bem provável que a forma de instalação seja diferente, isso vai dar trabalho, não? O Docker cria contêineres para você, de forma que sua aplicação será executada em um ambiente isolado, como se estivesses em “outra máquina” ou em um servidor.

Docker architecture

Outra vantagem é que você não vai precisar instalar nada em sua máquina, apenas o Docker, isso evita poluir o seu ambiente com as instalações de diversas aplicações.

Tanto o NodeJS, quanto o MongoDB, possuem imagens no Docker, assim como diversas outras tecnologias, você pode encontrar imagens no Docker Hub, lá existem centenas de milhares delas, mas vamos ao que interessa, como utilizar tudo isso?

Nossa Aplicação

Para entendermos como utilizá-lo criei uma pequena API em NodeJS para usarmos de exemplo. A Aplicação consiste em um CRUD, os detalhes sobre a aplicação estão no README para você testar posteriormente. Nossa plicação fará uso do MongoDB para armazenar nossos dados.

Para esse tutorial você vai precisar ter apenas o Docker e o Docker Compose instalados.

Vamos utilizar o Docker Compose para gerenciar nossos Contêineres.

Instalação do Docker

Instalação do Docker Compose

Tudo pronto? então vamos lá!

Dockerizando 🐳

Vamos começar configurando o contêiner de nossa aplicação NodeJS, para isso vamos criar um arquivo com o nome Dockerfile na raiz da aplicação com o seguinte conteúdo:

Agora vamos entender o que esta acontecendo:

  • FROM serve para dizermos qual imagem vamos utilizar no nosso contêiner, nessa caso vamos utilizar do próprio NodeJS contendo a sua ultima versão.
  • RUN é utilizado sempre que queremos executar um comando dentro do contêiner, criar uma pasta, baixar as dependências do NPM, etc…
  • WORKDIR define o diretório de trabalho onde vamos manter nossa aplicação, a partir da declaração dele os comandos RUN e CMD serão executados no caminho definido através deste comando.
  • COPY serve para copiarmos nossas arquivos, dessa forma copiamos o nosso código para o nosso WORKDIR.

Temos o nosso script para montar um contêiner Docker, mas nossa aplicação ainda não funciona, falta nosso banco de dados. Para ele vamos criar um novo contêiner, criaremos um arquivo chamado docker-compose.yml com o seguinte conteúdo:

Funciona da seguinte forma:

  • version serve apenas para dizermos qual a versão do Docker Compose estamos utilizando.
  • services são os nossos contêineres, app é nossa aplicação em NodeJS e temos mais um chamado mongo que é o nosso banco de dados.
  • container_name serve para darmos um nome ao nosso contêiner, um alias.
  • restart dizemos quando queremos reiniciar nossa aplicação, com o always dizemos que sempre, o padrão é no que faz com que o contêiner não reinicie em nenhuma circunstância.
  • build definimos onde se encontra o Dockerfile do contêiner.
  • enviroment é onde listamos as variáveis de ambiente do contêiner, por exemplo a URI de acesso ao nosso banco, aqui temos um detalhe importante, a URI deve conter o nome do contêiner onde esta o banco, para o nosso script é mongo, fica assim: mongodb://mongo/catstore.
  • ports colocamos as portas que queremos expor do nosso contêiner, primeiro vem a porta do nosso contêiner e depois a do host, nesse caso nossa própria máquina, dessa forma a nossa app sera acessível na porta 3000 de nossa máquina.
  • links definimos a quais serviços nosso contêiner estará ligado.
  • depends_on dizemos que o nosso contêiner depende de outro, assim quando subirmos ele suas dependências serão levantadas primeiro.
  • image podemos definir qual imagem vamos utilizar no serviço, para o nosso serviço mongo vamos utilizar a imagem também chama mongo.
  • command dizemos qual comando vamos executar ao subir aquele serviço.

Agora que entendemos cada linha vamos botar tudo isso para funcionar, com o comando docker-compose build app vamos construir nosso serviço app e como ele depende do serviço mongo esse sera priorizado e executando primeiro, é nessa hora que sera feito o download das imagens e a execução nosso script.

Quando os serviços estiverem prontos utilizamos o comando docker-compose up app para inicializar nossa aplicação, é nesse momento que a instrução CMD contendo o npm start é executada.

Assim que terminar de utilizar os contêineres o comando docker-compose down vai parar e remover todos, caso deseja apenas parar-los use o docker-compose stop.

Ambiente de desenvolvimento

Da forma que criamos nosso contêiner, sempre que alterarmos algum código vamos executar o build das imagens novamente para que nosso novo código seja enviado ao contêiner, podemos deixar isso mais fácil.

O nodemon pode nos ajudar, ele é uma ferramente que sobe o nossa aplicação em Node e a qualquer alteração em algum arquivo reinicia o servidor para nós.

Isso pode dar um pouco de dor de cabeça, não basta apenas executar a aplicação com nodemon, existem alguns detalhes que vamos ver abaixo, vamos adicionar então o nosso novo serviço app-dev:

Nessa configuração adicionamos o campo volumes, ele é necessário para dizermos onde o nosso source se encontra no HOST, funciona assim primeiro o caminho do HOST, no caso . e depois o caminho no contêiner que é /usr/src/app separados por :, outro detalhe é o uso da flag -L para habilitar o modo legacy do nodemon, dessa forma a pesquisa por mudanças de arquivos sera feita outra forma.

Agora basta executar docker-compose build e depois docker-compose up app-dev para levantarmos nossa aplicação para desenvolvimento, tente mudar algo no código e veja sua aplicação reiniciar.

Considerações

Assim temos nossa aplicação em NodeJS dockerizada, criamos um contêiner para o nosso ambiente de desenvolvimento, isolamos o que é comum nos contêineres em nosso Dockerfile e o que é diferente deixamos em nosso docker-compose.yml.

Aqui utilizamos uma stack NodeJS + MongoDB mais isso não impede você de utilizar outras tecnologias.

Espero ter ajudado com essas informações, conforme eu for percorrendo o meu caminho pretendo criar novos artigos, qualquer feedback ou correções são bem vindas!

Até mais! 🐳

--

--