Use rsync to deploy your website
breckyunits.com
breckyunits.com
http://stackoverflow.com/questions/279169/deploy-php-using-g...
The file ignore-files would contain the keywords or files to ignore, one per line.
* "-C" to exclude all common revision-control working directory files. Lowest filter priority, consider the rest of your args.
* Look up backup rsync guides and add snapshot or "--backup-dir" support to your deploys for a cheap alternative to system snapshots and other deployment reversion techniques.
* "-E" and "-X" for when you just want to apply execute settings and not blow away whatever custom permissions you may have on your deployed files ("--chmod" is also helpful here)
* "--delete-after" and "--delete-excluded" to clean up files you've deleted from your source files.
* "--timeout=120 --contimeout=60" Because nobody needs to wait 5 minutes to find out their deploy failed.
* "--compress-level=9"
* If you have a huge deploy tree, it may be faster (though less reliable) to run
find SRC -mtime -8 -print0 > files.txt && rsync OPTIONS --from0 --files-from files.txt DEST
This will make a list of only the past 7 days' worth of modified files to attempt to rsync, which may cut down on the total time to deploy considerably.* "--log-file=/big/partition/deploy.log" To get a better idea of how the deploy is going or how it went.
* Consider if you need --delay-updates to make the deploy more atomic. If files get deployed a few at a time, will this cause the user experience to suffer? Load as well as long file lists can cause long periods between updates.
* If you have more than one developer that can deploy to the site at the same time, consider that rsync should only be your file-transfer tool. You need a whole other layer to account for transaction locking, who is deploying or reverting files, and basic logging is very handy to track down problems. But that's a bit out of scope for this link :)
A "proper" deployment must be (at least):
* Completely automated. Should be just a simple command line.
* Atomic. As in all the files are changed at once.
* Easily revertible.
If your are deploying a db-backed application, deployment process also must manage db versioning (including possibility of rollbacks).
All of the above is trivially provided by Vlad or Capistrano. And since they are super easy to use even for non Ruby projects, I fail to see the reason to keep using ftp or rsync other then laziness.
I've seen some people using git for deployment, which is better then ftp/rsync, but still lacks in atomicity and rollbacks can be quite tricky.
I use svn export for deployments - all sorted by revision into static cached directories, then symlinked to HTTP root.
This has the added advantage of being able to roll back to any previous version instantly.
Sending diffs removes your ability to roll back at all, or if you're somewhat devious about it, it still wouldn't allow you to roll back more than a single version.
I'm surprised you're so concerned about time-to-deploy for an action that happens, what, once a day at most? Twice? The amount of safeguard you gain for the trivial non-human-time (it's not as if some guy is sitting there copying files) increase is pretty massive.
What happens when your 300MB deploy needs to be pushed from your development machine out to 15 different production servers? I wouldn't want to send ~4.3GB for every deployment. Furthermore, a quick deployment time is valuable when a crucial fix needs to be pushed to production.
This is not to mention the space that your 300MB deploy is going to take up on the hard drives of your production machines if you deploy twice a day. That's over 213GB a year per machine, sounds like you would need to start deleting old revisions. Or start just sending the diffs.
It is a handy tool for dealing with versioning and rollback. But i'd hate to be the guy who deploys a hot fix and suddenly rpm is out of locker entries.
#!/bin/sh
RSYNC="/usr/bin/rsync" # Verify with 'which rsync'
DIRS="/home/xich /etc" # Directories to be backed up.
TARGET="/mnt/secondhd/backup" # Directory into which all backups are placed.
# For instance, if TARGET is /mnt/secondhd/backup and DIRS is "/home/user1 /home/user2"
# then after running, there will exist a /mnt/secondhd/backup/user1 and
# /mnt/secondhd/backup/user2. DO NOT use trailing slashes for any of these paths,
# as that will change the behavior of rsync.
LOGFILE="/var/log/mirror_hds.log" # For errors only.
for dir in $DIRS; do
INEX=""
if [[ -e "$dir/.mirror_include" ]]; then
INEX="--include-from $dir/.mirror_include"
fi
if [[ -e "$dir/.mirror_exclude" ]]; then
INEX="$INEX --exclude-from $dir/.mirror_exclude"
fi
$RSYNC -av --delete $INEX $dir $TARGET &> $LOGFILE
done
The .mirror_include and .mirror_exclude files are just newline-delimited lists of file masks (they do what you would expect). I did it like this so each user can modify his own exclusion/inclusion lists (the file belongs to the user), and doesn't have to mess with the cron script (which belongs to root). Inclusion takes precedence. As an example, my exclude file: .* # any file that starts with a period
tv # my tv shows directory
movies
And my include file: .mirror_include # since this would be filtered out above
.mirror_exclude
.conkyrcI actually put the rsnyc command in a Makefile so I can update by typing `make`.
I have a folder in my ~ directory which contains a folder for each of the remote machines I work with. I can update any remote machine by going into its folder and typing `make`.
A majority of our time before was spent updating both our codebase then checking external dependencies on each server. Rsync made this process much quicker since these checks are completed once then pushed to each server.
#!/bin/bash
# run in the project root
git add -A # track added files
git commit # local commit
git push # push to remote bare repository
ssh REMOTE_HOST 'cd PROJECT_FOLDER; git pull' # expand a working folder from the remote bare repository; usually public www folder is contained there
extra benefits: two copies of complete history for backup local and remoteBut for various reasons (mainly rollback, history and consistency(rsync takes time, time in which your site has files from different versions) I much prefer the "schlep entire codebase into new directory and then switch symlinks when your ready to go live". Such as Fabric, Capistrano, or your custom deploy scripts do.
"schlep" is the technical term for scp/rsync/checkout/etc.
rsync -arvuz /src/foo /dest/foo/
but at the bottom it's rsync -arvuz /src/foo/ /dest/foo
Which is correct?What about partial successes?
It is pretty robust, but, syncing multiple files is not an atomic operation across the batch as a whole. So if one file fails you do get an err report. But the other files would have been synced. Once you fix whatever the problem is and you re-run your script, that one file will then be synced.
In practice, rsync is really great for deploying. It is also neat for backups - in fact, before I got my Mac and started using Time Machine, I used rsync for backups (and in fact used rsync.net for offsite backups).