🔄 Rsync
Synchronisation incrémentale locale et distante, avec exclusions, reprise de transfert et mode daemon.
rsync calcule les différences entre la source et la destination : seuls les blocs modifiés sont envoyés. C’est ce qui le rend rapide même sur des volumes importants.
Syntaxe de base
# Copie locale (équivalent cp -a mais avec les deltas)
rsync -avz /source/ /destination/
# Copie vers un serveur distant
rsync -avz /source/ user@host:/destination/
# Copie depuis un serveur distant
rsync -avz user@host:/source/ /destination/
# Forcer l'utilisation d'un port SSH spécifique
rsync -avz -e "ssh -p 2222" /source/ user@host:/destination/Options essentielles
| Option | Description |
|---|---|
-a | Mode archive : récursif, préserve permissions, timestamps, liens, groupe, owner |
-v | Verbeux : affiche les fichiers transférés |
-z | Compression durant le transfert (utile sur lien lent) |
--delete | Supprime les fichiers de la destination absents de la source |
--exclude | Ignore des fichiers/dossiers (pattern) |
--dry-run | Simule sans modifier — excellent pour vérifier |
-P | Progress + reprise de transfert |
--bwlimit=KBPS | Limite de bande passante (ex: --bwlimit=5000 = 5 Mo/s) |
--chown=user:group | Forcer l’owner/group sur les fichiers créés |
--info=progress2 | Barre de progression (rsync 3.2+) |
Schémas source/destination
# Local → Local
rsync -av /src/ /dst/
# Local → Distant (SSH, port 22)
rsync -av /src/ user@host:/dst/
# Distant → Local
rsync -av user@host:/src/ /dst/
# Distant → Distant (via serveur source)
rsync -av userA@host1:/src/ userB@host2:/dst/
# Via un socket daemon rsync
rsync -av rsync://host:8730/module/src/ /dst/Le piège de la barre oblique finale
# ⚠️ source/a/ → crée /dst/a/ (contenu dupliqué)
rsync -av /src/a/ /dst/
# Résultat : /dst/a/fichier.txt
# ⚠️ source/a → crée /dst/a/ (dossier dupliqué)
rsync -av /src/a /dst/
# Résultat : /dst/a/a/fichier.txtRègle : la barre oblique finale sur la source applique le contenu du dossier. Sans barre oblique, rsync recrée le dossier lui-même.
Exclusions
# Exclusion unique
rsync -av --exclude='node_modules' /src/ /dst/
# Exclusion multiple
rsync -av \
--exclude='.git' \
--exclude='node_modules' \
--exclude='*.log' \
--exclude='*.tmp' \
/src/ /dst/
# Fichier d'exclusion externe (utile pour les listes longues)
rsync -av --exclude-from='.rsyncignore' /src/ /dst/Fichier .rsyncignore :
# Ignorer les fichiers
node_modules/
.git/
*.log
*.tmp
# Ignorer les dossiers entiers
build/
dist/
.envOptions avancées
Affichage détaillé des changements (-i)
L’option --itemize-changes (ou -i) affiche un code court (10 à 14 caractères) pour chaque fichier traité. Utile pour comprendre exactement ce qui sera modifié avant d’exécuter une sync destructive.
Format du code (>f.stcuog.Dest par exemple) :
| Position | Codes | Signification |
|---|---|---|
| 1 | >, <, =, ! | Direction : > vers dest, < depuis src, = identique, ! supprimé |
| 2 | c, t, M, u, m, s, h, g, x, . | Motif de changement : checksum, date, permissions, owner, group, taille, hash, xattr, . identique |
| 3 | z ou . | Compression durant le transfert |
| 4 | p ou . | Version du protocole rsync |
| 5 | . | Toujours un point (réserve) |
| 6 | S ou D | Côté impacté : source ou destination |
| 7 | O ou N ou . | Ancienne ou nouvelle version |
| 8 | O ou N ou . | Ancienne ou nouvelle version |
| 9 | . | Toujours un point (réserve) |
| 10 | f, d, l, c, b, n, s, i, . | Type : fichier, répertoire, symlink, char-device, block-device, fifo, socket, autre |
Remarque : la longueur totale du code varie selon les changements détectés. Seuls les changements réels sont codés ; les positions non appliquées prennent la valeur ..
# Exemple de sortie typique : `>f.stcuog.Dest`
# signifie : fichier créé sur la destination (`>`), de type fichier (`f`),
# avec une taille et un checksum différents (`stcuog`).
rsync -avz -i /src/ user@host:/dst/ 2>&1 | head -20Sync sélective via répertoire de référence (--compare-dest)
Synchronise uniquement les fichiers nouveaux ou modifiés par rapport à un répertoire de référence, sans modifier ce dernier. Pratique pour déployer une version spécifique ou répercuter des changements entre environnements.
# Seulement les fichiers qui ont changé depuis la référence
rsync -avz --compare-dest=/reference/ /src/ user@host:/dst/
# Comparer par rapport à un tag git spécifique (local)
rsync -avz --compare-dest=/repos/myapp/v1.2.0/ ./dist/ user@staging:/opt/myapp/current/Snapshots avec liens durs (--link-dest)
Crée un lien dur vers les fichiers identiques au snapshot précédent. Permet des backups ou des déploiements multi-version sans doublonner les données inchangées.
# Déploiement avec snapshot versionné (zéro downtime)
NEW=/opt/myapp/releases/v1.3.0
PREV=/opt/myapp/releases/v1.2.0
mkdir -p "$NEW"
rsync -avz --link-dest="$PREV" \
--exclude='.git' --exclude='node_modules' \
./dist/ "$NEW/"
ln -sfn "$NEW" /opt/myapp/current
# Backups incrémentaux sans duplication
rsync -avz --link-dest="/backups/latest/" \
/var/lib/mysql/ "/backups/$(date +%Y%m%d%H%M)/"
ln -sfn "/backups/$(date +%Y%m%d%H%M)" /backups/latestIgnorer les timestamps des répertoires (--omit-dir-times)
rsync synchronise aussi les dates de modification des répertoires, ce qui peut provoquer des rebuilds inutiles (make, webpack) si la destination se retrouve avec des timestamps légèrement différents.
# Ne pas toucher aux timestamps des dossiers
rsync -avz --omit-dir-times /src/ user@host:/dst/Ne créer que les fichiers existants (--existing)
Empêche rsync de créer de nouveaux fichiers ou dossiers sur la destination. Utile pour rafraîchir uniquement le contenu existant (ex. : mise à jour incrémentielle de _node_modules_ sans recréer des dossiers vides).
# Mettre à jour uniquement les fichiers déjà présents
rsync -av --existing /src/ user@host:/dst/Mode daemon (serveur rsync)
Côté serveur
# /etc/rsyncd.conf
pid file = /var/run/rsyncd.pid
log file = /var/log/rsyncd.log
[website]
path = /var/www/html
comment = Site web statique
read only = yes
list = no
uid = www-data
gid = www-data# Démarrer le daemon
sudo rsync --daemon --config=/etc/rsyncd.conf
# Vérifier l'écoute
ss -tlnp | grep 873Côté client
# Lister les modules disponibles
rsync rsync://host/
# Sync depuis un module
rsync -av rsync://host/website/ /local/dst/
# Avec authentification (fichier mot de passe côté client)
echo "mon_secret" > ~/.rsync_pass
chmod 600 ~/.rsync_pass
rsync -av rsync://user@host/website/ /local/dst/ --password-file=~/.rsync_passsystemd (alternatif)
# /etc/systemd/system/rsyncd.service
[Unit]
Description=Rsync daemon
After=network.target
[Service]
ExecStart=/usr/bin/rsync --daemon --no-detach --config=/etc/rsyncd.conf
Restart=on-failure
[Install]
WantedBy=multi-user.targetsudo systemctl enable --now rsyncdCas pratiques
Déploiement staging
# Sync code + exclusions vers staging, suppression des fichiers orphelins
rsync -avz --delete \
--exclude='.git' \
--exclude='node_modules' \
--exclude='.env' \
--exclude='*.log' \
./deploy/ user@staging:/opt/myapp/current/Backup incrémental quotidien
# Archive avec dates, pas de --delete (on conserve l'historique)
DATE=$(date +%Y%m%d)
rsync -avz --backup --backup-dir="/backups/${DATE}" \
/var/lib/mysql/ /backups/mysql-latest/Miroir de assets statiques
# Miroir complet, suppression des fichiers supprimés en source
rsync -avz --delete -e ssh \
--exclude='*.DS_Store' \
/srv/assets/ user@cdn:/srv/mirror/assets/Reprendre un transfert interrompu
# Reprendre automatiquement grâce à -P
rsync -avP /gros_fichier/ user@host:/dst/Alias utiles
# ~/.bashrc
alias rsync-dry='rsync -avz --dry-run'
alias rsync-deploy='rsync -avz --delete --exclude=".git" --exclude="node_modules"'
alias rsync-mirror='rsync -avz --delete'Dépannage
Permission denied
# Vérifier les permissions sur la destination
ls -ld /destination/
ls -la /destination/
# Forcer l'ownership si nécessaire
rsync -av --chown=www-data:www-data /src/ user@host:/var/www/
# Sur le serveur rsync, vérifier rsyncd.conf :
# "uid" / "gid" / "read only" / "list"
# Test en mode verbeux :
rsync -avz --info=progress2 user@host:/src/ /dst/ 2>&1 | head