php runtime and server environment
Common Server Mistakes
Many PHP deployment failures are server configuration problems, not application bugs. A junior developer does not need to be a full-time systems administrator, but should recognise the symptoms well enough to look in the right place.
This lesson focuses on the mistakes that commonly appear with PHP-FPM, Nginx, Apache, Caddy, and framework front controllers.
PHP files download instead of executing
If visiting /index.php downloads PHP source code, the web server is serving .php files as static files. That is a serious security problem because source code, secrets, and business logic may be exposed.
Likely causes:
- no PHP handler is configured
- the PHP handler is disabled
- the request is not matching the
.phplocation or handler rule - the server is pointing at static files but not passing PHP to PHP-FPM
Do not leave this online while debugging. Remove public access or roll back the configuration first.
Wrong document root
Modern PHP applications often expect the public document root to be public/.
/var/www/app
├── app/
├── config/
├── public/
│ └── index.php
├── vendor/
└── .env
The web server should expose /var/www/app/public, not /var/www/app. If it exposes the project root, users may be able to request files that should never be public.
<?php
declare(strict_types=1);
$documentRoot = $_SERVER['DOCUMENT_ROOT'] ?? 'not running through a web server';
$scriptFile = $_SERVER['SCRIPT_FILENAME'] ?? 'no script filename';
echo 'Document root: ' . $documentRoot . PHP_EOL;
echo 'Script file: ' . $scriptFile . PHP_EOL;
// Example output from CLI:
// Document root: not running through a web server
// Script file: no script filename
Run a diagnostic like this through the web server if you need to confirm what it is actually exposing.
Bad SCRIPT_FILENAME
With FastCGI, the web server tells PHP-FPM which script file to execute. If SCRIPT_FILENAME points to the wrong path, PHP-FPM cannot find the script.
Common symptoms:
Primary script unknown
File not found.
404 for every PHP route
In Nginx, this often comes from a bad combination of root, alias, fastcgi_param SCRIPT_FILENAME, and fastcgi_script_name.
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
The exact expression depends on the rest of the server block, but the goal is simple: PHP-FPM must receive the real path to the PHP file that should run.
502 Bad Gateway
A 502 usually means the web server could not get a valid response from the upstream PHP runtime.
Likely causes:
- PHP-FPM is stopped or restarting
- the
fastcgi_passsocket or host does not match the PHP-FPM pool - socket permissions block the web server user
- PHP-FPM is overloaded and cannot accept connections
- PHP-FPM crashes while handling the request
Check the web server error log and PHP-FPM log before editing application code. Those logs usually show whether the problem is connection refused, permission denied, timeout, missing socket, or upstream closed connection.
Static assets work, routes fail
If /css/app.css works but /account/settings returns 404, static file serving is probably fine but front-controller routing is missing.
A typical Nginx rule for a front-controller application is:
location / {
try_files $uri /index.php$is_args$args;
}
For Apache, the equivalent is often handled by rewrite rules in virtual host config or .htaccess.
Safe debugging order
Use symptoms to avoid random changes:
- If PHP source downloads, disable public access and fix the PHP handler.
- If private project files are public, fix the document root.
- If all PHP requests fail with "File not found", check
SCRIPT_FILENAME. - If the response is 502, check PHP-FPM reachability and logs.
- If only pretty URLs fail, check rewrite or front-controller routing.
- If PHP runs but the application fails, then move into application logs and code.
What you should be able to do
After this lesson, you should be able to map common PHP server symptoms to likely configuration problems, explain why the document root should usually be public/, and know which logs to check before changing application code.
Practice
Task: Diagnose Server Symptoms
Create a troubleshooting table for common PHP deployment symptoms.
Requirements
- Include PHP source downloading in the browser.
- Include wrong document root exposing project files.
- Include
Primary script unknownorFile not found. - Include
502 Bad Gateway. - Include static assets working while application routes fail.
- For each symptom, write the likely cause and the first log or configuration file you would check.
Check your work
The table should help someone decide where to look before changing PHP application code.
Show solution
Symptom: Browser downloads index.php source code
Likely cause: The web server is serving PHP as a static file instead of passing it to PHP.
Check first: Web server PHP handler, Nginx PHP location block, Apache handler/module, hosting PHP setting.
Symptom: /vendor, /.env, or /composer.json is reachable
Likely cause: The document root points to the project root instead of public/.
Check first: server root, DocumentRoot, hosting panel document root.
Symptom: Primary script unknown or File not found
Likely cause: FastCGI SCRIPT_FILENAME points to the wrong file path.
Check first: Nginx fastcgi_param SCRIPT_FILENAME, root/alias usage, PHP-FPM error log.
Symptom: 502 Bad Gateway
Likely cause: The web server cannot reach PHP-FPM or PHP-FPM is failing.
Check first: web server error log, PHP-FPM service status, fastcgi_pass value, socket permissions.
Symptom: Static assets work, but /account/settings returns 404
Likely cause: Front-controller routing is missing or rewrite rules are disabled.
Check first: Nginx try_files rule, Apache rewrite rules, Caddy php_fastcgi/file_server order.
This kind of table keeps debugging focused. A server handoff failure should be investigated in server config and logs before changing controllers, routes, or framework code.