Search code examples
web-deploymentatomicswapfile-renameupdating

atomic way of deploying website updates?


When uploading changed files to a live webserver, how do I enforce at any given moment, my entire file set is either in the old state, or new, but never something in between?

With 'in between' I mean some files old and some new, or some particular file being overwritten halfway, et cetera.

Suppose I have a directory called foo/ on my live webserver containing a framework or bunch of script files including eachother, and I need to replace a whole bunch of files at the same time. I'd call this an 'atomic update'.

The closest I can get is uploading my new foo/ directory (containing the new files) to a different name, e.g. bar/, and then on a shell on the webserver I do:

mv foo foo-old; mv bar foo;

But this way there is still a tiny fraction of a second where foo/ doesn't exist, when the old dir has just been renamed and the new dir is about to.

Is there a 100% correct way of doing this? I guess I need some sort of 'atomic swap', to rename or swap two directory names as a single, atomic action on file system level.

In case it's OS dependent: I'm using a webserver running CentOS and got SSH access.


Solution

  • Near-atomic

    The simplest way to achieve a near-atomic change of directories is to use a symbolic link as your web root, which you can re-point to a different location when upgrading.

    $ mkdir old
    $ mkdir new
    $ ln -s old live
    $ ls -l
    live -> old
    new
    old
    

    ...

    $ ln -snf new live
    live -> new
    new
    old
    

    Changing the target of a symbolic link is actually a 2 step operation internally, unlink followed by symlink.

    Atomic

    An atomic change of directories can be achieved by creating a secondary symbolic link which points to a new directory, and then renaming the new symbolic link into the old symbolic link.

    $ mkdir old new
    $ ln -s old live
    $ ln -s new live_new
    $ mv -fT live_new live
    

    mv command will use a single atomic operation (rename) to overwrite the old symbolic link with a new one.

    Network layer atomic

    Use 2 separate hosts (physical or virtual) and route every new user from a defined moment in time to a new host which contains the upgraded website.