
Ruby on Rails brought with it a lot of good practices in regards to code structure and maintenance. At least for me, my experience with RoR two years ago was the first time I’d used subversion and deployed my code (via capistrano).
Even though I use PHP on my day-to-day, there’s no reason why PHP can’t be deployed like RoR. So let’s learn a thing or two from the RoR community and create a deploy script for PHP.
What does it mean to ‘deploy’ your code? Deployment is more than just a fancy name for syncing your svn repository with your web root. Deploying your code lets you:
- exclude certain files (i.e. those pesky .svn folders),
- put up a ‘maintenance’ page while your large upload is running,
- set permissions automagically,
- leave only ssh (and www) access open on your live server,
- deploy to multiple locations at once across servers (for testing, clustering, etc),
- and perhaps even compress your code on the fly.
Besides, saying ‘deploy’ every day kind of makes me feel like the commander of a starship battle group!
Unfortunately, deployment options for PHP seem pretty meager, so I figured I’d give you a peek into the custom way we do it, in case it’s helpful to you in your work.
I’m assuming you’re already using subversion. If you’re not, you should. Even if you’re on windows, using TortoiseSVN makes using svn as easy as pie. Its long-term benefits far outweigh the short setup time. Just use it.
I also assume you are running a dedicated server. It will be hard to implement this on a shared server due to the probable lack of rsync.
Here at Xobni, our process is pretty simple:
The deploy script
#! /bin/bash
# folders in wwwroot you want to include in deploy
sites=( domain.com common scripts )
# check for required root or sudo access
if [ “$USER” != “root” ]; then
echo “Please run as root”
exit 1
fi
Make sure to replace the elements in the {sites} array with the various folders you want to deploy to your www root. Also, the script checks for the root access it will need to svn up and such. Alternately, you could just run it as a privileged user.
Now we need to check to make sure our deploy script has not been updated. Since the deploy script is itself in the svn repository, we want to make sure we’re using the very latest.
# check for updated version of this script
MODDATEF=$(sudo stat -c %Y /var/www/deploy/scripts/deploy.sh)
svn up /var/www/deploy/scripts
MODDATEL=$(sudo stat -c %Y /var/www/deploy/scripts/deploy.sh)
chmod 755 /var/www/deploy/scripts -R
if [ “$MODDATEF” != “$MODDATEL” ]; then
echo “Deploy script updated. Please run again.”
exit 1
fi
Next we need to get the parameters from the script call to see what the user wants us to do, and then run an svn up:
TEST=0
# GET PARAMETERS
while getopts “:dtr:” optname
do
case “$optname” in
“d”)
echo “*** Will DEPLOY! ***”
DEPLOY=1
;;
“r”)
REVISION=$OPTARG
;;
“t”)
TEST=1
DEPLOY=1
echo “TEST deploy”
;;
*)
echo “error: unexpected parameter”
exit 1
;;
esac
done
# inform the user if we are rolling back
if [ !$REVISION ]; then
echo “Not rolling back, -r NUM to rollback”
else
echo “ROLLBACK to rev num $REVISION”
fi
# SVN UP (or down) SITES
for site in ${sites[@]}
do
if [ $REVISION ]; then
#echo “Rolling back to rev num $REVISION”
svn up /var/www/deploy/$site -r $REVISION
else
#echo “svn to latest revision. run with -r NUM to rollback”
svn up /var/www/deploy/$site
fi
done
Now that we’ve svn updated our root, we’re ready to deploy if the right parameter has been specified (-t or -d). Note that we set up passwordless ssh between our servers, which I recommend if you want a single-command deploy.
deploysite=”/var/wwwroot”
predeployloc=”/var/www/deploy”
#rsync options to use
deployoptions=”–compress –delete –progress –exclude .svn –archive -e ’ssh -p 22′”
# note: deploys to test dir always, and live dir only if deploy
if [ $DEPLOY ]; then
for site in ${sites[@]}
do
# WWW
su - privledgeduser -c “rsync $deployoptions $predeployloc/$site privledgeduser@265.265.265.265:$deploysite-test”
echo “TEST - WWW deploy completed ($site)”
if [ $TEST != 1 ]; then
su - privledgeduser -c “rsync $deployoptions $predeployloc/$site privledgeduser@265.265.265.265:$deploysite”
echo “LIVE - WWW deploy completed! ($site)”
fi
done
echo “Completed!”
else
echo “Did not deploy: run with -d to deploy”
fi
Be sure to change ‘privledgeduser’ to the passwordless user, and 265.265.265.265 to your remote server’s ip address.
Now, when you run deploy.sh, with one line you’ll be taking care of syncing your site to the very latest in your svn repository!
Ok, so maybe commanding ships into battle would be more fun, but you have to admit it’s a thrill when your infrastructure works so seamlessly. One of these days I’m going to convince the guys to install a flashing red light above my desk that I can activate when I deploy. To the stars we go!
Posted on March 14th, 2008 by plusbryan
Filed under: Development, Infrastructure | 1 Comment »