Deploying new code live
What's the best practise to deploy new code on a live (e-commerce) site?
For now I have stopped apache for +/- 10 seconds when renaming directory public_html_new
to public_html
and old to public_html_old
. This creates a short down-time, before I start Apache again.
The same question goes if using Git to pull the new repo to the live directory. Can I pull the repo while the site is active? And how about if I need to copy a DB as well?
During the tar (backup purpose) compression of the live site I noticed that changes occurred in the media directory. That indicated to me that files keep on changing periodically. And if these changes can interfere if Apache is not stopped during deployment.
Using a load balancer is a good idea. If the site is important enough to worry about a few seconds of downtime, it's important enough to worry about fault tolerance.
That aside, if this is on a UNIX system you can put Apache on hold during the rename (or symlink update, etc.):
killall -STOP httpd # Pause all httpd processes
mv public_html public_html_orig
mv public_html_new public_html
killall -CONT httpd # Resume all httpd processes
This will keep Apache from accepting new requests during the rename. If you prefer symlinks or some other approach, the same idea can be used:
killall -STOP httpd # Pause all httpd processes
rm /var/www/html
ln -s /var/www/version/03 /var/www/html
killall -CONT httpd # Resume all httpd processes
Note that any pending connections or packets will queue up in the OS. For an extremely busy site, consider tuning ListenBacklog if appropriate for your httpd worker type, and check your OS settings related to TCP listen backlog.
You could also change DocumentRoot in httpd.conf and do a graceful restart (apachectl graceful
). The drawback here is the increased risk of errors, since you'd have to update any Directory
configuration as well.
The fastest and easiest is to use a version directory such as
/var/www/version/01
/var/www/version/02
and use a current symbolic link as your html_root :
/var/www/html -> /var/www/version/02
This technique integrate perfectly into a revision control system (svn, git, mercurial, ...) as you can checkout branches & tags, changes the symbolic link and reload Apache. The downtime is minimal using this technique and it allows very easy rollback.
It also integrate well with more complex deployment system such as RPM packages, or configuration change management (chef, puppet, etc) infrastructure.
Renaming the directories without shutting Apache down should work as well. That will shorten the window significantly. mv public_html public_html_old && mv public_html_new public_html
should finish in a fraction of a second.
A couple of drawbacks are that this approach will give a 404
to any request that still manage to happen during the window. And if you run the above command without having a public_html_new
directory it will fail and leave you with a site giving 404
on every request.
Doing it atomically with directories is not support. But you could do it with symlinks. Instead of having a directory named public_html
, have a directory named public_html.version-number
and a symlink called public_html
pointing to that directory. Now you can create a directory called public_html.new-version-number
and a new symlink called public_html.new
.
Then you can rename public_html.new
to public_html
to switch atomically. Notice that mv
is "too intelligent" to perform that rename, but it could be done using os.rename
from python or anything else which will call the rename
system call without trying to be smart.
What to do with the data base depends on what database you are using, and what you are using it for. You need to provide a lot more details about the database before we can give you a good answer to that part of your question.