Workflow do GitHub Actions para deploy de aplicação Java
Veja um workflow do GitHub Actions para deploy de aplicação Java em máquina virtual utilizando Maven e Docker.
Por Gabriel Luciano
Criado em 08 de outubro de 2024 às 22:48

Há um tempo atrás tive a necessidade de implementar um workflow do GitHub Actions para o deploy de uma aplicação Spring Boot para uma máquina virtual utilizando Docker.
Desenvolvi o workflow abaixo que contém os seguintes passos:
- Execução de testes unitários e de integração (o workflow falha caso algum teste termine com exit code diferente de zero)
- Build e push da imagem do Docker para o Docker Hub (importante realizar o build do jar a partir do Dockerfile)
- Transferência do compose file, arquivos de configuração e scripts SQL para o servidor utilizando SSH.
- Remoção dos containers em execução e deploy dos novos containers.
O arquivo faz uso de GitHub Secrets para garantir a segurança dos tokens e chaves e outras informações sensíveis.
name: Java Test and Deploy CI
on:
push:
branches: ["main"]
workflow_dispatch:
env:
SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
SSH_USER: ${{ secrets.SSH_USER }}
SSH_HOST: ${{ secrets.SSH_HOST }}
jobs:
tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up JDK 21
uses: actions/setup-java@v4
with:
java-version: "21"
distribution: "temurin"
cache: maven
- name: Run unit tests
run: mvn -B test
- name: Run integration tests
run: mvn test -B -P integration-tests
build:
runs-on: ubuntu-latest
needs: tests
steps:
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build and push
uses: docker/build-push-action@v6
with:
push: true
tags: ${{ secrets.DOCKERHUB_USERNAME }}/app-name:latest
deploy:
runs-on: ubuntu-latest
needs: build
steps:
- uses: actions/checkout@v4
- name: Deploy project to the server
run: |
eval "$(ssh-agent -s)" && \
echo "$SSH_PRIVATE_KEY" | ssh-add - && \
rsync -az --delete-after -e "ssh -o StrictHostKeyChecking=no" docker-compose.prod.yml \
*.sql *.conf "$SSH_USER@$SSH_HOST:/app/api/" && \
ssh -o StrictHostKeyChecking=no "$SSH_USER@$SSH_HOST" '\
cd "/app/api" && \
docker compose -f docker-compose.prod.yml down && \
docker compose -f docker-compose.prod.yml pull && \
docker compose -f docker-compose.prod.yml up -d'
Talvez a parte mais complexa do script seja o comando SSH para envio dos arquivos para a máquina virtual. Vamos entender os passos:
eval "$(ssh-agent -s)" && echo "$SSH_PRIVATE_KEY" | ssh-add -
- inicia o SSH Agent e adiciona a chave SSH no agentrsync -az --delete-after -e "ssh -o StrictHostKeyChecking=no" docker-compose.prod.yml *.sql *.conf "$SSH_USER@$SSH_HOST:/app/api/"
- utiliza o comando rsync (presente na maioria das distribuições Linux) para transferir os arquivos do repositório local para a máquina virtualssh -o StrictHostKeyChecking=no "$SSH_USER@$SSH_HOST" 'cd "/app/api" && docker compose -f docker-compose.prod.yml down && docker compose -f docker-compose.prod.yml pull && docker compose -f docker-compose.prod.yml up -d'
- através de uma conexão SSH, faz o encerramento e remove os containers atuais, realizando o pull das imagens na sequência e subindo os containers novamente.
Concluindo
Com esse simples workflow, é possível automatizar todo o processo de testes automatizados e deploy da aplicação. O workflow pode ser facilmente customizado para outros projetos ou mesmo para outras linguagens. Espero que seja útil para você!