160

I'm beginning a new project in PHP and I'd love to get some feedback from other developers on their preferred strategy for PHP deployment. I'd love to automate things a bit so that once changes are committed they can be quickly migrated to a development or production server.

I have experience with deployments using Capistrano with Ruby as well as some basic shell scripting.

Before I dive head first on my own it would be great to hear how others have approached this in their projects.

Further information

Currently developers work on local installations of the site and commit changes to a subversion repository. Initial deployments are made by exporting a tagged release from svn and uploading that to the server.

Additional changes are typically made piecemeal by manually uploading changed files.

3

15 Answers 15

109

For PHP, SVN with Phing build scripts are the way to go. Phing is similar to ANT but is written in PHP, which makes it much easier for PHP developers to modify for their needs.

Our deployment routine is as follows:

  • Everyone develops on the same local server at work, every developer has a checkout on his machine back home as well.
  • Commits trigger a post-commit hook which updates a staging server.
  • Tests are ran on staging server, if they pass - continue.
  • Phing build script is ran:
  • Takes down production server, switching the domain to an "Under construction" page
  • Runs SVN update on production checkout
  • Runs schema deltas script
  • Runs tests
  • If tests fail - run rollback script
  • If tests pass, server routes back to production checkout

There's also phpUnderControl, which is a Continuous Integration server. I didn't find it very useful for web projects to be honest.

8
  • I was about to post a list of what I do at my Windows/.NET shop, but it's more or less what you've got here. +1 Commented Jan 8, 2009 at 20:21
  • have you encountered any disadvantages for having a svn co as a production environment? I really can't think of any disadvantages but it doesn't seem "clean" to have a svn co as production? Why not an svn export or rsync?
    – ChrisR
    Commented Nov 10, 2010 at 18:11
  • Because of the basic difference between a co and an export - you can't push specific changes, you have to export the entire application again. It's a very important difference that makes life that much easier Commented Nov 10, 2010 at 22:50
  • 36
    Why put up the site down screen? If you run a directory of releases/, and point liveSite/ via a symlink to your folder in releases/, then you can completely checkout the site into a new releases/ folder and flip the symlink over instantaneously once the co is done? No need for downtime (unless you are the poor sob that makes a request during that symlink switch). Commented May 20, 2011 at 20:38
  • 2
    Who is responsible for doing all those tasks such as update SVN on production and symlinkin the new release? Is it phing? Is it jenkins? Commented Jul 14, 2013 at 15:00
24

I'm currently deploying PHP using Git. A simple git push production is all that's needed to update my production server with the latest copy from Git. It's easy and fast because Git's smart enough to only send the diffs and not the whole project over again. It also helps keep a redundant copy of the repository on the web server in case of hardware failure on my end (though I also push to GitHub to be safe).

7
  • I've been doing the same thing for years on small- to medium-sized projects as well. I've got to say, it's been working great for me. You've got to love the simplicity of this approach. Commented Jun 15, 2011 at 16:46
  • 3
    How do you handle the database with this approach? Commented Aug 16, 2011 at 8:05
  • 1
    @neilc By hand, unfortunately. Any changes to the DB need to be manually performed before the push. Commented Aug 16, 2011 at 8:13
  • I usually include() a PHP file that contains the DB config, and manually place the file on the server or test machine. That way you're not storing passwords in git and also not accidentally operating on a production database.
    – Matt
    Commented Jan 31, 2014 at 13:36
  • How do you configure git to do this for you? Is there any guide/tutorial? Thank you in advance. Commented Jan 5, 2015 at 15:03
14

We use Webistrano, a web frontend for Capistrano, and are very happy with it.

Webistrano allows multi-stage, multi-environment deployments from SVN, GIT and others. It has built-in rollback support, support for separate server roles such as web, db, app, etc., and deploys in parallel. It allows you to override config parameters on multiple levels, such as per stage, and logs the results of every deploy, optionally mailing it.

Even though Capistrano and Webistrano are Ruby applications, the syntax of the deployment 'recipes' is easy and powerful enough to understand for any PHP programmer. Originally Capistrano was built for Ruby on Rails projects, but easily accommodates PHP projects.

Once configured it is even easy enough to be used by non-programmers, such as testers deploying a staging version.

To provide the fastest deploy possible we installed the fast_remote_cache method, which updates a svn working-copy cache on the remote server, and then hardlinks the result.

6

I use Apache Ant to deploy to different targets (dev, QA and live). Ant is designed to work for Java deployment, but it provides a pretty useful general case solution for deploying arbitrary files.

The syntax of the build.xml file is pretty easy to learn - you define different targets and their dependencies which run when you call the ant program on the command line.

For example, I have targets for dev, QA and live, each of which depends on the cvsbuild target which checks out the latest head revision from our CVS server, copies the appropriate files to the build directory (using the fileset tag), and then rsyncs the build directory to the appropriate server. There are a few quirks to learn, and the learning curve is not totally flat, but I've been doing it this way for years with no trouble so I'd recommend it for your situation, though I'm curious what other answers I'll see on this thread.

6

I do stuff manually using Git. One repository for development, which gets git push --mirror'ed to a public repo, and the live server is a third repo pulled from that. This part I suppose is the same as your own setup.

The big difference is that I use branches for nearly every change I'm working on (I've got about 5 right now), and tend to flip back and forth between them. The master branch doesn't get changed directly except for merging other branches.

I run the live server direct from the master branch, and when I'm finished with another branch and ready to merge it, flip the server to that branch for a while. If it breaks, putting it back to master takes seconds. If it works, it gets merged into master and the live code gets updated. I suppose an analogy of this in SVN would be having two working copies and pointing to the live one via a symlink.

3

I know Phing has been mentioned a few times now, but I've had great luck with phpUnderControl. For us we

  1. Check out individual copies of branches to local machines
  2. Branches are tested and then merged into Trunk
  3. Commits to Trunk are automatically built by phpUnderControl, runs tests and builds all documentation, applies database deltas
  4. Trunk gets run through quality testing and then merged into our Stable branch
  5. Again, phpUnderControl automatically builds Stable, runs tests, and generates documenation and updates database
  6. When we're ready to push to production we run a rsync script that backs up Production, updates the database, and then pushes the files up. The rsync command is invoked by hand so that we make sure someone is watching the promotion.
1
  • 5
    phpUnderControl is dead :|
    – m02ph3u5
    Commented Aug 20, 2015 at 15:23
3

an alternative to home-made deployment scripts is to deploy to a platform-as-a-service which abstracts away a lot of that work for you. A PaaS will typically offer its own code deployment tool, as well as scaling, fault-tolerance (eg. not going down when hardware fails), and usually a great toolkit for monitoring, log checking etc. There's also the benefit of deploying to a known good configuration which will be kept up-to-date over time (one less headache for you).

The PaaS I would recommend is dotCloud, in addition to PHP (see their PHP quickstart) it can also deploy MySQL, MongoDB and a whole bunch of additional services. It also has nice goodies like zero-downtime deployment, instant rollback, full support for SSL and websocket, etc. And there's a free tier which is always nice :)

Of course I'm slightly biased since I work there! Other options worth checking out in addition to dotCloud are Pagodabox and Orchestra (now part of Engine Yard).

Hope this helps!

Solomon

2

I am way late to the party, but I thought I would share our methods. We use Phing with Phingistrano, which provides Capistrano-like functionality to Phing via pre-built build files. It is very cool, but only works if you use Git at the moment.

1

That you automatically and blindly take changes from a repository to production servers sounds dangerous. What if your committed code contains a regression bug, so your production application gets glitchy?

But, if you want a Continuous Integration system for PHP, I guess Phing is the best choice for PHP. I haven't tested it myself, though, as I do stuff the manual way of e.g. scp.

1

I have a working copy of an SVN release branch on the server. Updating the site (when there aren't schema changes) is as easy as issuing an SVN update command. I don't even have to take the site offline.

2
  • 1
    so you have .svn directories scattered all over the site? my purist brain goes against this:)
    – Stann
    Commented Apr 24, 2011 at 3:30
  • This only takes care of the source code. Deployments often need other actions taken - database changes applied, caches cleared, etc. Commented May 8, 2014 at 11:35
1

Phing is probably your best bet, if you can stand the pain of xml configuration files. The Symfony framework has its own port of rake (pake), which works quite well, but is rather tightly coupled to the rest of Symfony (Though you could probably separate them).

Another option is to use Capistrano. Obviously it doesn't integrate as well with PHP, as it does with Ruby, but you can still use it for a lot of stuff.

Lastly, you can always write shell scripts. So far, that's what I have done.

1

http://controltier.org/wiki/Main_Page

we are going to use it for multi-server deployments & maintenance.

1

One year late but... In my case, deployment is not automatic. I find it dangerous to deploy code and run database-migration scripts automatically.

Instead, subversion hooks are used to deploy only to testing/staging server. Code is deployed to production at the end of an iteration, after having run tests and made sure things will work. For the deployment itself, I use a custom-made Makefile that uses rsync for transferring files. The Makefile may also run the migration scripts on the remote server, pause/resume web and database servers.

1

At my work myself and my team have developed a Phing oriented replacement for capistrano's deploy and we've also incorporated some of the goodies available in phing like PHPUnit testing, phpcs and PHPDocumentor. We've made it a git repo that can be added to a project as a submodule in git and it works very well. I've attached it to a handful of projects and it's modular enough that it's easy to make it work with any project on any of our several environments (staging, testing, production, etc...).

With the phing build scripts you can run them from the command line manually, and I've also had success automating the build/deploy routines with Hudson and now Jenkins ci.

I can't post any links now because the repo isn't public yet, but I've been told we're going to open source it sometimes soon, so please feel free to contact me if you're interested or if you have any questions on automating your deployment with phing and git.

0

I guess SVN deploy way is not very good. Because:

You need to open the SVN access for the whole world

have many .svn in the production web servers

I think Phing to produce a branch + combine all the js/css + replace stage config + ssh upload to all www servers is better way.

ssh to 10 www server and svn up is also trouble.

1
  • Opening my svn server to the whole world, no way! Just use your firewall and authentication over ssl to limit who can see your code.
    – Shadok
    Commented Sep 26, 2012 at 15:34

Not the answer you're looking for? Browse other questions tagged or ask your own question.