Recently I’ve been putting time into rebuilding the server infrastructure for
Holiday API.
This has included hardening the system to be more fault tolerant and building
out a new cluster of web servers. The biggest improvement was [finally]
introducing a continuous deployment pipeline to complement the existing
continuous integration flow.
Everything has come together quite swimmingly, and I was even able to flip the
switch this past weekend, without any downtime.
That’s not to say things came together as smoothly as I would have liked. This
has been something I’ve been chipping away at for the last week or two, tweaking
and tuning along the way.
The biggest issue I ran into was in regard to how the code was being linked on
the server. Originally I was deploying to a single directory, no symbolic
linking (or symlinking) involved at all.
With the new deployment flow, I opted to build the release and then symlink to
the “current” release. This was all then symlinked to a directory in /var/www/
to marry up with how the existing Docker configuration works.
Nothing revolutionary or anything and everything actually worked great. When the
deployment pipeline ran, new code would go live and all was well.
That was, until I made a change to the primary index.php
file in the document
root. This particular file’s changes would not register until I restarted the
php-fpm
service.
Changes to other PHP files were picked up immediately. The issue was limited to
the aforementioned index.php
file in the document root.
The old web server didn’t have this issue, so I knew it had something to do with
the new server’s configuration. Without knowing for certain, I assumed it had
something to do with the symlinks that were now in play.
At this point, I did quite a bit of web searching, and ran into quite a few web
sites that were discussing getting PHP files to serve correctly with nginx, and
not necessarily anything related to my issue.
Finally, I stumbled upon a Stack Overflow post that seemed like what I was
experiencing, but sadly was scummed up by some asshole letting the original
poster know that their issue wasn’t well researched at all and they shouldn’t
have even posted the question.
There’s always a critic, right?
This was my first time running into the issue, and at least for me and my
Google Fu, it was a pain in the butt to find a solution for the issue.
That said, after more research, going through the nginx documentation and some
experimenting, I did figure things out. It had to do with the php-fpm
portion
of my nginx configuration file.
Originally, the configuration for my server, looked a little something like this
(abridged for the sake of this post):
server {
location ~ .php$ {
try_files $uri =404
include /etc/nginx/fastcgi_params
fastcgi_pass unix:/run/php/php-fpm.sock
fastcgi_index index.php
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name
}
}
The big issue here is the $document_root
variable being used in the
fastcgi_param
.
As I came to find out, when using symbolic links, that particular variable ends
up being converted to an absolute path and is effectively cached when the server
starts or something like that.
Fortunately, there’s another variable that doesn’t does fall victim of this
alleged caching. The $realpath_root
variable is a drop in replacement for the
$document_root
.
The updated file looked more like this:
server {
location ~ .php$ {
try_files $uri =404
include /etc/nginx/fastcgi_params
fastcgi_pass unix:/run/php/php-fpm.sock
fastcgi_index index.php
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name
}
}
After quick restart of both nginx and php-fpm
, I went ahead and deployed some
new code that affected the index.php
in the document root. After deployed, the
changes were showing up and all was well again!