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.
Para configurar nosso pipeline, precisaremos das seguintes ferramentas:
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.
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:
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.
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.
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'
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.
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.
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
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.