Recommended Free Tools
Run PHP as FastCGI by letting Apache handle HTTP requests and forwarding only PHP requests to PHP-FPM through Apache’s mod_proxy_fcgi module. PHP-FPM manages the PHP worker processes and listens on a Unix socket or TCP address. Once the endpoint, socket permissions, virtual host mapping, and document root agree, Apache can serve PHP without loading PHP directly into its own process.
Antihost offers Linux VPS plans with full root access, unlimited traffic on a 1 Gbps port and a 14-day free trial.
This guide shows a distribution-neutral deployment, example commands for common Linux families, a complete virtual-host pattern, verification steps, and fixes for downloads, 404/403 errors, 502 responses, timeouts, and unintended PHP versions.
As an Amazon Associate I earn from qualifying purchases.
Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchPC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11What “PHP as FastCGI with Apache” means
In a FastCGI deployment, Apache is the web server and PHP-FPM is the application process manager. Apache accepts the browser connection, serves static files itself, and passes requests whose paths end in .php to PHP-FPM. PHP-FPM starts and supervises PHP workers, sends the script output back over FastCGI, and then Apache returns the HTTP response.
Apache does not start PHP-FPM for you. The service must be installed, running, and listening at the exact endpoint used by the virtual host. Apache’s mod_proxy_fcgi documentation states: “This module requires the services of mod_proxy and provides support for the FastCGI protocol.”
#1 Best Overall
PHP-FPM can listen on a Unix-domain socket such as /run/php/php-fpm.sock or on a TCP address such as 127.0.0.1:9000. A Unix socket is normally preferable when Apache and PHP-FPM are on the same machine because it avoids exposing a network listener and gives you explicit filesystem permission controls. TCP is useful when the FPM service is on another host or when your distribution already standardizes on a local port.
Why use PHP-FPM instead of loading PHP into Apache?
PHP-FPM is the modern default for Apache installations that need controlled worker pools or isolation. It keeps PHP worker management outside Apache, allows separate pools to run under different Unix accounts, and can be restarted independently of the web server. It also works with Apache’s event, worker, and prefork MPM choices, while mod_php historically imposed tighter MPM and process-model constraints.
| Area | PHP-FPM through FastCGI | mod_php |
|---|---|---|
| Process ownership | PHP-FPM owns PHP workers; Apache proxies requests. | PHP runs inside Apache processes. |
| Pool users | Each pool can have its own Unix user and group. | PHP generally runs with the Apache worker identity. |
| Worker controls | Pool settings control worker counts, spare workers, and request limits. | Controls are tied more closely to Apache’s process model. |
| Apache MPM choice | Compatible with modern Apache MPM arrangements when configured correctly. | Often requires legacy prefork combinations. |
| Restart behavior | PHP-FPM can be restarted or upgraded without restarting Apache. | Changing PHP commonly requires an Apache restart. |
| Memory behavior | Worker memory can be bounded per pool and tuned for concurrency. | PHP code is loaded into Apache processes, increasing coupling. |
| Operational complexity | Requires a running FPM service, a reachable listener, and proxy rules. | Simpler initial wiring but less flexible isolation and scaling. |
Keep mod_php only when a documented legacy application or hosting constraint requires it. Do not enable both handlers for the same virtual host: an old module or rule can intercept requests before the intended FPM mapping.
Before you configure Apache
Identify the operating system and package names
Package and service names differ by distribution and release. Debian- and Ubuntu-family systems commonly use the apache2 and php-fpm package families; RHEL-, Fedora-, and Rocky-family systems commonly use httpd and php-fpm. The PHP-FPM service may include a version suffix, such as php8.2-fpm, rather than the unqualified name php-fpm. Use the package manager’s installed-file and service information to find the actual unit and socket path instead of assuming a version.
Confirm the PHP-FPM pool listener
Open the active pool configuration and find its listen directive. Typical values are:
listen = /run/php/php-fpm.sockfor a Unix socket.listen = 127.0.0.1:9000for a local TCP listener.
Use the exact value in Apache. A path that differs by one PHP version, directory, or filename will produce a gateway error even when the FPM service itself is healthy.
Plan the document root and account boundaries
Choose the directory that contains the site’s public files, for example /var/www/html. The FastCGI backend path must correspond to that document root so that the script filename Apache sends is the one PHP-FPM can read. For applications with private configuration or uploaded secrets, keep those files outside the document root and expose only the public directory.
Install and start the required components
Install Apache, PHP, PHP-FPM, and your distribution’s FastCGI proxy support. On Debian- or Ubuntu-family systems, a typical starting point is:
Rank #2
sudo apt update
sudo apt install apache2 php-fpm
On RHEL-, Fedora-, or compatible systems, the equivalent package transaction is commonly:
sudo dnf install httpd php-fpm
These commands are examples, not universal package names. Add the PHP extensions required by your application using the names supplied by your distribution.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Enable and start both services. Substitute the actual unit name if your distribution installs a versioned FPM service:
sudo systemctl enable --now apache2
sudo systemctl enable --now php-fpm
For an Apache service called httpd, use:
sudo systemctl enable --now httpd
Check service state before editing the virtual host:
systemctl status php-fpm
systemctl status apache2
If the FPM unit is versioned, query the installed units with your service manager and use that unit consistently for status, restart, and log commands.
Load Apache’s FastCGI proxy modules
Apache needs both the general proxy module and the FastCGI provider. On Debian- and Ubuntu-family systems, enable them with:
sudo a2enmod proxy proxy_fcgi
On distributions that manage modules through configuration files rather than a2enmod, make sure the equivalent mod_proxy and mod_proxy_fcgi modules are loaded. A configuration containing proxy_fcgi without proxy is incomplete because the FastCGI provider depends on the core proxy service.
Do not enable a broad proxy rule that forwards every URL. The virtual host should send only PHP requests to FPM; images, stylesheets, JavaScript, and ordinary directories should remain Apache-served files.
Configure a virtual host with a Unix socket
The following example uses /var/www/html as the document root and /run/php/php-fpm.sock as the FPM socket. Replace both values with the paths from your server.
<VirtualHost *:80>
ServerName example.test
DocumentRoot /var/www/html
DirectoryIndex index.php index.html
<Directory /var/www/html>
Options FollowSymLinks
AllowOverride All
Require all granted
</Directory>
ProxyPassMatch ^/(.*.php(/.*)?)$ unix:/run/php/php-fpm.sock|fcgi://localhost/var/www/html/
ErrorLog ${APACHE_LOG_DIR}/example-error.log
CustomLog ${APACHE_LOG_DIR}/example-access.log combined
</VirtualHost>
ProxyPassMatch matches a PHP script, including an optional path-info suffix, and sends it to the Unix socket. The path after fcgi://localhost/ must reflect the filesystem root used by the site. If the document root is /srv/www/app/public, that backend path must use /srv/www/app/public/ instead of /var/www/html/.
Some Apache releases and distribution layouts use a SetHandler form instead. A common pattern is:
<FilesMatch .php$>
SetHandler "proxy:unix:/run/php/php-fpm.sock|fcgi://localhost/"
</FilesMatch>
Use one deliberate PHP handler for the virtual host, not several overlapping rules. The exact SetHandler path behavior depends on the surrounding directory configuration and Apache version; the ProxyPassMatch example makes the document-root mapping explicit.
Configure a TCP listener instead
If the pool declares listen = 127.0.0.1:9000, use a TCP backend:
<VirtualHost *:80>
ServerName example.test
DocumentRoot /var/www/html
DirectoryIndex index.php index.html
<Directory /var/www/html>
Options FollowSymLinks
AllowOverride All
Require all granted
</Directory>
ProxyPassMatch ^/(.*.php(/.*)?)$ fcgi://127.0.0.1:9000/var/www/html/
ErrorLog ${APACHE_LOG_DIR}/example-error.log
CustomLog ${APACHE_LOG_DIR}/example-access.log combined
</VirtualHost>
Bind a local-only listener unless another host must reach FPM. A listener on all interfaces can expose the FastCGI service to the network and should not be used casually. For cross-host FPM, restrict access with firewall rules and transport controls appropriate to your environment; a local Unix socket avoids that network exposure altogether.
Set socket ownership and permissions
Apache must be able to open the Unix socket, while unrelated users should not. In the FPM pool configuration, align these directives with the account under which Apache workers run:
listen.owner = www-data
listen.group = www-data
listen.mode = 0660
Some distributions use apache instead of www-data. Determine the actual Apache runtime user from the distribution’s service configuration and use a shared group if a separate pool account is required. Avoid 0666 or other world-writable socket modes.
Rank #4
After changing pool settings, restart or reload PHP-FPM so the socket is recreated with the new ownership. If an old socket remains after an upgrade, stop FPM, remove the stale socket only when you have confirmed no active service needs it, and start the intended FPM unit again. Never delete an arbitrary socket while a production pool may still be serving requests.
Authorize the document tree safely
The <Directory> block controls whether Apache may traverse and serve the document root. A 403 response can result from a missing Require all granted, a parent directory without execute permission, or filesystem ownership that prevents Apache from reading the script.
The Tool Desk
Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Grant read and traverse access to the public tree, but do not make the entire application writable by the web user. Upload and temporary directories should have narrowly scoped write permissions. Store environment files, database credentials, private keys, and other secrets outside /var/www/html; if a sensitive file is accidentally placed under the root, an Apache rule is not a substitute for removing it.
Validate, reload, and test
- Check the complete Apache syntax before reloading:
sudo apachectl configtestProceed only when the result is
Syntax OK. - Reload Apache without dropping established connections:
sudo systemctl reload apache2Use
httpdas the service name on systems that use it. - Create a temporary PHP test file in the document root:
printf '<?php echo "fastcgi-ok\n"; ?>n' | sudo tee /var/www/html/fcgi-test.php - Request it locally and inspect headers and body:
curl -i http://127.0.0.1/fcgi-test.phpA successful test returns an HTTP response whose body contains
fastcgi-ok, not the PHP source. - Remove the diagnostic file immediately:
sudo rm /var/www/html/fcgi-test.php
Do not leave phpinfo() or any diagnostic script on a public site. Such pages disclose PHP versions, filesystem paths, loaded extensions, environment variables, and server details.
Why is Apache downloading my PHP file?
If the browser displays or downloads PHP source, Apache is serving the file as static content instead of passing it to FPM. Check the causes in this order:
- The proxy modules are not loaded. Confirm that both
mod_proxyandmod_proxy_fcgiare active. - The rule is in a different virtual host. Verify that the request’s hostname selects the virtual host containing the PHP mapping.
- The pattern does not match. A rule limited to
.php$may not match path-info requests, while a rule placed outside the intended virtual host may never run. - An old handler overrides the new one. Remove stale
mod_php,SetHandler, or distribution snippets that target the same files. - Apache was not reloaded. Run
apachectl configtest, then reload the service after every configuration change.
Never treat source disclosure as a harmless configuration defect. Until fixed, assume any PHP file containing credentials or application logic may have been exposed and rotate secrets that could have been downloaded.
Free tools Windows power users keep installed
One-click scans. No signup required.
Why am I getting a 502 Bad Gateway from PHP-FPM?
A 502 usually means Apache cannot complete the FastCGI connection or the backend returned an unusable response. Check:
- Confirm that the intended FPM service is active and listening.
- Compare the pool’s
listenvalue character for character with the Apache socket path or TCP address. - For a Unix socket, inspect its owner, group, mode, and every parent directory’s traversal permission.
- For TCP, verify that FPM is bound to the address and port Apache uses, and that a local firewall is not blocking it.
- Read Apache’s error log and the FPM service log at the time of a fresh request.
- Check that the backend document-root path in
ProxyPassMatchpoints to the same filesystem tree asDocumentRoot.
A stale socket after a PHP upgrade can make Apache connect to nothing or to an obsolete service. Stop the old pool, clear the stale endpoint when safe, start the intended pool, and then retest. Do not mask the problem by changing socket permissions to world-writable.
Fix 404, 403, timeouts, and wrong PHP versions
404 Not Found
Check that the URL maps to a file under the selected virtual host’s DocumentRoot, that the hostname reaches that host, and that DirectoryIndex index.php index.html is present when requesting a directory. A mismatch between the URL path and the FastCGI backend path can also make PHP-FPM look for a script in the wrong directory.
403 Forbidden
Inspect Apache authorization directives, filesystem ownership, and parent-directory execute permissions. The Apache account needs to traverse every directory in the path and read the script; it does not need broad write access to the application.
Do these 3 things before closing this tab:
1Repair Windows errors before they cause bigger problems2Scan for outdated or missing drivers - takes under a minute3Clear out junk files and repair common Windows errorsRequests time out
Inspect FPM pool worker limits and Apache request timeouts. If every FPM worker is busy, new requests wait until a worker is available. Apache also warns that unsuitable connection reuse can leave PHP-FPM workers occupied and contribute to request timeouts. Review connection-reuse behavior for your Apache version and pool design rather than blindly increasing timeout values.
Tune worker limits to available memory and expected concurrency. A larger process count can increase throughput only until CPU, memory, database, or downstream limits are reached; excessive workers can cause swapping and longer outages.
The site uses the wrong PHP version
Confirm which FPM socket or TCP service the virtual host references and which PHP binary that pool runs. Disable stale virtual-host snippets and old sockets after an upgrade, then reload Apache and restart the intended FPM service. A command-line php -v result alone does not prove that web requests use the same PHP version; the web request follows the configured FPM endpoint.
Separate pools for isolation
A single shared pool is adequate for many small sites. Use separate FPM pools when applications need different PHP versions, resource limits, filesystem access, or Unix identities. A pool can run under a least-privileged account dedicated to one application, with its own socket and worker limits. Point that application’s virtual host at the pool-specific socket.
Quick wins for a faster PC:
Scan for outdated or missing drivers - takes under a minuteDriver Scan →Clear out junk files and repair common Windows errorsFree Scan →Pool separation reduces the blast radius of a compromised application, but it does not replace patching, file permissions, input validation, or database isolation. Monitor both Apache and FPM logs so you can distinguish web-server errors from pool exhaustion or application failures.
Operational checklist
- Apache, PHP, and PHP-FPM packages are installed from supported repositories.
- The intended FPM service is enabled, running, and listening at the configured endpoint.
mod_proxyandmod_proxy_fcgiare loaded.- The virtual host’s
DocumentRootand FastCGI backend path refer to the same public directory. - Only PHP requests are proxied; static assets remain Apache-served.
- Socket ownership and mode permit Apache access without world write access.
DirectoryIndex, directory authorization, and filesystem traversal permissions are correct.- Apache configuration passes
apachectl configtestbefore every reload. - Logs are monitored during deployment and after PHP or Apache upgrades.
- Temporary test files,
phpinfo(), credentials, and source archives are absent from the document root. - Apache, PHP, PHP extensions, and FPM receive security updates.
When FastCGI with Apache is the right choice
Choose PHP-FPM when you want modern Apache MPM compatibility, per-application users, independent PHP restarts, explicit worker controls, or a path toward multiple pools and versions. A Unix socket is a strong default for a same-host deployment; a loopback TCP listener is a practical alternative when the distribution or architecture already uses it.
The essential rule is simple: the PHP-FPM listener, Apache proxy mapping, document root, and socket permissions must describe the same system. Validate the configuration, test one PHP request, remove diagnostics, and then monitor both services under real load.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




