Relative symlinks
We all use symbolic links (also known as symlinks) on Linux or other Unix systems. It’s an easy way to create a shortcut to a file or folder that is located in another directory. The ln binary allows us to create these links, both hard links and symbolic links.
Symlinks in the deployment process
Symlinks are very popular in the deployment process. People deploy the latest version of their code in a separate folder and link to production folder to it. Creating the link is an atomic action that can be reverted quite easily. When a deployment would fail, rolling back just means linking the production folder to the previous release.
And quite often there are files that are shared across versions and that are not part of the deployment. These are usually static assets: pictures, stylesheets, javascript files, web fonts, logs, …
Those files are usually symlinked too, but from within the specific version of the sofware.
An example
Imagine you deploy a web application that has a backend where users can upload files. These uploaded files aren’t under the control of the developer and can change at any given time. A normal deployment would overwrite or wipe these files, which is unacceptable.
In this example we have a “files” folder that contains user uploads. To be on the safe side, we store them outside of the application root.
This is what the symlink could look like:
lrwxrwxrwx 1 www-data www-data 43 Mar 8 15:23 files -> /home/myuser/files
And this is the commando to create the symlink:
ln -s /home/myuser/files files
The problem
In some cases the deployment server is not the webserver itself. Some deployments are done to a separate gateway server that has the filesystem mounted (e.g. via NFS).
There is a possibility that the absolute paths are different and that “/home/myuser/files” doesn’t exist on that machine. Maybe it’s “/opt/jail/home/myuser/files”. Creating such a symlink will cause errors and your shared resources will not be loaded.
The solution: relative symlinks
Relative symlinks could save the day: just create the symlink on your deployment machine, but add the “relative” parameter. The “ln command” will then convert the absolute path to a relative one. That path can be resolved on the webservers and won’t cause much trouble.
This is what the symlink could look like:
lrwxrwxrwx 1 www-data www-data 43 Mar 8 15:23 files -> ../../files
And this is the commando to create the symlink:
ln -rs /home/myuser/files files
Notice the “-r” parameter.