CI/CD para Flask: automatize o Deploy da sua API com Docker e GitHub Actions

Rocketseat

Conheça o Rocketseat Para Empresas
Oferecemos soluções personalizadas para empresas de todos os portes.
Já cansou de fazer deploy manual toda vez que atualiza seu código? Aquela sensação de "será que esqueci alguma coisa?" ou "por que funciona na minha máquina e não no servidor?" é familiar?
Bora acabar com isso agora!
Você vai aprender a criar um pipeline de CI/CD completo que automatiza todo o processo de build e deploy da sua API Python Flask usando Docker e GitHub Actions. No final, cada
git push que você fizer vai desencadear um processo automático que empacota e disponibiliza sua aplicação.O melhor de tudo? Você não precisa ser especialista em DevOps para fazer isso acontecer.
O que você vai construir
Um pipeline automatizado que:
- Detecta mudanças no seu código automaticamente
- Cria uma imagem Docker otimizada da sua aplicação
- Faz o push dessa imagem para um registro (Docker Hub)
- Deixa tudo pronto para o deploy em qualquer ambiente
O que você precisa saber antes
- Familiaridade com Docker (saber criar um container básico)
- Uma conta no GitHub
- Uma conta no Docker Hub (para armazenar suas imagens)
- Vontade de automatizar suas entregas
Bora começar? 🚀
Entendendo CI/CD
CI/CD é um conjunto de práticas que mudam o jogo no desenvolvimento de software. Mas o que significa na prática?
CI: Continuous Integration (integração contínua)
Imagine que você e outras pessoas estão trabalhando no mesmo projeto. Cada um faz suas alterações e envia para o repositório principal (no GitHub, por exemplo).
A integração contínua é o processo de juntar essas alterações automaticamente e frequentemente. A cada novo commit, o sistema verifica se o novo código funciona bem com o código existente. Isso geralmente envolve rodar testes automatizados.
Benefício: você descobre bugs e conflitos muito mais cedo, antes que eles virem uma bola de neve.
CD: Continuous Delivery ou Continuous Deployment (entrega ou deploy contínuo)
Depois que o código passa pela integração (CI), entra o CD.
- Continuous Delivery (entrega contínua): significa que seu código está testado, empacotado e pronto para ir para produção a qualquer momento. O deploy final ainda pode ser manual, mas o pacote está pronto.
- Continuous Deployment (deploy contínuo): leva isso um passo adiante. Se o código passar por todos os testes, ele é automaticamente enviado para produção, sem intervenção humana.
Neste material, vamos focar em preparar o terreno para o CD, automatizando o build e o empacotamento da nossa aplicação Flask em uma imagem Docker.
Benefício: você entrega valor mais rápido, com menos erros manuais e muito mais confiança no seu processo.
Preparando a API Flask
Vamos começar criando uma API Flask super simples. O foco aqui não é o Python, mas sim o processo de automação.
Se você está começando com Python ou quer reforçar os conceitos de Flask, você pode criar sua própria API seguindo o curso gratuito da Rocketseat: Introdução ao Python e Flask.
Estrutura do projeto
Crie uma pasta para o projeto. Sua estrutura inicial ficará assim:
flask-cicd-pipeline/ ├── app.py └── requirements.txt
O código da API
Crie o arquivo
app.py e adicione o seguinte código. É uma API com uma única rota para teste.from flask import Flask, jsonify app = Flask(__name__) @app.route('/') def index(): return jsonify({"message": "Deploy automatizado funcionando! 🚀", "status": "success"}) # O bloco abaixo só é usado local. if __name__ == '__main__': app.run(host='0.0.0.0', port=5000, debug=True)
Dependências
Para rodar nossa aplicação em um ambiente de produção (como um container Docker), é recomendado usar um servidor web mais robusto que o servidor de desenvolvimento do Flask. Usaremos o
gunicorn.Crie o arquivo
requirements.txt e adicione:Flask>=3.0.0 gunicorn
Você pode testar localmente instalando as dependências (preferencialmente em um ambiente virtual) e rodando
python app.py.Criando o Dockerfile
Agora vamos "containerizar" nossa aplicação. O Dockerfile é a receita que diz ao Docker como construir a imagem da nossa API Flask.
Crie um arquivo chamado
Dockerfile (sem extensão) na raiz do projeto.Vamos construir o
Dockerfile passo a passo, focando em otimização de camadas:# 1. Imagem base: Começamos com uma imagem Python oficial e leve. # 'slim' significa que ela tem apenas o necessário para rodar Python. FROM python:3.11-slim # 2. Diretório de trabalho: Define onde o código vai ficar dentro do container. WORKDIR /app # 3. Instalação de dependências: # Copiamos apenas o requirements.txt primeiro. Isso otimiza o cache do Docker. # Se o código mudar, mas os requisitos não, essa etapa não precisa ser refeita. COPY requirements.txt . # Rodamos o pip para instalar as dependências. # '--no-cache-dir' ajuda a manter a imagem final menor. RUN pip install --no-cache-dir -r requirements.txt # 4. Código da aplicação: Copiamos o restante dos arquivos do nosso projeto. COPY . . # 5. Exposição de porta: Informamos ao Docker que nossa aplicação vai usar a porta 5000. EXPOSE 5000 # 6. Comando de inicialização: O que o container deve fazer quando iniciar. # Usamos gunicorn para servir nossa aplicação Flask. # '--bind 0.0.0.0:5000' faz a aplicação escutar em todas as interfaces na porta 5000. # 'app:app' diz ao gunicorn para procurar o objeto 'app' dentro do módulo 'app.py'. CMD ["gunicorn", "--bind", "0.0.0.0:5000", "app:app"]
Como testar o container localmente
Antes de automatizar, é sempre bom garantir que o Dockerfile funciona na sua máquina.
- Build da imagem:
No terminal, dentro da pasta do projeto, rode o comando para construir a imagem. Vamos chamá-la de
flask-api-cicd.
docker build -t flask-api-cicd .
Rodar o container:
Agora, vamos iniciar um container a partir dessa imagem. Mapeamos a porta 5000 do host para a porta 5000 do container.
docker run -p 5000:5000 flask-api-cicd
Abra seu navegador em
http://localhost:5000. Você deve ver a mensagem da API. Sucesso! Configurando o GitHub Actions
Chegou a hora da mágica acontecer. O GitHub Actions é a ferramenta de CI/CD integrada ao GitHub que nos permite automatizar fluxos de trabalho (workflows).
Componentes principais
- Workflow: o processo automatizado completo que você define.
- Trigger (gatilho): o evento que inicia o workflow (ex: um
pushna branchmain).
- Job: um conjunto de passos que rodam em um ambiente.
- Step (passo): uma tarefa individual dentro de um job (ex: rodar um comando).
Criando o arquivo de workflow
Os workflows ficam em uma pasta específica no seu repositório. Crie a estrutura de diretórios
.github/workflows/ na raiz do seu projeto, e dentro dela, crie o arquivo deploy.yml.flask-cicd-pipeline/ ├── .github/ │ └── workflows/ │ └── deploy.yml ├── app.py ├── Dockerfile └── requirements.txt
Configuração do workflow
Vamos criar um workflow que faz o build da imagem Docker e envia para o Docker Hub toda vez que houver um push na branch
main.Abra o
deploy.yml e adicione o seguinte conteúdo:name: CI/CD Pipeline - Build and Push Docker Image # Triggers: Define quando o workflow será executado on: push: branches: [ "main" ] # Apenas na branch main pull_request: branches: [ "main" ] # Também roda quando um PR for aberto contra a main # Jobs: Os trabalhos que serão executados jobs: build-and-push: # Define o ambiente onde o job vai rodar (uma máquina virtual Ubuntu) runs-on: ubuntu-latest # Steps: Os passos do job steps: # Passo 1: Checkout do código # Usa uma action pronta para baixar o código do repositório para a máquina virtual - name: Checkout code uses: actions/checkout@v4 # Passo 2: Login no Docker Hub # Precisamos fazer login para poder enviar a imagem para o registro - name: Login to Docker Hub # Só executa este passo se for um push na main (não em PRs) if: github.event_name == 'push' uses: docker/login-action@v3 with: # Usamos secrets do GitHub para armazenar credenciais de forma segura username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} # Passo 3: Configurar o Docker Buildx # Buildx é uma ferramenta avançada do Docker para builds mais eficientes - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 # Passo 4: Build e Push da imagem # A action principal que faz o trabalho pesado - name: Build and push Docker image uses: docker/build-push-action@v5 with: context: . # Onde está o Dockerfile (na raiz) # Só faz o push se for um push na main. Em PRs, apenas faz o build (para verificar se funciona) push: ${{ github.event_name == 'push' }} # Define o nome e a tag da imagem. Ex: seuusuario/flask-api-cicd:latest tags: ${{ secrets.DOCKERHUB_USERNAME }}/flask-api-cicd:latest
Explicação do workflow
- Adicionamos
pull_requestnos triggers. Isso é uma boa prática de CI: verificar se o código do PR consegue ser integrado antes do merge.
- Usamos
if: github.event_name == 'push'para garantir que o login e o push para o Docker Hub só aconteçam quando o código for efetivamente enviado para amain, não durante a verificação de um PR.
Secrets e variáveis de ambiente
Você percebeu que usamos
${{ secrets.DOCKERHUB_USERNAME }} e ${{ secrets.DOCKERHUB_TOKEN }}? Não podemos colocar nossas credenciais direto no código. O GitHub Secrets é um cofre seguro para guardar essas informações.- Crie um token no Docker Hub:
- Vá em Docker Hub > Account Settings > Security.
- Clique em "New Access Token".
- Dê um nome (ex: "github actions token") e gere o token.
- Importante: Copie ele agora! Você só verá ele uma vez.
- Configure no GitHub:
- No seu repositório no GitHub (você precisará subir o código que criamos até agora), vá em Settings > Secrets and variables > Actions.
- Clique em "New repository secret".
- Crie
DOCKERHUB_USERNAMEcom seu nome de usuário do Docker Hub. - Crie
DOCKERHUB_TOKENcom o token que você copiou do Docker Hub.
Testando o pipeline
Tudo configurado! Agora vamos ver a automação funcionando na prática.
Como fazer um commit que vai acionar o workflow
- Certifique-se de que seu projeto está no GitHub.
- Faça uma pequena alteração (opcional). Se quiser testar a atualização, mude a mensagem no
app.py:
- Commit e Push:
Certifique-se de que todos os arquivos (incluindo o diretório
.github/workflows) foram adicionados e faça o push para a branchmain.
Onde visualizar os logs no GitHub Actions
Assim que você fizer o push, o GitHub Actions vai detectar a mudança e iniciar o workflow.
- Vá para a aba "Actions" no seu repositório do GitHub.
- Você verá seu workflow listado, provavelmente com um ícone amarelo indicando que está em execução.
- Clique nele para ver os detalhes e acompanhar os logs de cada step em tempo real.
Como interpretar sucessos e falhas
- Sucesso (Verde ✅): Parabéns! Sua imagem Docker foi construída e enviada para o Docker Hub.
- Falha (Vermelho ❌): Não se preocupe. Clique no passo que falhou para ler os logs. O GitHub Actions fornece logs detalhados que geralmente apontam a causa do problema.
Debug de problemas comuns
- Falha no login do Docker Hub: verifique se as secrets (
DOCKERHUB_USERNAMEeDOCKERHUB_TOKEN) estão corretas no GitHub. Lembre-se que o token não é sua senha normal.
- Falha no build: pode haver um erro no seu
Dockerfileou no código da aplicação. Leia os logs do step "Build and push Docker image". Teste o build localmente primeiro.
- Workflow não inicia: verifique se o arquivo está em
.github/workflows/deploy.ymle se o trigger está configurado para a branch correta (main).
Próximos passos e melhorias
Você construiu um pipeline de CI/CD funcional, mas isso é só o começo da sua jornada em DevOps. Existem várias melhorias que você pode implementar:
Adicionar testes automatizados
Este é talvez o passo mais importante para um CI robusto. Antes de fazer o build da imagem, você deve rodar seus testes (com
pytest, por exemplo). Se os testes falharem, o pipeline deve parar.Implementar diferentes ambientes
Conheça o Rocketseat Para Empresas
Oferecemos soluções personalizadas para empresas de todos os portes.
Artigos_
Explore conteúdos relacionados
Descubra mais artigos que complementam seu aprendizado e expandem seu conhecimento.
NewsletterReceba conteúdos inéditos e novidades gratuitamente