Muita gente tem me procurado para saber um pouco mais sobre Docker e como fazer sua aplicação rodar em um container. Por isso, resolvi fazer esse pequeno artigo mostrando como fazer o deploy de uma aplicação Node.js em um container no Docker.
Vou partir da premissa que você já tenha o Docker, NPM e Node.js instalados. Caso contrário, você pode encontrar ajuda aqui:
- NPM + Node.js: https://nodejs.org/en/download/
- Docker: https://docs.docker.com/install/
A primeira coisa que vamos fazer é clonar o repositório do nosso projeto, e instalar as dependências:
$ git clone <a href="https://github.com/claudineyjr/docker_node_tutorial">https://github.com/claudineyjr/docker_node_tutorial</a> $ cd docker_node_tutorial $ npm install
Pronto, tudo instalado! Essa aplicação é extremamente simples, está rodando um servidor com express e quando acessado localhost:3000, ele nos exibe o conteúdo do objeto process.env, que nada mais é do que o ambiente em que está rodando o processo; um objeto presente por padrão em uma aplicação Node.js.
Neste projeto vamos focar em um arquivo em especial, o Dockerfile, que é o arquivo usado para moldar a imagem docker a ser usada. Podemos fazer um paralelo dele. À título de exemplo, com o que é o código de uma declaração de uma classe em POO (Programação Orientada a Objeto), nele definimos todas as propriedades que a imagem Docker terá. Vamos ver um pouco do que está acontecendo neste arquivo.
# Usa uma imagem do docker hub com a versão carbon do Node.js FROM node:carbon
Esse comando define nosso “ponto de partida” da imagem; vamos usar uma imagem publicada no Docker Hub que contém o Node.js. Precisamos definir em qual diretório do container iremos usar para copiar os arquivos e rodar nossa aplicação. Para isso, usamos o comando WORKDIR.
# Define qual diretório será usado para nossa aplicação dentro do container WORKDIR /usr/src/app
Como vocês sabem, nos arquivos package.json e package-lock.json, temos todas as dependências usadas em nossa aplicação, assim como a estrutura da aplicação. Portanto, para inicializar nosso projeto, precisamos copiar esses arquivos da pasta em que se encontra o Dockerfile para a pasta declarada no WORKDIR.
O comando abaixo usa o operador COPY e recebe dois parâmetros, arquivos de origem package*.json, onde “*” é um operador para dizer à maquina que ela pode pegar todos os arquivos que começam com/tenham a extensão json, e o segundo parâmetro é a pasta destino representada pelo “./“.
# Copia todos os arquivos que começam com package e tem extensão .json para o diretório definido acima COPY package*.json ./
Após copiar todos os arquivos de pacote para nosso diretório de trabalho, precisamos instalar todas as dependências. Para isso, vamos rodar:
# Instala todas as dependências declaradas no package.json RUN npm install
Agora falta copiar nossa aplicação de fato, para dentro do container. Para isso usaremos o COPY novamente, com dois parâmetros, sendo que o “.” quer dizer que é pra copiar tudo do nível do Dockerfile para tudo do nível do WORKDIR.
# Copia todos os arquivos da raiz da nossa aplicação para a pasta deinida no WORKDIR COPY . .
Bom, precisamos também deixar disponível a porta em que nossa aplicação roda, certo? Então exporemos a porta 3000 do container.
# Expõe a porta 3000 do container EXPOSE 3000
Também precisamos que o container rode nossa aplicação, né? Para isso, colocaremos que é preciso rodar o npm start também.
# Roda o comando 'npm start' CMD [ "npm", "start" ]
E isso conclui nosso Dockerfile. Temos nosso modelo para criar a imagem, agora vamos criá-la. Agora abriremos o terminal e navegaremos até o diretório onde se encontra o Dockerfile.
Para buildar uma imagem, usamos o comando docker build e podemos usar a opção -t nomedoprojeto para dar uma tag para sua imagem. Vamos chamar essa imagem de seunome/docker-node-tutorial a partir do diretório local.
docker build -t seunome/docker-node-tutorial .
O comando acima provavelmente demorará um pouco na primeira vez que você executar, pois ele precisa baixar a imagem node:carbon, que tem um tamanho considerável. As próximas vezes serão praticamente instantâneas.
Agora você já tem sua imagem Docker criada. Uma imagem é como se fosse uma classe em POO, e você precisa instanciá-la. A instância de uma imagem é o container da mesma, então podemos comparar um container a um objeto em POO.
Vamos listar nossas imagens usando o comando docker images no terminal. O resultado será uma lista com todas as imagens disponíveis no computador.
Só falta rodar a aplicação agora, certo? Para isso, basta usar o comando:
docker run -p 49160:3000 -d seunome/docker-node-tutorial
Vamos entender o comando acima: usamos docker run para rodar uma aplicação. O “-p” é para definir as portas, sendo que a porta 49160 ficará disponível fora do container e direcionará à porta 3000 que nós definimos na nossa aplicação e expusemos no Dockerfile. O “-d” faz com que o container rode em background e que exiba no terminal o id do container. O último argumento é o nome da sua imagem, que você definiu acima.
Pronto! Sua aplicação está rodando! Para acessar, vá em localhost:49160 e você deverá ver o process.env do seu container. Veja que ele é diferente do que você recebe quando roda sua aplicação direto do terminal, pois ele exibe as informações do container.
Agora que você já sabe da estrutura e de como começar, você pode desenvolver aplicações e imagens docker para rodar em qualquer ambiente. E essa é a base para levar seus aplicativos pra nuvem, para serviços como IBM Cloud, Amazon, Microsoft e Google.
Dê uma olhada no repositório e dê estrela lá:
Prefere vídeo? Tem também, meu vídeo no YouTube falando sobre o assunto está nesse link.
Quer ficar ligado nas atualizações? Se inscreva no meu canal!
Valeu, pessoal! Espero que tenham gostado.