Deploying PHP to Amazon’s EC2 using Capistrano and Github

Reading time ~3 minutes

One of the trickier things when working in a small team with no IT department and no SCM is how to promote code to your Dev/Staging/Production environments.  On one of our projects we use a private Github repository and have an EC2 instance running Fedora so I was looking for a way to deploy code almost auto-magically.  Github has some post push hooks you can use but we have DB scripts that need to run as part of the deployment process and I want to be able to test builds locally before going to production.

Being a Rails dev at heart I had fiddled with Capistrano and Heroku.  After a few hours of messing around with it I was able to get deployments running on EC2.  My guilty pleasure is having .rb files in my PHP project =)

Quick disclaimer.  Be careful with some of this stuff.  You’ll be logged in as root to your EC2 Instance.  You can muck stuff up.  I will not be held responsible for any damage you do to your code or EC2 instance.  My recommendation is that you test this out on a Free Micro instance before trying this on your production box.

First you’ll need to install Capistrano if you haven’t already done so. (If you’re using RVM make sure you’re on your correct Ruby version)

sudo gem install -y capistrano

Next navigate to your Git project in Terminal and we’ll setup the project to use Capistrano

capify .

This step creates a few Capistrano files that we’ll be editing with the most of the work being in


To see what commands are available run cap -T from Terminal.

Open on the deploy.rb file and you’ll see some default setup values. Here’s what mine looks like after some tweaking. Keep in mind this is a very basic version and your file may vary.

set :repository,  "."
set :scm, :git
set :application, "YourAppName"
role :web, ""
role :app, ""
role :db,  "" , :primary => true
#role :db,  "your slave db-server here"
set :user, "root"
default_run_options[:pty] = true #if you don't do this you'll get a tty sudo error on EC2
ssh_options[:keys] = [File.join(ENV["HOME"], ".ssh", "id_rsa")]
set :deploy_to, "/var/www/#{application}"
set :deploy_via, :copy
# if you're still using the script/reaper helper you will need
# these
# If you are using Passenger mod_rails uncomment this:
# namespace :deploy do
#   task :start do ; end
#   task :stop do ; end
#   task :restart, :roles => :app, :except => { :no_release => true } do
#     run "#{try_sudo} touch #{File.join(current_path,'tmp','restart.txt')}"
#   end
# end

A couple of line of note. We set the user to root because this is assuming you’re using the default user setup of the EC2. Also, Capistrano tries to run sudo commands on the box as part of its deployment process so the default_run_options[:pty] option sets a pseudo sudo =). And the path is going to be your path to your web app. Capistrano deploys to a /current subdirectory in that path so make sure you update your conf, vhost, hosts files accordingly.

Alright so now with Capistrano all set up let’s copy our keys to our EC2 instance.

scp -i ~/path/to/your/ec2keypair ~/.ssh/ [email protected]:/root/.ssh/authorized_keys2

Last but not least run.

cap deploy:setup
cap deploy

Now log into your EC2 and checkout the path to your application. You should have a current and release directories full of files.

Disclosure: I did run into some issues along the way that I did not document here. That said I did run into quite a few snags so if you have any issues post a comment and I’ll try help. You may also need to have Git installed on your EC2 instance. A simple Yum install will suffice while you’re logged in as root.

But if it all worked out gloriously then buy me a beer the next time you see me because I just saved you the cost of hiring an SCM.

Writing Node.js Apps from Scratch

Satirical posts regarding the bloat of modern day apps are a hot topic of both memes and [dev discussion boards](… Continue reading

Servicing Your Actual Customer

Published on May 26, 2016

Testing your APIs with Cucumber

Published on August 02, 2015