Fixing Symlinked Release Issues with PHP Deployer and Nginx
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 requestSCRIPT_FILENAME
tells PHP-FPM the actual file path to executeDOCUMENT_ROOT
ensures PHP knows the correct document root for the current release
Implementation Steps
- Update your Nginx configuration with the lines above
- Test the configuration for syntax errors:
sudo nginx -t
- 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.