Skip to content

Fixing Symlinked Release Issues with PHP Deployer and Nginx

By Jasper Frumau

When using PHP Deployer for zero-downtime deployments, you might encounter a frustrating issue where Nginx continues serving cached content from previous releases instead of loading the latest symlinked code. This happens because Nginx resolves the symlink path once and caches it, rather than following the symlink to its current target on each request.

The Problem

PHP Deployer creates a directory structure like this:

/var/www/app/
├── releases/
│   ├── 20240101120000/  # Previous release
│   ├── 20240101130000/  # Current release
│   └── ...
├── shared/              # Shared files (logs, uploads, etc.)
└── current -> releases/20240101130000/  # Symlink to current release

When you deploy a new release, the current symlink gets updated to point to the new release directory. However, Nginx’s PHP-FPM configuration often resolves this symlink once and continues serving files from the old path, defeating the purpose of zero-downtime deployments.

The Solution

To fix this issue, you need to modify your Nginx PHP block to use $realpath_root instead of the default $document_root. Add these two lines to your PHP location block:

location ~ \.php$ {
    # ... your existing PHP-FPM configuration ...
    
    # Add these lines to resolve symlinks dynamically
    fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
    fastcgi_param DOCUMENT_ROOT $realpath_root;
    
    # ... rest of your PHP-FPM configuration ...
}

What This Does

  • $realpath_root resolves the symlink to its actual target directory on each request
  • SCRIPT_FILENAME tells PHP-FPM the actual file path to execute
  • DOCUMENT_ROOT ensures PHP knows the correct document root for the current release

Implementation Steps

  1. Update your Nginx configuration with the lines above
  2. Test the configuration for syntax errors:sudo nginx -t
  3. Reload Nginx to apply changes:sudo systemctl reload nginx

After this one-time setup, your deployments will work seamlessly. When PHP Deployer creates a new release and updates the current symlink, Nginx will automatically serve content from the new release without requiring any server reloads.

Benefits

  • True zero-downtime deployments: No need to reload PHP-FPM or Nginx after each deployment
  • Immediate content updates: New releases are served instantly after the symlink update
  • Simplified deployment process: Eliminates manual intervention in your deployment pipeline
  • Better developer experience: Code changes appear immediately without cache-clearing steps

This configuration ensures that your deployment process remains automated and your users always see the latest version of your application immediately after deployment completes.

Comments are closed for this post.