Several versions at once
A machine can have more than one PHP installed, and that is the point rather than an edge case. An application still on 8.2 and one on 8.5 can share a server, because each site’s nginx configuration names its own FPM socket. Each site picks its version independently.Removing a version
A version still in use by a site cannot be removed. Nginx does not check that the socket it has been pointed at exists — it just fails the request — so a site left pointing at an uninstalled version answers 502 on every request without complaining anywhere you would look first. Move the sites off it, then remove it.The CLI default
One installed version is thephp on PATH. It is what a
scheduled job or a
daemon written as php artisan ... will get, and what
somebody typing php -v over SSH sees.
It is not what a site runs. A site’s requests go to its own FPM pool, and a
deploy script gets its site’s version through $SHIPWAYS_PHP. Setting the CLI
default is about the machine, not about any one site — and it is why a process
written with the full path, /usr/bin/php8.4 artisan queue:work, is the safer
form.
PHP configuration
Written into a drop-in that every installed version reads, so two versions on one machine cannot disagree about the limits. Applying restarts each FPM pool. If a pool does not come back up, the previous configuration is put back — a machine whose PHP will not start is worse than one whose upload limit is wrong.Max file upload size
One field, because there are three settings and changing one of them is what makes the whole thing look broken. Setting it to N megabytes writes:upload_max_filesize= NM — the largest single file.post_max_size= N + 8 M — the largest whole request body.- nginx
client_max_body_size= N + 8 m — the largest body nginx passes on.
post_max_size. PHP’s answer to that is to discard
$_POST and $_FILES entirely and say nothing, which is a bug report about a
form that “silently does nothing”.
With the headroom, the limit actually reached is upload_max_filesize, and PHP
reports it as UPLOAD_ERR_INI_SIZE against the field it happened on.
Nginx’s own limit matters because nginx answers 413 before PHP is started at
all. That is not a PHP error and does not appear in a PHP log, which sends
people looking in the wrong place.
Max execution time
Setsmax_execution_time, and nginx’s fastcgi_read_timeout to 10 seconds
more.
Nginx stops waiting after 60 seconds on its own. Raising only PHP’s limit gets
you a 504 from nginx at the old boundary rather than a longer request, so
both move together.