A containerização é agrupar uma aplicação, suas dependências e bibliotecas juntas para que possam ser usadas como plug-and-play em qualquer tipo de infraestrutura. Cada pacote é chamado de contêiner.
Por que containerizar um serviço Node.js?
Como discutido na seção anterior, containerizar um serviço Node.js significaria agrupar o aplicativo, suas dependências, bibliotecas e até mesmo a configuração em um único contêiner.A containerização tem os seguintes benefícios:
- Portátil. Como agrupamos todos os requisitos do aplicativo em um contêiner, as mesmas imagens podem ser instaladas em desenvolvimento, homologação e produção.
- Rápido e leve. Os contêineres tendem a ser muito mais rápidos do que máquinas virtuais (VMs) ou bare metal, pois estão executando apenas os requisitos do aplicativo, enquanto historicamente, as VMs ou bare metal iniciariam toda a máquina e todos os aplicativos
- Escalável. Com os dois benefícios acima, a escalabilidade se torna muito fácil, pois os contêineres são rápidos, eficientes e fáceis de implantar.
Neste artigo, vamos nos concentrar especificamente em containerizar um aplicativo Node.js.
Pré-requisitos
Ferramentas e Software
Docker (Docker Engine e Docker CLI)
Precisaremos instalar o Docker para gerenciar nossos contêineres. O Docker Engine lida com o tempo de execução e o CLI pode ser usado para interagir por meio da linha de comando.
Node.js e npm/yarn Instalados (Para Desenvolvimento/Teste Inicial)
Vamos precisar do Node.js e do npm instalados para instalar as dependências das bibliotecas e executar o serviço.
Kubernetes ou Docker Compose para Gerenciar Múltiplos Contêineres (Opcional)
Vamos precisar do Kubernetes ou Docker Compose para gerenciar vários contêineres.
Fundamentos
Estrutura da aplicação Node.js:
- É esperado que o leitor já entenda o papel do arquivo principal (
app.js
ouindex.js
) no projeto, juntamente com o papel de outros arquivos comopackage.json
eyarn.lock
. - Este artigo também não abordará outros aspectos do projeto, como controladores, middleware e rotas.
Comandos Docker Básicos e Sintaxe do Dockerfile
Comandos Docker:
docker ps -> Lists all the containers running on the system
docker pull -> Pulls any image from the docker hub or official registry of Docker
docker build -> Creates an image from the docker file
docker run -> Starts a container from an exiting image
docker stop -> Stops a container if it has crashed or if you want to switch the container
Instruções principais do Dockerfile:
FROM -> Every DockerFile
WORKDIR -> Set the working directory inside the container
COPY (or ADD) -> Transfers the application's files to the image
RUN -> Executes commands during build time
CMD -> Sets the default command to be run when the container is started from the image
EXPOSE -> Specifies the port the container listens on
ENV -> Sets environment variables used during build and runtime
Tanto as tabelas abordadas quanto a estrutura do Node.js são suficientes para começar a contêinerização e implantar seu serviço Node.js.
Configurando o Serviço Node.js
Configurando o ambiente Node.js é um processo simples. Certifique-se de que você tenha o Node.js instalado em sua máquina. Se você tiver alguma dúvida, consulte o apêndice (1). Uma vez instalado, abra o seu terminal e verifique a instalação digitando.
node -v
npm -v
Crie um diretório de projeto e inicialize o seu projeto da seguinte maneira:
npm init -y
Instale o módulo express
npm install express
Crie um arquivo de servidor, vamos chamá-lo de server.mjs, onde podemos adicionar a rota e a lógica correspondente à rota. Como este artigo é mais sobre containerização, manteremos a lógica do endpoint muito simples. Algo assim:
import express from "express";
const app = express();
const port = 8080;
app.get('/', (req, res) => {
res.send('Welcome to my demo service!');
});
app.listen(port, () => {
console.log(`Demo Service is running on port ${port}`);
});
Agora seu serviço está pronto para ser iniciado, navegue até o diretório do projeto no terminal e execute este comando:
node server.mjs
O serviço está ativo e funcionando; se visitarmos http://localhost:3000, veremos:
“Bem-vindo ao meu servidor”
Criando o Dockerfile
Vamos revisar o que é um Dockerfile, ele contém as instruções para construir a imagem do docker. Vamos criar um Dockerfile no diretório raiz. Durante esta etapa, conforme discutimos nas instruções do Dockerfile, precisamos fazer as seguintes coisas:
FROM node:18-alpine => Indicate the base image to use. Here we're using the official Nodejs 14 image.
WORKDIR /usr/src/app => Sets the working directory in the container.
COPY package*.json ./ => Duplicate the package.json and package-lock.json files to the working directory.
RUN npm install => Installs the app package dependencies.
COPY . . => Copies the remaining of the app to the working directory.
EXPOSE 8080 => Exposes the port our app is listening on.
CMD ["node", "app.js"] => Defines the command to start your Node.js application.
Construindo e Executando a Imagem do Docker
A partir da raiz do terminal, navegue atéseuprojeto e execute o seguintecomando:
docker build -t image-name .
Onde nome-da-imagem
é o nome da imagem Docker. O .
no final define o contexto como o diretório atual.
Uma vez que a imagem estiver construída, vamos criar o contêiner e executar o aplicativo Node.js com o seguinte comando:
docker run --name container-name -p 8080:8080 image-name
Após o sucesso do acima, vocêpode verificar que o serviço está em execução executando o comando docker ps e, em seguida, acessando a mesma URL localhost como antes.
Enviando Imagens para um Registro
Agora que sua imagem está pronta, é hora de enviá-la para um registro. Para o escopo deste artigo, vamos enviar apenas para o Docker Hub. O Docker Hub é um serviço baseado em nuvem para armazenar, compartilhar e gerenciar imagens de contêineres Docker.
Crie uma conta em https://hub.docker.com/ e faça login com sua conta.
docker login
Depois de fazer login, imagens construídas localmente podem ser adicionadas como:
docker tag image-name:tag dockerhub-username/repository-name:tag
Onde:
tag
é oulatest
ou um número de versão.nome-do-repositório
é o nome do repositório desejado.
Em seguida, envie a imagem da seguinte forma:
docker push dockerhub-username/repository-name:tag
Conclusão
Como podemos ver, a conteinerização torna fluxos de trabalho e serviços complexos rápidos, portáteis e escaláveis ao separar as dependências. Uma vez implementado, toda a equipe se beneficia disso.Eu o encorajo a explorar os recursos avançados como builds de múltiplas etapas e redes de contêineres. Além disso, considere aprender sobre ferramentas de orquestração (por exemplo, Kubernetes) e integrar pipelines de CI/CD para otimizar seu fluxo de trabalho de desenvolvimento.
Apêndice
Source:
https://dzone.com/articles/containerization-of-a-nodejs-service