It's a PHP app. How can I minimize the downtime while updating the entire codebase?
migrated from stackoverflow.com Nov 18 '11 at 3:32
What we generally do, at work is :
All this process is done via an automatic script (the only not-automatic thing is us launching it when needed). This means :
Of course, this doesn't prevent you from testing the new version on your staging server before putting it to production -- but, who knows... Sometimes, there is a really big bug that no-one has been able to see while testing :-(
Here is some kind of a quick example : suppose I have this VirtualHost in my Apache configuration :
Pretty "standard"... The only thing is
Notice that the symlinc points to the "old version"
Now, that the new version has been totally uploaded to the server, let's switch :
And, now, the
And we just have to restart Apache :
The three steps "remove the link ; create the new link ; restart apache" should be made quickly ; ie, by an automated script, and not by a human being.
Using this solution :
And if using some opcode-cache like APC with the stat option at 0, it can mean even less risk of downtime, I suppose.
|show 9 more comments|
Can't you take the existing code and migrate the project into a separate test php file, and use that while you are making your updates? What I mean is, you should have a test server and a production server so that when you have to make an update you don't incur any downtime.
Set up a second server with the updated codebase and switch them as fast as possible. :-)
If not possible, make sure your codebase is divided into dozens of smaller parts. Then the downtime would be limited to just one subpart one at the time. The smaller codeblocks are easier to replace and most will just continue to run without problems. Just try this on a test environment first, though!
First off, I often use and like a method similar to Pascal MARTIN's response.
Another method that I also like is to use my SCM to push new code. The exact process depends on your type of SCM (git vs svn vs ...). If you're using svn, I like to create an "online" or "production" branch that I checkout as the document root on the server. Then, whenever I want to push new code from another branch/tag/trunk, I just commit the new code into the "online" branch and run svn update in the document root. This allow for very easy rollbacks as there is a complete revision log of what's gone up/down to the server and who did it and when. You can also easily run that "online" branch on a test box, allowing you to vet the app you're about to push.
The process is similar for git and other styles of SCM, just modified to be more natural for their style of work flow.
Want to pull/poll instead of pushing updates? Just have a cron job or other, smarter mechanism automatically run svn update.
Extra: You can also use this process to backup files that your application wrote to disk. Just have a cron job or some other mechanism run svn commit. Now the files your application created are backed up in your SCM, revision logged, etc. (ex., if a user updates a file on disk, but wants you to revert it, just push the old revision).
I use a similar approach to Pascal MARTIN's, too. But instead of uploading multiple versions of my app to the production server, I keep the "builds" behind my firewall, each in a separate directory with the build number and date. When I want to upload a new version I use a simple script that includes "rsync -avh --delay-updates". The "delay=updates" flag will upload everything (that's different) to a temporary folder until all the updates are there, and then move everything over at once at the end of the transfer to their proper paths so the app will never be in a half-old-half-new state. It has the same effect as the method above, except I only keep one version of the app on the production site (best to only have only the bare essential files on the production server, IMO).