CI/CD pour Laravel : GitHub Actions, staging, déploiement et rollback
DOG&DEV · 25/01/2025
CI/CD pour Laravel : GitHub Actions, staging, déploiement et rollback
Une pipeline CI/CD pour Laravel permet d’exécuter les tests à chaque push, de déployer sur staging puis production, et de gérer les migrations et les rollbacks de façon reproductible. Ce guide décrit une approche avec GitHub Actions, staging et prod, Envoy (ou équivalent) pour des déploiements à downtime maîtrisé, et les précautions pour les migrations et les retours en arrière.
Prérequis
- Dépôt GitHub avec le code Laravel
- Serveur(s) cibles (staging, prod) accessibles en SSH
- Secrets GitHub :
SERVER_IP,SERVER_USER,SSH_KEY, etc.
1. Workflow de base (tests + déploiement)
Exemple .github/workflows/deploy.yml :
name: Deploy Laravel
on:
push:
branches: [main, develop]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: 8.3
extensions: mbstring, intl, bcmath, pdo_mysql
- name: Install deps
run: composer install --no-dev --optimize-autoloader
- name: Tests
run: php artisan test
- name: Set deploy path
run: |
if [ "${{ github.ref_name }}" = "main" ]; then
echo "DEPLOY_PATH=/var/www/laravel-prod" >> $GITHUB_ENV
else
echo "DEPLOY_PATH=/var/www/laravel-staging" >> $GITHUB_ENV
fi
- name: Deploy (SCP)
uses: appleboy/scp-action@v0.1.4
with:
host: ${{ secrets.SERVER_IP }}
username: ${{ secrets.SERVER_USER }}
key: ${{ secrets.SSH_KEY }}
source: "."
target: ${{ env.DEPLOY_PATH }}
main→ prod ;develop→ staging.- SCP copie les fichiers ; pour un vrai déploiement (composer, migrate, caches), on préfère une commande SSH ou Envoy (voir ci‑dessous).
2. Déploiement avec Envoy (zéro-downtime)
Envoy (Laravel) exécute des tâches sur les serveurs via SSH. Exemple Envoy.blade.php à la racine :
@servers(['web' => 'deploy@votre-serveur'])
@task('deploy', ['on' => 'web'])
cd /var/www/laravel-app
git pull origin main
composer install --no-dev --optimize-autoloader
php artisan migrate --force
php artisan config:cache
php artisan route:cache
php artisan view:cache
@endtask
Dans le workflow, remplacer (ou compléter) l’étape Deploy par :
- name: Deploy via Envoy
run: php vendor/bin/envoy run deploy
env:
# Envoy peut utiliser des variables pour le serveur
En pratique, on configure souvent clés SSH et inventory (host, user) dans Envoy ou en variables. Pour un downtime encore plus réduit, des schémas avec releases + symlink (comme Deployer) sont préférables ; Envoy sert ici d’exemple de script remote centralisé.
3. Migrations en production
- Toujours exécuter les migrations dans la tâche de déploiement (ou une tâche dédiée) avec
--forcepour éviter les prompts. - Pour les changements de schéma lourds (grosses tables, ajout de colonnes non nullables), une approche en plusieurs déploiements est plus sûre :
- Déploiement 1 : migration qui ajoute une colonne nullable (ou avec défaut).
- Déploiement 2 : remplir la colonne (job, migration de data).
- Déploiement 3 : passer la colonne en NOT NULL ou supprimer l’ancienne.
En cas de maintenance explicite (court downtime acceptable) :
php artisan down
php artisan migrate --force
php artisan up
4. Rollback
- Code : déploiement d’un commit/tag précédent (nouveau run du workflow avec l’ancien ref, ou script qui fait
git checkout <ref>puiscomposer install, caches, etc.). - Migrations :
php artisan migrate:rollback --force(une ou plusieurs étapes). À anticiper : les rollbacks qui suppriment des colonnes ou des tables peuvent faire perdre des données ; bien les tester en staging. - Releases : si vous utilisez un schéma releases/ + current (symlink), le rollback consiste à remettre le symlink sur la release précédente puis éventuellement
migrate:rollback.
5. Notifications (optionnel)
Pour être notifié en cas de succès ou d’échec (Slack, Discord, email) :
- name: Notify Slack
uses: 8398a7/action-slack@v3
with:
status: ${{ job.status }}
fields: repo,message,commit,author
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK }}
Dépannage
| Symptôme | Piste | Correctif |
|---|---|---|
| Échec SSH / SCP | Clé, user, host, firewall | Vérifier Secrets GitHub, known_hosts, accès SSH depuis un runner |
composer install ou migrate en échec sur le serveur |
Chemins, PHP, .env, BDD |
Tester les commandes en SSH sur le serveur ; vérifier APP_ENV, DB_*, droits |
| Migrations qui cassent la prod | Migration non réversible ou non testée | Tester en staging ; privilégier des migrations additive (colonnes nullables, tables) avant des breaking |
Bonnes pratiques
- Secrets : ne jamais commiter de clés, mots de passe ou
.env; tout passer par GitHub Secrets (ou un secret manager). - Staging : déployer et tester (manuellement ou E2E) avant de merger vers
mainet déployer en prod. - Migrations : les garder réversibles (rollback) quand c’est possible ; documenter les étapes pour les changements en plusieurs fois.
Ressources
- Tech Verse Daily – CI/CD for Laravel with GitHub Actions
- Documentation Laravel – Envoy
- GitHub Actions – Documentation
Cet article s’inscrit dans notre série de guides technique et développement web. Pour un serveur ou une application sur-mesure, contact.