# De rsync au déploiement zéro downtime : notre migration vers Deployer

> rsync nous convenait très bien, jusqu'à ce qu'un déploiement en pleine journée coupe le site pendant douze secondes de trop. Voici pourquoi et comment on est passés à Deployer.

- Auteur : Clément Hadrot
- Publié le : 2022-07-06
- Mis à jour le : 2022-07-06
- Catégorie : Outils &amp; workflow
- URL : https://wpmoderne.dev.wordpress-developpement.fr/outils/deployer-zero-downtime-migration-rsync/

## L’essentiel

- Chaque déploiement crée un nouveau dossier horodaté, jamais d'écrasement
- Un lien symbolique bascule instantanément vers la nouvelle version
- Rollback en une commande en cas de problème

Notre script rsync a très bien fonctionné pendant deux ans, sur des dizaines de projets. La bascule est arrivée sur un site à trafic soutenu : un déploiement en pleine journée a provoqué douze secondes d'erreurs 500, le temps que rsync termine de transférer les fichiers modifiés pendant que des requêtes arrivaient sur une version partiellement mise à jour du code. Douze secondes, ce n'est rien la nuit. En pleine journée sur un site marchand, ça se traduit en commandes perdues.

C'est ce qui nous a poussés vers [Deployer](https://deployer.org/), un outil de déploiement PHP pensé spécifiquement pour le déploiement atomique — c'est-à-dire sans jamais laisser le serveur dans un état intermédiaire entre deux versions du code.

## Le principe du déploiement atomique

Contrairement à rsync qui modifie les fichiers en place, Deployer crée à chaque déploiement un nouveau dossier complet et horodaté, puis bascule un lien symbolique vers ce nouveau dossier une fois le déploiement terminé et validé. La bascule elle-même, une simple opération de lien symbolique, est quasi instantanée :

```
/var/www/site/
├── releases/
│   ├── 20220612153000/
│   ├── 20220628091500/
│   └── 20220706104500/   ← version en cours de déploiement
├── shared/
│   ├── wp-content/uploads/
│   └── .env
└── current -> releases/20220706104500/
```

Le dossier `shared` contient tout ce qui doit persister entre les déploiements — les uploads, la configuration d'environnement — et qui est lié symboliquement dans chaque nouvelle release plutôt que dupliqué.

## Un fichier de configuration Deployer pour WordPress

> L'essentiel à retenir : Chaque déploiement crée un nouveau dossier horodaté, jamais d'écrasement ; Un lien symbolique bascule instantanément vers la nouvelle version ; Rollback en une commande en cas de problème

```
<?php
namespace Deployer;

require 'recipe/common.php';

set( 'repository', 'git@github.com:agence/mon-site.git' );
set( 'shared_files', [ '.env' ] );
set( 'shared_dirs', [ 'wp-content/uploads' ] );
set( 'writable_dirs', [ 'wp-content/uploads', 'wp-content/cache' ] );

host( 'production' )
    ->setHostname( 'serveur.exemple.fr' )
    ->set( 'remote_user', 'deploy' )
    ->set( 'deploy_path', '/var/www/site' );

task( 'wordpress:cache-flush', function () {
    run( 'cd {{release_path}} && wp cache flush' );
} );

after( 'deploy:symlink', 'wordpress:cache-flush' );
after( 'deploy:failed', 'deploy:unlock' );
```

Le déploiement s'exécute ensuite en une commande, depuis n'importe quel poste avec un accès SSH configuré :

```
dep deploy production
```

## Le rollback, la vraie différence avec rsync

C'est la fonctionnalité qui justifie à elle seule la migration : en cas de problème détecté après déploiement, revenir à la version précédente ne demande qu'une commande, puisque l'ancienne release existe toujours intacte sur le disque.

```
dep rollback production
```

Avec rsync, un retour arrière signifiait reconstituer manuellement l'état précédent depuis une sauvegarde ou un commit Git antérieur — une opération lente, stressante, et sujette à erreur au pire moment possible. Avec Deployer, c'est une bascule de lien symbolique, aussi rapide que le déploiement lui-même.

## Comparatif rapide avec notre ancienne approche

| Critère | rsync | Deployer |
| --- | --- | --- |
| Interruption pendant le déploiement | Quelques secondes, état intermédiaire possible | Aucune, bascule atomique |
| Rollback | Manuel, lent | Une commande |
| Complexité de mise en place | Faible | Modérée |
| Gestion des dossiers partagés (uploads) | Via exclusions rsync | Native, via liens symboliques |

## Ce que la migration nous a coûté

La mise en place initiale a pris plus de temps que notre script rsync : il a fallu adapter la structure des dossiers sur le serveur pour accueillir le schéma `releases`/`shared`/`current`, et reconfigurer le serveur web pour pointer vers `current` plutôt que vers un chemin fixe. Sur des projets avec peu de trafic, où quelques secondes d'interruption ne changent rien, on continue d'ailleurs à utiliser rsync : Deployer ne se justifie pas systématiquement.

> La règle qu'on applique désormais : en dessous d'un certain trafic, rsync reste largement suffisant. Au-dessus, ou dès qu'un rollback rapide devient une vraie nécessité opérationnelle, Deployer change la donne.

## En résumé

Passer de rsync à Deployer n'était pas une question de mode, mais une réponse concrète à un incident précis : une interruption de service, même brève, sur un site à trafic soutenu. Le déploiement atomique et le rollback en une commande ont justifié la complexité de mise en place supplémentaire, sur les projets où l'enjeu de disponibilité le méritait vraiment.
