---
title: "Déploiement continu d'un projet Symfony avec Deployer et GitHub Actions"
description: "Mettre en place le déploiement continu d'une application Symfony avec Deployer et GitHub Actions : recette deploy.php, releases sans coupure, migrations et rollback."
pubDate: 2024-11-18
updatedDate: 2026-10-04
family: 'php-symfony'
tags: []
heroImage: /images/deploiement-continu-dun-projet-symfony-avec-deployer-et-github-actions.webp
videoUrl: 'https://youtu.be/lyIDPSA1I6A'
faq:
  - question: 'Deployer est-il toujours maintenu ?'
    answer: 'Oui. La dernière version stable est la 8.0.5, publiée en mai 2026, et le dépôt continue de recevoir des commits.'
  - question: 'Faut-il installer Deployer globalement ou dans le projet ?'
    answer: "Dans le projet, avec composer require --dev deployer/deployer, dès qu'un pipeline entre en jeu : la version est alors figée par le composer.lock et la CI utilise celle que tu as testée."
  - question: 'Comment Deployer évite-t-il une coupure pendant le déploiement ?'
    answer: "Il prépare chaque version dans son propre dossier sous releases/, puis bascule le lien symbolique current. Le serveur web ne pointe jamais vers une release en cours d'écriture."
  - question: 'Comment revenir à la version précédente ?'
    answer: "dep rollback rebascule current vers la release précédente, et dep releases liste les versions encore présentes sur l'hôte."
  - question: 'Les migrations de base de données sont-elles lancées automatiquement ?'
    answer: "La recette Symfony fournit la tâche database:migrate : c'est à toi de l'appeler dans le déroulé du déploiement, elle n'est pas branchée à ta place."
---

Un `git pull` sur le serveur tient jusqu'au jour où la mise à jour des dépendances coupe le site. Deployer change la mécanique : chaque déploiement prépare une nouvelle release dans son propre dossier, puis bascule un lien symbolique vers celle-ci. Si quelque chose casse, le retour arrière est immédiat.

La vidéo en bas de page a été enregistrée sur Deployer 7 : le projet est passé en 8.x depuis, et la recette décrite ici est celle de la version courante.

## Ce que Deployer fait, concrètement

Sur l'hôte, Deployer tient trois dossiers : `releases/` contient toutes les versions déployées, `shared/` les fichiers qui survivent d'une release à l'autre, et `current`, un lien symbolique vers la release active. Ton serveur web pointe sur `current`. Un déploiement crée la nouvelle release à côté, puis échange le lien : le site n'est donc jamais servi depuis une arborescence en cours d'écriture.

## Installer Deployer

Pour un pipeline, installe Deployer **dans le projet** via Composer :

```
composer require --dev deployer/deployer
```

Une installation globale fonctionne en local, mais elle laisse la version du CLI dépendre de ta machine. En projet, la version est figée dans le `composer.lock` et la CI exécute exactement celle que tu as testée.

## La recette deploy.php

La recette Symfony apporte ce qu'un déploiement Symfony demande : provisioning, releases sans coupure et rollback. Elle s'active en tête du fichier :

```
require 'recipe/symfony.php';
```

Tu déclares ensuite ton hôte :

```
host('example.org')
    ->set('remote_user', 'deployer')
    ->set('deploy_path', '~/mon-projet');
```

La recette pose des valeurs par défaut qu'il vaut mieux connaître : `.env.local` est un fichier partagé, il n'est donc pas écrasé à chaque déploiement, et `var/` est déclaré inscriptible pour le cache et les logs.

## Le workflow GitHub Actions

Le pipeline vit dans `.github/workflows/deploy.yml` et se déclenche sur un push vers la branche principale :

```
on:
  push:
    branches: [main]
```

La clé privée SSH n'a rien à faire dans le dépôt : elle va dans les secrets, et le workflow la lit par `${{ secrets.SSH_PRIVATE_KEY }}`. Un déploiement concurrent sur la même cible est l'incident qu'on veut éviter, et la clé `concurrency` garantit qu'un seul job du groupe s'exécute à la fois.

## Migrations et cache

La recette expose des tâches prêtes à l'emploi : `database:migrate` lance les migrations Doctrine, `doctrine:schema:validate` vérifie le mapping, `deploy:cache:clear` vide le cache et `deploy:dump-env` génère un fichier d'environnement optimisé. Côté Composer, `--no-dev` évite d'installer les dépendances de développement en production et `--optimize-autoloader` accélère l'autoloader.

## Revenir en arrière

`dep rollback` rebascule `current` vers la release précédente. `dep releases` liste ce qui est encore disponible sur l'hôte, et `dep deploy --start-from <tâche>` permet de reprendre un déploiement interrompu sans tout refaire.

Si tu pars d'un serveur nu, [créer et déployer une application Symfony 7 sur un VPS avec Portainer](/blog/creer-et-deployer-une-application-web-sur-un-vps-avec-symfony-7-et-portainer/) couvre l'installation en amont de Deployer. La [documentation officielle de Deployer](https://deployer.org/docs/8.x/getting-started) détaille chaque tâche de la recette, et la [syntaxe des workflows GitHub Actions](https://docs.github.com/en/actions/reference/workflows-and-actions/workflow-syntax) précise le format du fichier YAML.

## Pour approfondir

**[Symfony et backend : du premier écran à la production](https://pentiminax.fr/blog/symfony-backend.md)**

Un parcours Symfony par objectif : Twig et Doctrine, projets concrets, déploiement continu, permissions et diagnostic à partir des articles du site.

[Parcourir le guide Symfony et backend](https://pentiminax.fr/blog/symfony-backend.md)

## Questions fréquentes

**Deployer est-il toujours maintenu ?**

Oui. La dernière version stable est la 8.0.5, publiée en mai 2026, et le dépôt continue de recevoir des commits.

**Faut-il installer Deployer globalement ou dans le projet ?**

Dans le projet, avec composer require --dev deployer/deployer, dès qu'un pipeline entre en jeu : la version est alors figée par le composer.lock et la CI utilise celle que tu as testée.

**Comment Deployer évite-t-il une coupure pendant le déploiement ?**

Il prépare chaque version dans son propre dossier sous releases/, puis bascule le lien symbolique current. Le serveur web ne pointe jamais vers une release en cours d'écriture.

**Comment revenir à la version précédente ?**

dep rollback rebascule current vers la release précédente, et dep releases liste les versions encore présentes sur l'hôte.

**Les migrations de base de données sont-elles lancées automatiquement ?**

La recette Symfony fournit la tâche database:migrate : c'est à toi de l'appeler dans le déroulé du déploiement, elle n'est pas branchée à ta place.
