

Ask HN: How do you deploy your PHP apps to production? - smharris65

I have several php applications for various projects and the code is deployed in production using either rsync or subversion. But I want all apps to be deployed with scripts using one method for consistency. Which methods have been successful for you?
======
abyssknight
Capistrano, despite being written in Ruby, will deploy PHP. I've used it to
deploy WordPress and SMF installs once or twice. The advantage here is that
you don't have to choose git over svn or any CVS for that matter. You can keep
your configs separate and link them in.

~~~
agotterer
We use capistrano with multi-stage deployment. There is a recipe called
"railsless-deploy" that removes all the rails dependent processes
(<http://github.com/leehambley/railsless-deploy>). We also use the "git-
deployment" recipe which does auto tagging of staging and production pushes
(<http://github.com/apinstein/git-deployment>).

------
rtuck
I've tried out a few different tools now; the only two I've had any real
success with were Capistrano and Fabric.

Capistrano works well, great git integration, but it does have some rails-isms
you need to override to make it work sanely. The capistrano-php extension can
help with that: <http://github.com/namics/capistrano-php> but you'll need to
use gem to manage it. You'll also definitely want the multistage plugin which
doesn't come standard. There were some bugs present in the CVS integration
which may be a problem depending on your source control system.

I've also tried Fabric: <http://docs.fabfile.org/0.9.2/> I liked the tool. I
found it a bit more low level then Capistrano but also a little simpler to
work with. It comes prepackaged (albeit an older version) in Ubuntu without
any dependencies other than stock python which our sysadmin preferred to using
Ruby gems. I do recommend the new version found in pip though. The two main
problems with Fabric are its lack of any integration plugins and the Paramiko
SSH library it uses has no support for SSH key forwarding (there is a
workaround: [http://lincolnloop.com/blog/2009/sep/22/easy-fabric-
deployme...](http://lincolnloop.com/blog/2009/sep/22/easy-fabric-deployment-
part-1-gitmercurial-and-ssh/) but it has its own set of problems).

In the end, neither worked out for me. Capistrano had to much of a learning
curve for my co-workers and Fabric wouldn't work with our SSH setup. For now,
I'm using a script in our working directory that I SSH to, run, and it updates
the code in place. Crude, but ultimately effective. That said, definitely
looking forward to a replacement.

~~~
grumpycanuck
I was using Capistrano too but, like you, couldn't get my co-workers up-and-
running with it so we switched to using Phing. I didn't want to be the _only_
one doing deployments at work.

------
wvenable
Subversion -- the website is a working copy of the production branch and I
just do an _svn update_ when changes need to be deployed.

The whole thing is wrapped up in a script that makes it possible to one-click
deploy changes.

The biggest thing is the application is directory independent and auto-senses
the host for database selection. This means that no changes are required to
the application to run it in development, staging, or production.

Edit: Apache is setup so that no .svn directories are served. Given that most
web applications go through a front-controller now, I'm hoping this isn't as
much of a concern anymore.

~~~
jacquesm
Same here, not as nicely automated though (still need to actually type 'svn
update').

What I really like is the ability to instantly roll back to any version.

Don't forget to block .svn directories in your apache config!

~~~
jumby
umm, isn't that what svn export is for :)

why stop at .svn, how about .~, .bak, .tmp, .swp !

~~~
wvenable
The problem with export is that you're deploying every single file. With svn
update, you're only deploying the changed files.

------
atstsolutions
We have build scripts for phing, exports from subversion, migrates the
database, loads stored procs, triggers and views, creates symlinks for data
here and there, creates our dojo build layers, and builds a couple of
executables we need.

Capistrano is better for the simple stuff, but once we started doing more we
moved to phing.

~~~
dclaysmith
We have a bash script which grabs the latest Phing config/property files and
then Phing handles the rest...

* calls YUI Compressor to minify css/js * calls a custom script to upload images to the CDN * calls dbdeploy to update our staging database * symlinks the "built" revision to our staging site

When we push a build from staging to production, we run a small bash script
that calls Phing which symlinks the desired revision to the production site.

------
kylemathews
For Drupal, I use Aegir (<http://groups.drupal.org/aegir/overview>), Git, and
Make files (<http://drupal.org/project/drush_make>).

Aegir let's me spin up as many copies of my project as I want for both testing
+ production.

Git (+ github) stores all my custom development.

My Make files pull together all of my custom code + drupal contributed code +
any 3rd party libraries I'm using.

------
f1gm3nt
Right now I'm using symfony php framework that deploys the code to whatever
server I want(uses rsync and you must have access to ssh on that server). All
the projects are kept in svn repo's.

I can imagine writing a script that just runs every so often to sync the
staging server to the production server, however I don't really care for this
method because I want more control. I may change my mind in the future.

For some internal applications that I work on at work, we deploy them using
the good ol' "svn up". I really don't like this method for a ton of reasons.
The first reason being I can just goto <http://www.example.com/.svn> and see
all the svn files.

I think the best by far is using rsync. Some things that I have done with
rsync is configure the database settings in a config file, then just have
rsync ignore that file so I can set different database settings for
dev/staging servers.

For personal projects I usually have them on a private space on Assembla,
which one of the options is they allow you to FTP your code to a server. I
haven't used it myself, but I can see where this would be useful.

~~~
tonyarkles
You could use a .htaccess file to prevent the .svn directory from being
accessible, I would think

------
hlidotbe
We use Mercurial here. Easy, secure (ssh with keys) never forget files, small
transfer size, possibility of committing regularly when the client has access
to the files. With hooks, the update is done as soon as the changesets are
received.

In some cases we can even create websites on the fly with a simple "hg clone"

I guess Git allows more or less the same workflow but Mercurial is easier for
your designers.

~~~
kellishaver
Yes, I do basically this, but with Git.

------
cm
I wrote this up when I was dealing with the same issue a few months back - a
simple deploy script for PHP applications using git:
[http://themetricsystem.rjmetrics.com/2010/02/01/simple-
deplo...](http://themetricsystem.rjmetrics.com/2010/02/01/simple-deploy-
script-for-php-applications/)

------
DCoder
For hosts that support git, I simply clone/pull updates from a central repos.

For hosts that don't (i.e. we used to have one project running on a Windows
server with nothing but Remote Desktop access and no permission to install any
VCS), I use this:

    
    
        alias gdate=date\ +%Y.%m.%d-%H.%M.%S
        gitzip () { zip -ruv "$(gdate).zip" $(git diff $@ --name-only); }
    

Invoking `gitzip $commit` produces a zip file containing all the changed files
since said commit. Unzip archive to wwwroot, check for files that need to be
deleted, done.

------
ianl
I use git, with three levels, dev (active development), stage (current stable
version), and production. All three have different branches. Then I have a
bash script that configures them accordingly.

------
Ixiaus
I used to be a PHP developer (Python only now) but I still used Fabric
extensively. Rsync is invaluable, tying it in with fabric makes for a pretty
useful deployment tool.

------
bkorte
We use Trunks (<http://www.trunksapp.com>) to host our SVN repos, then have
post-commit hook fire an HTTP request to the production staging server to
check out the latest revision.

We manually initiate an export from the live server, although we likely will
look in the commit message for a keyword (like [live]) and initiate from
there.

------
sammcd
I deploy a large symfony php app with capistrano.

The only big change I needed to add was to tell it not to run the server
restarting code, other then that it wasn't that hard.

Rollback support, and the fact that I don't have to login to the server and
run commands each time I deploy is great.

------
mikelbring7
I started to use <http://www.deployhq.com/>. I was already using their
<http://codebasehq.com> for GIT hosting. Works great, server does not even
need to have GIT installed, it can use ftp or ssh.

~~~
JonnieCache
Upvoted, I've been checking this out recently. As a codebase customer they
sent me a free account to deployHQ and it seems pretty nice. It has an API
(with a rubygem) so you can integrate it into your scripts to achieve whatever
level of fancyness you need.

I'm also looking into the possibilities around having a 'deploy' or
'production' branch in git, and a post-commit hook that automatically deploys
(with another script obviously) any commits to that branch. This is how heroku
works and it's much cleaner than capistrano in my eyes.

------
ulysses
Work: rdist over ssh Personal projects: rsync over ssh

In both cases I use a wrapper script to make the push as simple as possible.
At work I push from the dev server to prod, at home I push from my desktop to
either dev or (dev and prod).

In both case I use RCS for version control.

------
aonic
bash script checks out SVN code, then uses a configuration file to build
bundles of JS and CSS files using YUI-compressor, and add query string
timestamps to CSS images for cache busting. After all that, the code is
rsync'd to various web servers

------
mithaler
We have a script that tars up projects or specific files and uploads them and
puts them in place, but lately we've been moving towards plain svn.

If it were up to me, it'd be git, with separate branches for production and
beta for easy merging.

------
koichirose
I use git with a remote repository to which you can push (and pull) stuff
easily.

~~~
ivanstojic
I do this as well, for 5 websites based on a custom PHP microframework. Git
kicks ass!

------
dangrossman
If you use <http://springloops.com/> to host your Subversion repositories,
they let you script automatic deployments upon commits to your repositories.

------
unsane1
Goodness, I hope all the people using SVN to deploy are making sure that
they're taking care of the .svn directories and the resulting security issues.

~~~
JonnieCache
I assume they're `svn export`ing rather than `svn checkout`ing.

~~~
unsane1
Yet I see at least one reference to `svn update`

I'm scurred.

~~~
gregjor
Read the whole comment. It's easy to configure Apache or whatever HTTP server
you're using to not serve anything in .svn directories. Duh.

------
mise
Since I'm only updating one PHP app at a time, I commit my changes to the SVN
repo, then SSH into the server and update.

------
sjs382
ftp a tarball then untar, or rsync.

------
willlangford
Beanstalk Hosted SVN/GIT has deployment tools. I haven't used them as I do my
pulls manually.

------
gorm
Git or rsync

------
EvanK
Capistrano + Git. Works beautifully, and rolling back bad deployments is a
breeze

------
apowell
I deploy my CodeIgniter apps via the Springloops hosted SVN service.

------
workhorse
GIT!

'nuff said.

------
syntaxritual
Vlad + Github

------
rbpasker
phpfog.com !

