PHP Deployment

Learn how to deploy PHP applications the proper way using Capistrano.

Introduction

Picture this scenario: You’ve finished your work for the week, it’s time to relax, but you get an urgrent call from your client, “Matt!, There’s a bug on the site. It needs fixing now!”. You quickly scramble to get it fixed as fast as possible, so you login to the server, edit the file from the terminal and the day is saved “hooray”.

There are a few flaws with this method of fixing bugs, lets see what they are:

  • Since the file was edited directly there’s no change log, so you’ll have to keep a personal record. Wouldn’t it be easier if you could add notes (or messages) when you commit changes to code?
  • The patch didn’t work and now you have to roll back (sigh). You should have tested locally first, but you were so frantic you forgot (it happens). How would you roll back quickly and easily? If it takes more than a second then it’s too long.

It’s a slow and error prone way of dealing with an emergency. I wonder how we can make this better …

Using version control

I’ll be using Bazaar for my deployment, but there’s a huge choice out there. Here are a few you might be interested in: Git, Subversion, CVS or Mercurial

sudo aptitude install bzr

Set up capistrano

Capistrano is client side software which means we are done touching the server (for now). Prerequisites for deployment are:

  1. capistrano
  2. capistrano-ext (used for its multi-stage plugin)
  3. railsless-deploy (overrides rails actions that don’t apply to PHP)

Writing the recipe

I’ll assume you have a local code repository setup and populated with content.

From a directory outside of the code repo (unless you want to version your recipe files) run

capify .

Here is the output of that command:

[add] writing './Capfile'
[add] making directory './config'
[add] writing './config/deploy.rb'
[done] capified!

Since I’ll be using the multi-stage plugin (you don’t have to) I need to modify the “Capfile” that was generated.

load 'deploy' if respond_to?(:namespace) # cap2 differentiator

require 'rubygems'
require 'railsless-deploy'
require 'capistrano/ext/multistage'

set :stages, %w(staging production)
set :default_stage, "staging"

Here we have included the extensions, defined our stages and setup a default stage. All self explanatory. Recipes follow the following structure:

config/deploy/:stage

Using cap production deploy will use config/deploy/production.rb, for example.

You can find an example recipe on my gist page.

From here on out it’s normal capistrano deployment procedure so I wont bother repeating what’s on the internet already. I’m happy to answer any questions you may have though.

This entry was posted in Capistrano, PHP and tagged . Bookmark the permalink.

6 Responses to PHP Deployment

  1. Nick says:

    Nice guide – I’m planning to take a look at Capistrano at some point, so this’ll come in handy :-)

  2. Isaiah says:

    Great post! Now Capistrano has been officially added to my “things to learn” list ;)

  3. Toddler says:

    Nice one! This proved very useful for me, although I had many issues trying to get it to work on with VirtualBox and Ubuntu.

    I have a little suggestion for your recipe file though, I changed the last 2 lines to:

    before :deploy, "deploy:web:disable"
    after :deploy, "deploy:web:enable"

    Because I noticed Kohana spit out errors while deploying the app, instead there should be the maintenance page. Anyways, just a minor issue ;)

  4. Thank you for taking the time to write this up. I have been doing some research on staged deployments, and this answered the last couple of questions that I had lingering. Thank you!

  5. AlexOgol says:

    I want to quote your post in my blog. It can?
    And you et an account on Twitter?

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>