Deployment de Laravel no Cloud com CI/CD (GitHub Actions e GitLab CI)

Deployment de Laravel no Cloud com CI/CD (GitHub Actions e GitLab CI)

Deploy manual funciona até o dia em que deixa de funcionar. Enquanto o projeto é pequeno e o time é reduzido, subir código via SSH, rodar alguns comandos e torcer para dar certo parece aceitável. Em projetos reais, com mais gente mexendo, deploy frequente e produção rodando 24/7, isso vira risco operacional.

CI/CD não é sobre velocidade. É sobre previsibilidade, repetibilidade e segurança no processo de entrega.


O que CI/CD realmente resolve em projetos Laravel

Em aplicações Laravel, o pipeline de deploy resolve três problemas clássicos:

  1. Ambiente inconsistente
    O código roda local, mas quebra em produção porque algo foi esquecido ou executado fora de ordem.
  2. Deploys inseguros
    Código sobe sem testes, sem validação, sem rollback fácil.
  3. Processo dependente de pessoas
    “Só fulano sabe fazer deploy”. Quando ele não está, ninguém sobe nada.

CI/CD elimina esses pontos ao transformar deploy em processo automatizado, não em ritual manual.


Conceito básico do pipeline (independente da ferramenta)

Antes de falar de GitHub Actions ou GitLab CI, é importante entender o fluxo lógico. Um pipeline de Laravel bem definido costuma ter estas etapas:

  1. Checkout do código
  2. Instalação de dependências
  3. Execução de testes
  4. Build (quando aplicável)
  5. Deploy
  6. Pós-deploy (migrations, cache, filas)

Se qualquer etapa falhar, o deploy não acontece. Isso é uma proteção, não um obstáculo.


Estrutura mínima de um deploy Laravel saudável

Independente de cloud ou CI, alguns princípios não mudam:

  • composer install sempre em modo produção
  • .env nunca versionado
  • APP_ENV e APP_DEBUG corretos
  • migrations rodando de forma controlada
  • cache/config/views limpos e recompilados
  • workers reiniciados corretamente

Se isso não estiver automatizado, o risco é constante.

Exemplo de pipeline com GitHub Actions

Um pipeline simples, mas funcional, usando GitHub Actions:

name: Deploy Laravel

on:
push:
branches:
- main

jobs:
deploy:
runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.2'
extensions: mbstring, pdo, pdo_mysql

- name: Install dependencies
run: composer install --no-dev --optimize-autoloader

- name: Run tests
run: php artisan test

- name: Deploy via SSH
uses: appleboy/ssh-action@v1
with:
host: ${{ secrets.SERVER_HOST }}
username: ${{ secrets.SERVER_USER }}
key: ${{ secrets.SERVER_SSH_KEY }}
script: |
cd /var/www/app
git pull origin main
composer install --no-dev --optimize-autoloader
php artisan migrate --force
php artisan optimize
php artisan queue:restart

Onde muita gente erra no deploy de Laravel

Rodar migration sem pensar em impacto

Migration em produção pode travar tabela, gerar lentidão ou indisponibilidade. CI/CD não elimina isso. Ele apenas automatiza. Migration precisa ser escrita com consciência de produção.

Cache mal tratado

Não limpar/recriar cache de config e routes gera bugs difíceis de explicar. Cache antigo em produção é clássico.

Workers esquecidos

Deploy sobe código novo, mas workers continuam rodando código antigo. Resultado: comportamento inconsistente.

Falta de rollback

CI/CD sem rollback é metade da solução. Mesmo que seja manual, precisa existir um caminho claro para voltar.


Estratégia simples de rollback

Mesmo sem blue/green ou canary, dá para ter rollback básico:

  • manter tags ou releases
  • usar git checkout para versão anterior
  • rodar php artisan migrate:rollback quando aplicável
  • reiniciar workers

O importante é ter plano. Não improvisar sob pressão.


CI/CD não substitui observabilidade

Deploy automatizado reduz erro humano, mas não impede bugs. Por isso, CI/CD precisa andar junto com:

  • monitoramento de erros
  • alertas pós-deploy
  • logs estruturados
  • métricas de saúde

Deploy sem visibilidade é só um erro mais rápido.

CI/CD em projetos Laravel não é luxo nem modinha. É uma camada básica de segurança operacional. Ele garante que o código passe sempre pelo mesmo caminho, reduz risco humano e cria previsibilidade no processo de entrega.

Quando o deploy deixa de ser um evento tenso e vira algo rotineiro, o time ganha confiança para evoluir o sistema. E isso, no fim, é o que permite crescer sem quebrar tudo a cada release.