Ask HN: How do you deploy your PHP apps to production?
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?
56 comments
[ 2.9 ms ] story [ 112 ms ] thread'nuff said.
If it were up to me, it'd be git, with separate branches for production and beta for easy merging.
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.
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.
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.
Capistrano is better for the simple stuff, but once we started doing more we moved to phing.
* 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.
Phing can checkout from SVN, run a mysqldump to snapshot the DB, modify text files (i.e. different .htaccess files for staging/production), run arbitrary shell commands and ping web-APIs for notification etc.
Deploys take between 10 and 30 seconds.
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.
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... 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.
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.
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.
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!
why stop at .svn, how about .~, .bak, .tmp, .swp !
simple.
priceless.
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.
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.