Criando uma pipeline de CI/CD para aplicações Node.js no GitHub Actions

Criando uma pipeline de CI/CD para aplicações Node.js no GitHub Actions

No mundo do desenvolvimento de software, a entrega contínua de valor é essencial para se manter competitivo. É aqui que entra o CI/CD (Integração Contínua e Entrega Contínua/Implantação Contínua). Este artigo explora a criação de uma pipeline de CI/CD para aplicações Node.js usando Docker e GitHub Actions, oferecendo um guia prático para implementar essas práticas no seu fluxo de trabalho.

Requisitos

Para configurar nosso pipeline, precisaremos das seguintes ferramentas:

  • Node.js: Ambiente de execução para JavaScript;
  • Docker: Plataforma de contêineres que facilita a criação, envio e execução de aplicações;
  • GitHub Actions: Serviço de integração contínua e entrega contínua que permite automatizar fluxos de trabalho diretamente no GitHub;
  • Outras ferramentas úteis: ESLint para linting e Jest para testes.

Repositório de exemplo

Para nossa demonstração de hoje, sugerimos que você siga os passos da próxima seção para aprender como baixar e configurar o Node.js na sua máquina local e dockerizar sua aplicação através da criação do Dockerfile. Porém, se você já souber esses passos e quiser um repositório que contém um Dockerfile pronto para ser usado, você pode usar o código que está disponível no repositório https://github.com/toolbox-playground/hello-world-com-docker-languages/tree/main/nodejs,  no qual temos um simples “Hello World” feito em Node.js já dockerizado.

Preparando o ambiente

Configuração do Projeto Node.js

Para iniciar, vamos configurar um projeto básico em Node.js. Certifique-se de ter o Node.js instalado em sua máquina.

				
					# Crie o diretório de trabalho
mkdir nodejs-ci-cd
cd nodejs-ci-cd

# Certifique-se de instalar NPM
sudo apt-get install npm # Para instalações em Ubuntu/Linux
brew install npm # E no caso de MacOs

# Inicie o NPM
npm init -y
				
			

Resultado:


O comando acima cria uma estrutura básica para um projeto Node.js. Em seguida, adicione as dependências necessárias:

				
					npm install express
npm install --save-dev jest
				
			

No arquivo package.json, configure os scripts para iniciar a aplicação e rodar os testes:

				
					"scripts": {
  "start": "node index.js",
  "test": "jest"
}
				
			

O resultado vai ser um package.json parecido com o do screenshot abaixo:

 

Dockerizando a Aplicação

Para garantir que nossa aplicação possa ser executada de forma consistente em qualquer ambiente, vamos criar um Dockerfile no projeto:

				
					# Usando a imagem oficial do Node.js
FROM node:latest

# Cria o diretório da aplicação
WORKDIR /app

# Copia os arquivos do projeto
COPY package*.json ./
RUN npm install

# Copia o restante do código
COPY . .

# Expõe a porta que a aplicação irá rodar
EXPOSE 3000

# Comando para iniciar a aplicação
CMD ["npm", "start"]
				
			

Com o Dockerfile pronto, construa e teste a imagem Docker localmente:

				
					docker build -t nodejs-ci-cd .
docker run -p 3000:8080 nodejs-ci-cd
				
			

Você verá algo parecido com a imagem a seguir:

 

E acessando a nossa aplicação pelo browser, conseguiremos ver a aplicação funcionando:

O próximo passo é o de subir sua imagem Docker em alguma plataforma de container registry, como Docker Hub ou Azure Container Registry, mas como o intuito deste artigo é fazer isso via pipeline CI/CD, vamos deixar esse passo para ser feito no Github actions, na seção a seguir.

 

Não esqueça de salvar suas alterações localmente e subir para o GitHub seguindo esta documentação.

Configurando o GitHub Actions

O GitHub Actions (https://docs.github.com/pt/actions) é uma plataforma de automação que permite criar workflows customizados diretamente no repositório GitHub. Esses workflows podem ser configurados para executar testes, builds, deploys, entre outras tarefas automatizadas.

Criando o Workflow

Crie um diretório .github/workflows na raiz do seu projeto no GitHub e adicione um arquivo ci-cd.yml com o seguinte conteúdo:

				
					name: CI/CD Pipeline

on:
  push:
    branches:
      - main

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
    - name: Checkout code
      uses: actions/checkout@v2

    - name: Build Docker image
      run: cd nodejs && docker build -t nodejs-ci-cd .

    - name: Push Docker image to Docker Hub
      env:
        DOCKER_HUB_USERNAME: ${{ secrets.DOCKER_HUB_USERNAME }}
        DOCKER_HUB_PASSWORD: ${{ secrets.DOCKER_HUB_PASSWORD }}
      run: |
        echo $DOCKER_HUB_PASSWORD | docker login -u $DOCKER_HUB_USERNAME --password-stdin
        docker tag nodejs-ci-cd $DOCKER_HUB_USERNAME/nodejs-ci-cd
        docker push $DOCKER_HUB_USERNAME/nodejs-ci-cd


				
			

Ou se você preferir, ao criar/entrar no seu repositório no GitHub, clique em Actions → New Workflow → Set up a workflow yourself → copie e cole o código yaml acima, conforme mostra o screenshot abaixo:

 

Não esqueça de adicionar as variáveis contendo usuário e senha do seu Docker Hub, mas evite colocá-las no formato hard-coded, ou seja, usuário e senha fixos no seu arquivo yaml, pois se seu repositório for público, você estará expondo seu usuário e senha do Docker Hub para qualquer pessoa no mundo.

 

Para configurar variáveis no GitHub, é possível ir em Settings → Secrets and Variables → Actions. Dentro do GitHub existem vários tipos de variáveis, cada um com sua devida utilidade e caso de uso definidos e você pode conferir suas diferenças em clicando aqui.  

 

Esse workflow será acionado em cada push para a branch main, executando os testes, construindo a imagem Docker e publicando-a no Docker Hub. 

 

Você pode logar no seu Docker Hub e ver sua imagem publicada lá.

 

Agora que concluímos a integração contínua (CI) e nossa imagem está armazenada em um Container Registry, podemos nos concentrar na entrega contínua (CD) da nossa aplicação. O GitHub é um dos serviços de Git que mais contribui com a comunidade, criando várias documentações e formas de engajar as pessoas. Eles disponibilizam muitas documentações que podemos usar para nossos propósitos, que podem ser encontradas em https://docs.github.com/en/actions/deployment/deploying-to-your-cloud-provider/deploying-to-azure. Dessa forma, você pode usar variações desses arquivos, usando-os como base para te ajudar com a criação do CD da sua aplicação.

No nosso caso, como forma de ser objetivo no nosso artigo, vamos simular o deploy da nossa aplicação feita em Node.js em um App Service usando como base o que o GitHub disponibilizou em https://docs.github.com/en/actions/deployment/deploying-to-your-cloud-provider/deploying-to-azure/deploying-docker-to-azure-app-service .

				
					/ ** Continuação da parte que fizemos do CI ** /

  deploy:
    runs-on: ubuntu-latest

    needs: build

    environment:
      name: 'production'
      url: ${{ steps.deploy-to-webapp.outputs.webapp-url }}

    steps:
      - name: Docker Login
        env:
          DOCKER_HUB_USERNAME: ${{ secrets.DOCKER_HUB_USERNAME }}
          DOCKER_HUB_PASSWORD: ${{ secrets.DOCKER_HUB_PASSWORD }}
        run: |
          echo $DOCKER_HUB_PASSWORD | docker login -u $DOCKER_HUB_USERNAME --password-stdin

      - name: Deploy to Azure Web App
        env:
          AZURE_WEBAPP_NAME: MY_WEBAPP_NAME   # Nome da Aplicação
        id: deploy-to-webapp
        uses: azure/webapps-deploy@85270a1854658d167ab239bce43949edb336fa7c
        with:
          app-name: ${{ env.AZURE_WEBAPP_NAME }}
          publish-profile: ${{ secrets.AZURE_WEBAPP_PUBLISH_PROFILE }}
          images: '$DOCKER_HUB_USERNAME/nodejs-ci-cd:latest'

				
			

Implementando o Pipeline

Pipeline de Integração Contínua

A primeira parte do pipeline foca na Integração Contínua, que inclui a instalação das dependências, execução dos testes automatizados e construção da imagem Docker. A execução desses passos garante que cada alteração no código seja verificada imediatamente, permitindo identificar e corrigir erros rapidamente.

Pipeline de Entrega Contínua

A Entrega Contínua envolve o deploy automático da aplicação após a construção bem-sucedida da imagem Docker. Esse deploy pode ser configurado para diferentes ambientes, como staging e produção. Utilizando GitHub Actions, podemos definir diferentes jobs e steps para realizar o deploy em servidores configurados com Docker.

Melhores Práticas

  • Segurança: Utilize variáveis de ambiente e segredos (secrets) para armazenar informações sensíveis, como credenciais de login no Docker Hub.
  • Monitoramento e Alertas: Implemente ferramentas de monitoramento e configure alertas para ser notificado em caso de falhas no pipeline ou na aplicação em produção.

Acelere sua carreira conosco

A Mentoria Next Level DevOps é um programa de mentoria de 12 meses com encontros semanais ao vivo, com um grupo seleto e restrito, onde estaremos do seu lado para mantê-lo relevante e atualizado no mercado de tecnologia, aprendendo e implementando as melhores práticas e ferramentas de DevOps.

Clique aqui para entrar na prioridade pela melhor oferta de lançamento

Considerações Finais

Implementar um pipeline CI/CD para aplicações Node.js utilizando Docker e GitHub Actions não só melhora a eficiência do desenvolvimento como também aumenta a confiabilidade do software entregue. Ao seguir as melhores práticas e ajustar o pipeline às necessidades específicas do seu projeto, você pode garantir entregas contínuas e de alta qualidade.