views:

354

answers:

6

I don't really know how to perform deployment from offline development to live webserver correctly in web development. I mostly resort on intuition, but this is more or less what I did until now: I have a web application in python, or php, and I am hosting it on a live webserver. I use an offline development version whose source is under svn.

Now, as I develop the offline version, I will perform commits to the svn. When time has come for release, I could either:

  1. copy the code from the offline server to a temporary directory on the live webserver, then swap the old codebase with the new one (eg. with a link), or...
  2. have the live webserver work on a checkout svn, and just run svn update.

I normally do the second, although if I have to upgrade the database before the live deployment, I normally write upgrade sql scripts, and run them first on the live database, then checkout.

What are the best practices for this task ?

+1  A: 

In theory I would export the svn to a new area on webserver. Then reconfigure the webserver to use new area and restart.

grigy
+4  A: 

You should consider some deployment scripts to automate all this. it will help prevent you from making mistakes. SQL upgrade scripts are a way of life, but you should always test them on a copy of the live database before you run them on them on the real one.

What you might consider having is a staging server. You do your local changes, then svn checkout to the staging server and run your upgrade scripts there as well. You do your acceptance test on the staging server. When everything is good, you deploy everhting to the live server. This should be as simple as running some scripts. i.e. update-staging.pl and update-prod.pl.

You can make your sql script easier to automate by adding a version table to your db. whenever you create an update script, you tag it with a version. then the deployment script can look at the version of your update script, and the version of the database and apply the updates as needed. this also makes restoring from backups feasible. If you have made changes, then restore to a backup, you just run your upgrade script and it goes through and updates the db to the current version.

Byron Whitlock
indeed, I also write "rollback" scripts whenever possible. I don't know how useful it is, since I won't reinsert the data, but at least I will have a way to downgrade the SQL structure, just in case.
Stefano Borini
+9  A: 

I recommend leveraging SVN export instead of checkout. This way, you will not expose any of the SVN files to the world. It also generally creates a cleaner folder structure.

I have leveraged rsync before when moving files between stage and production.

My typical deployment proceeds as follows:

  • backup production site
  • Restore from backup to stage server
  • Lock the server down from all external IP addresses
  • Export the code from the repository into a temp folder (optionally diff the two folders for small changes)
  • rsyc files from the temp folder to the stage server folder
  • Validate that only the files you expect to have changed have actually changed.
  • Apply SQL scripts to the DB
  • Test the upgrade
  • Unlock the webserver

Now, to deploy to production, replay these steps in fast forward. Using scripts make it much easier.

TheJacobTaylor
I agree, but if you have alot of files, svn export can be SLOW!
Byron Whitlock
It's trivial on most webservers to set up a filter that makes it not serve .svn folders, so I wouldn't take that as a reason against using "svn update". It is something to keep in mind when you first set up the server though.
rmeador
well, in general speed is not an issue if you are exporting from a local (disk or network) svn. or is it ? I mean, not that svn is fast. far from it.
Stefano Borini
Good point on the web server filters. Unfortunately, I have found that people will frequently forget why things are setup a particular way and then change them later to "enhance security" or something along those lines. If you do publish folders containing your SVN stuff, make sure to have a simple program that verifies they are still blocked. I recently encountered a regression where log files were being published due to this kind of issue.If SVN is slow, you can perform a local export and then rsync from there. Thankfully rsync is fast.
TheJacobTaylor
SVN get slower the more you use it. To recreate a file, I believe that it has to go back through all revisions of the file patching it to get to the current version. For repositories with lots of changes per file, this can be rather painful. Recently, I have been using and loving GIT. It stores the latest version and can retrieve it immediately.
TheJacobTaylor
+2  A: 

I use Capistrano to script & automate the deployment process. Here's an outline of what happens when I enter cap deploy from my local workstation:

Capistrano will. . .

  1. Checkout latest version of source in a time-stamped directory (e.g. to /var/http/mywebsite.com/releases/20090715014527) on my webserver, prompting me @ my local workstation for any passwords, if necessary.

  2. Run pre-processing scripts (e.g. update database schema)

  3. Soft link the site to a live directory:

    ln -sf /var/http/mywebsite.com/releases/20090715014527 /var/http/mywebsite.com/current

  4. Run post-processing scripts (e.g. maybe you need to restart apache or something)

If there were any problems along the way, Capistrano will rollback to the previous working release.

Although Capistrano is written in Ruby, it can deploy web applications in any language/framework. See the "Deploying non-rails apps" section of the tutorials for ideas. The railsless-deploy seems particularly useful for using Capistrano to manage deploying PHP and Python apps.

Pete
+1  A: 

for small, php-based systems, what we used to do is this:

for code changes, we use an ant script running from eclipse that compares the local (dev) system with the remote (qa/prod/whatever) systems, then zips all the changed files, scp the zip to the remote system and unzip it on the target. Of course we have automated backup and the like. If this is of interest I would be able to post an example script in the next few days.

for sql changes, we try to maintain a scripts for each change (usually in our bug-tracker) and manually run each change on the target system.

for large systems you shoudl really use something more robust.

note that if your prod system is pulling directly from svn then you are deplolying changes that might have not been tested properly (you might forget to commit something, test you local system, and everything would break in prod...)

Nir Levy
about zip: what about deletion of old files then ?+1 for the last remark. I've been bit.
Stefano Borini
actually, i keep the old zip files all the time. I name them yyyymmddhhmiss.zip so i can always know exactly what code was put on prod exactly when and can even (painfully) revet to old versions if my backups fail. I only delete them when i start running out of disk space.
Nir Levy
+1  A: 

I would recommend the first option. If you have a structure where you can put versions of the code and flip between them by changing a link, it is much easier to roll back than if you just have an svn checkout. With svn you have to merge with a previous version to revert.

docgnome