It's a popular strategy for the web server to reference the current build via symlink, and to switch the symlink to deploy a new build
/var/www/current -> /var/www/build-1
Is this a problem for requests running when the symlink is switched, given that scripts reference other files during execution, and those files have been modified in the new build?
If so, do you think this disqualifies it as a strategy for a service that requires high-availability?
Is it a better strategy to update Nginx's config to reference the new build directly and run service nginx reload? I assume reload allows current requests to complete on the old build, while sending new requests to the new build.
If it's relevant, I'm specifically interest in PHP and Laravel.
Packaging content as a directory like you suggest has the advantage of making it easier to version, archive, install and revert.
Changing the path of the content in the httpd configuration is not required. The intent of the serving the current version of the deployed application has not changed. Updating content directories in httpd servers happens all the time.
Minimizing the time of the transition helps reduce the window of version skew where only some files are different. Use of symlinks makes atomic switches possible, not strictly required but might as well try for a clean transition.
(Or
exch
program as of util-linux 2.40 can atomically swap real directories, but is Linux only.)On POSIX systems, in general, open files that are removed are still open. The file handles are by inode not by name. However that is the old version. Anything long running should be told somehow to close what they have open.
PHP is relevant for the implementation details. Many installs these days are separate php-fpm processes. Sending it USR2 signal will gracefully reload workers and its config. Read your service manager's documentation for how to send that, such as on systemd Linux
systemctl reload
Reloading the http server can also be necessary. When it serves static content directly. For in process languages like httpd with mod_php. For config changes. Same thing, usually there is a graceful reload signal.
High availability is the design and implementation of what you want your uptime target to be. A graceful reload of php-fpm and nginx might only cause a very brief blip in service as the new workers start. By itself that might be fine for some use cases. However, even if content updates is almost no downtime, eventually a reboot for software updates will be required. If those few minutes of infrastructure downtime is a problem for your organization, even the most graceful reload is not a complete HA solution.
Starting multiple http servers and putting them behind a load balancer is a pattern that is described all over the place. Putting them on different hosts prevents a variety of faults from stopping the service entirely, improving uptime. Further, it becomes possible to drain all connections from a process, and do whatever maintenance on it at your leisure.
Some of these deployment methods intend for different versions to be running at the same time. Discipline during development helps, especially for shared resources or APIs. Perhaps there is an opportunity to restructure database queries in version 2. A transition period where the database can do queries of version 1 or 2 makes deployment easier. Rolling install and reload, one backend at a time, take some time to check for a tolerable number of errors. Easy to put version 1 back, or complete the install of 2.
For high-availability services, switching the symlink can cause issues with active requests referencing different builds. Reloading Nginx is a better approach for zero-downtime deployments.