Search code examples
cachingnginxdeploymentcapistrano

Nginx vhost cache symlink


I've got a problem with deploying my application. I have a PHP application and I deploy my application with Capistrano to my server.

Capistrano makes a new release folder with the latest version of my application and my current folder symlinks to the that release. That works fine, it really links the latest release.

But when I go the the URL of my website nothing changes, the files are from the old release folder even when the symlink links to the current folder (latest release).

Does Nginx cache all my files? Or does it cache my symlinks, I have no idea.

Folder structure:

 current (symlink new release)
 releases
     new release
     old release

Vhost:

server {
    listen 443;
    server_name servname.com;
    root /apps/application/production/current/public; 
}

Solution

  • The problem is at real path cache level. It caches the PHP file with the symlink path. What you need to do is provide the real document path.

    You need to add these 2 lines in your config file

    fastcgi_param DOCUMENT_ROOT $realpath_root;
    fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
    

    The important part is $realpath_root.

    From the documentation:

    $realpath_root
    an absolute pathname corresponding to the root or alias directive’s value for the current request, with all symbolic links resolved to real paths
    

    Meaning $realpath_root solves all symlinks to their real path. This is the important part.

    So your location ~ \.php$ would become

    location ~ \.php$ {
                try_files $uri =404;
                fastcgi_split_path_info ^(.+\.php)(/.+)$;
                fastcgi_pass unix:/var/run/php5-fpm.sock;
                fastcgi_index index.php;
                include fastcgi_params;
                fastcgi_param DOCUMENT_ROOT $realpath_root;
                fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        }
    

    Make sure the include fastcgi_params if present does not overwrite the 2 directives you just added.