TIL: rsync’s --link-dest
is pretty bad for deploying code to production servers, unless you can get some fancy copy-on-write going on.
Rsync is probably the best utility to transfer large numbers of files from one location to another, quickly and effectively. The --link-dest
argument allows you to hard-link files from a different destination if they haven’t changed, saving both time on transfer, as well as disk space.
It’s perfect for backups, and seemed to me like it would be a good idea for code deployments as well. But I was wrong.
Deploying to production means you have a particular copy lying around, that is not unlikely to change especially in single-server setups, where user actions, such as a WordPress core or plugin update, can lead to changes on the filesystem.
So if you change a file that happened to be hard-linked to other releases lying around for a potential emergency rollback, then you’ve effectively just borked them all :(
$ mkdir -p releases/1
$ echo good > releases/1/wp-config.php
$ rsync -rt --link-dest=../1/ releases/1/ releases/2/
$ rsync -rt --link-dest=../2/ releases/2/ releases/3/
$ rsync -rt --link-dest=../3/ releases/3/ releases/4/
$ ln -sfn releases/4 latest
$ echo bad > latest/wp-config.php
# I screwed up, I'm going to roll back to release 1.
# Which I know was good... Right?
$ cat releases/1/wp-config.php
bad
Next best option is --copy-dest
just to speed up transfer, but not preserve disk space.