Product docs and API reference are now on Akamai TechDocs.
Search product docs.
Search for “” in product docs.
Search API reference.
Search for “” in API reference.
Search Results
 results matching 
 results
No Results
Filters
Modern PHP-FPM and NGINX Configuration
Traducciones al EspañolEstamos traduciendo nuestros guías y tutoriales al Español. Es posible que usted esté viendo una traducción generada automáticamente. Estamos trabajando con traductores profesionales para verificar las traducciones de nuestro sitio web. Este proyecto es un trabajo en curso.
PHP FastCGI Process Manager (PHP-FPM) runs PHP processes independently of the web server, enabling process isolation, independent scaling, and better resource management than mod_php or CGI implementations.
This guide shows how to deploy PHP-FPM with NGINX on Akamai cloud compute, including installation, FastCGI proxy configuration, PHP-FPM pool setup, and security hardening for Akamai infrastructure.
For full configuration options, see the official PHP-FPM and NGINX documentation.
Before You Begin
Complete these prerequisites before installing PHP-FPM and NGINX. Create and configure your instance using Akamai’s Creating a Compute Instance and Set Up and Secure a Compute Instance guides.
Create and configure your instance using Akamai’s Creating a Compute Instance and Set Up and Secure a Compute Instance guides.
For OS-level documentation, see the Ubuntu Server documentation.
Prerequisites:
- A compute instance running Ubuntu 22.04 LTS
- SSH access to the instance with a non-root user account
- Sudo privileges for package installation and service management
- Cloud Manager access to configure firewall rules
- Basic familiarity with Linux package management (apt)
Instance Sizing Reference
Instance sizing affects PHP-FPM performance, especially under concurrent load. Use this table as a planning reference when selecting your instance plan, and revisit it after deployment if you need to resize.
| Workload | Plan | RAM |
|---|---|---|
| Development/Testing | Shared CPU | 1–2 GB |
| Production: Low to Medium Traffic | Shared CPU | 4–8 GB |
| Production: High Traffic | Dedicated CPU | 8+ GB |
After deployment, monitor CPU and memory usage in Cloud Manager and adjust your instance size if needed.
Akamai-Specific Considerations
Configure platform-specific settings for your PHP-FPM deployment including firewall rules, instance sizing, and optional storage or load balancing.
Cloud Firewall Configuration
Configure Cloud Firewall rules to allow web traffic to your instance. Work through these steps promptly, as Cloud Manager sessions can time out and unsaved changes will be lost.
Navigate to Cloud Manager and select Firewalls from the sidebar under Networking.
Create a new firewall or modify an existing one.
Add each of the following as a separate inbound rule by clicking Add an Inbound Rule, completing the fields, and clicking Add Rule before starting the next:
- HTTP: Protocol: TCP, Port: 80, Action: Accept, Source: All IPv4 / All IPv6
- HTTPS: Protocol: TCP, Port: 443, Action: Accept, Source: All IPv4 / All IPv6
To apply the firewall to your compute instance:
- select the Linodes tab within your firewall
- click Add Linodes To Firewall
- select your instance from the list that appears, click outside the dropdown to close it
- then click Add.
For detailed firewall configuration, see Getting Started with Cloud Firewalls.
Development/Testing:
- Shared CPU (1-2 GB RAM) for low-traffic sites or development environments.
Production - Low to Medium Traffic:
- Shared CPU (4-8 GB RAM) for small to medium production sites.
- Supports 50-200 concurrent PHP-FPM processes depending on application complexity.
Production - High Traffic:
- Dedicated CPU (8+ GB RAM) for high-traffic applications requiring sustained CPU performance; eliminates resource contention for consistent PHP execution times
Monitor CPU and memory usage through Cloud Manager after deployment and resize as needed.
Optional: Block Storage
Consider attaching Block Storage volumes for user-uploaded content, application file storage exceeding local disk capacity, or separation of application data from system storage. Block Storage volumes are portable between instances and can be resized independently. See Block Storage documentation for setup instructions.
Optional: Load Balancer Configuration
For high-availability deployments, use NodeBalancers to distribute traffic across multiple PHP-FPM instances. Configure health checks on port 80 or 443, set session persistence if application requires sticky sessions, and ensure backend nodes run identical PHP-FPM and NGINX configurations. NodeBalancer setup is beyond the scope of this guide. See Getting Started with NodeBalancers.
Install PHP-FPM
Log in to your instance as the sudo user you create and install PHP-FPM and NGINX packages using the Ubuntu package manager. For comprehensive PHP installation options and configuration reference, see the official PHP-FPM documentation.
Install the required packages:
sudo apt update
sudo apt install nginx php8.1-fpmType “Y” and enter to continue with installation when prompted about disk space usage. You are returned to the prompt.
Then verify both services are installed and running:
sudo systemctl status nginx
sudo systemctl status php8.1-fpmBoth commands should returnactive (running) with worker processes listed. Press q to return to the command prompt.
If either service shows a status other than active (running), review the installation steps and check the system logs using sudo journalctl -u nginx or sudo journalctl -u php8.1-fpm.
Common PHP Extensions
Install additional PHP extensions based on application requirements:
sudo apt install php8.1-mysql php8.1-xml php8.1-mbstring php8.1-curl php8.1-gdType “Y” and enter to continue with installation when prompted about disk space usage.You are returned to the prompt.
Common extensions:
- php8.1-mysql: MySQL/MariaDB database connectivity
- php8.1-xml: XML parsing and manipulation
- php8.1-mbstring: Multibyte string handling
- php8.1-curl: HTTP client functionality
- php8.1-gd: Image processing
Install only the extensions your application requires.
Restart PHP-FPM after installing extensions:
sudo systemctl restart php8.1-fpmVerify the extensions are active:
php -m | grep -E 'mysql|xml|mbstring|curl|gd'A successful installation output looks like this:
curl
gd
libxml
mbstring
mysqli
mysqlnd
pdo_mysql
xml
xmlreader
xmlwriterThen confirm PHP-FPM restarted cleanly:
sudo systemctl status php8.1-fpmThe service should again show active (running). Press q to return to the command prompt.
mysqlnd in php -m output. This is expected behavior and confirms that MySQL support is active.Troubleshooting: MySql extension does not appear in php-m
If the php -m doesn’t show any of the mysql after using the command above to install them, install it explicitly:
sudo apt install php8.1-mysqlThen restart:
sudo systemctl restart php8.1-fpmThen, again, verify the extensions are active:
php -m | grep -E 'mysql|xml|mbstring|curl|gd'A successful installation looks like the output shown above and includes mysql in the list and may include additional modules and indicate normal, expected behavior.
Configure NGINX for PHP-FPM
NGINX communicates with PHP-FPM through the FastCGI protocol, passing PHP requests to the PHP-FPM process manager for execution. NGINX was installed in the previous section alongside PHP-FPM.
The default NGINX installation requires no additional global configuration to work with PHP-FPM. You only need to create a server block that enables FastCGI processing.
For comprehensive NGINX configuration options, see the official NGINX documentation.
Verify FastCGI Communication
NGINX forwards PHP requests to PHP-FPM via a UNIX socket or TCP connection. The Unix socket method provides better performance for local communication between NGINX and PHP-FPM on the same instance.
Step 1: Check the PHP-FPM socket location:
ls -la /run/php/php8.1-fpm.sockThis is the type of output you will see:
srw-rw---- 1 www-data www-data 0 Feb 24 18:05 /run/php/php8.1-fpm.sock
The socket path must match the fastcgi_pass directive in the NGINX server block configuration. If the socket exists and shows the expected ownership and permissions, PHP-FPM is ready for NGINX to connect to it.
Create the NGINX Server Block
Step 1: Create an NGINX server block file to handle PHP requests. This example assumes a site served from /var/www/example.com:
sudo nano /etc/nginx/sites-available/example.comStep 2: Add the server block configuration:
| |
Step 3: Understand Key directives:
- listen: Defines ports for IPv4 and IPv6
- server_name: Domain names for this server block
- root: Document root directory
- fastcgi_pass: Socket path for PHP-FPM communication
- include snippets/fastcgi-php.conf: Standard FastCGI parameters
Step 4: Enable the server block and test the configuration:
sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
sudo nginx -tThen after you run the next command you receive a confirmation message that the syntax is okay and the test was successful.
**Step 5: Reload NGINX to apply changes:
sudo systemctl reload nginxSuccess returns you to the prompt.
Configure PHP-FPM
The default pool configuration listens at /etc/php/8.1/fpm/pool.d/www.conf which matches the fastcgi_pass directive in your NGINX server block. No changes are required for standard deployments (for more information see the official PHP-FPM configuration documentation).
Verify PHP-FPM Socket Configuration
Confirm the PHP-FPM socket path matches the NGINX server block configuration.
Step 1: Open the pool configuration file
sudo nano /etc/php/8.1/fpm/pool.d/www.confStep 2: Locate the listen directive:
1listen = /run/php/php8.1-fpm.sock
This socket path must match the fastcgi_pass directive in your NGINX server block. The default configuration is correct for most deployments.
Process Manager Configuration (Optional)
PHP-FPM’s process manager controls how worker processes are spawned and managed. These settings are optional and do not affect basic functionality.
Default Process Manager Settings
1 2 3 4 5pm = dynamic pm.max_children = 5 pm.start_servers = 2 pm.min_spare_servers = 1 pm.max_spare_servers = 3
Directive Description
- pm = dynamic: Spawns child processes based on demand
- pm.max_children: Maximum concurrent PHP-FPM processes
- pm.start_servers: Processes created at startup
- pm.min_spare_servers: Minimum idle processes
- pm.max_spare_servers: Maximum idle processes
Performance Tuning (Advanced, Optional)
Adjust pm.max_children based on available memory and expected traffic. Each PHP-FPM process typically consumes 20-50 MB of RAM depending on application complexity.
Memory Calculation Example
| |
For a 4 GB instance with 1 GB reserved for system processes and an average PHP-FPM worker size of 80 MB:
| |
This formula is provided as a planning guideline only. It is not a command and does not produce output.
Monitor actual memory usage after deployment and adjust accordingly. Exceeding available memory causes swapping and degrades performance.
Restart PHP-FPM to apply configuration changes if you have made any to the process manager settings:
sudo systemctl restart php8.1-fpmTest the Deployment
Testing confirms that NGINX and PHP-FRM are communicating correctly.
Create Test File
Step 1: Create a PHP info file in your document root:
sudo nano /var/www/example.com/info.phpAdd the following content:
1 2 3<?php phpinfo(); ?>
Step 2: Set Permissions:
sudo chown www-data:www-data /var/www/example.com/info.phpThis command produces no output when successful.
Verify PHP Execution
Access the test file through your web browser using your server’s IP address or domain name:
http://example.com/info.php
A page displaying PHP configuration information confirms PHP-FPM is processing requests correctly.
Verify the Server API line shows:
`FPM/FastCGI`
This confirms NGINX is communicating with PHP-FPM rather than using an alternative PHP handler.
Remove the Test File
Delete the info file after verification to prevent exposing system configuration details:
sudo rm /var/www/example.com/info.phpThe phpinfo() function displays sensitive server information including file paths, loaded modules, and environment variables, so removal is necessary.
Basic Security Hardening
Apply foundational security measures to protect your PHP-FPM deployment. These settings address common vulnerabilities without requiring application-specific configuration.
Disable Dangerous PHP Functions
Restrict PHP functions that can execute system commands or access the file system in ways that pose security risks.
Edit the PHP configuration file:
sudo nano /etc/php/8.1/fpm/php.iniLocate the disable_functions directive and add potentially dangerous functions:
1disable_functions = exec,passthru,shell_exec,system,proc_open,popen,curl_exec,curl_multi_exec,parse_ini_file,show_source
Restart PHP-FPM to apply changes:
sudo systemctl restart php8.1-fpmTest your application after disabling functions to ensure required functionality remains intact. Some applications legitimately require these functions.
Configure File Permissions
Set appropriate ownership and permissions for web files to prevent unauthorized modification.
Set ownership to the web server user:
sudo chown -R www-data:www-data /var/www/example.comSet directory permissions:
sudo find /var/www/example.com -type d -exec chmod 755 {} \;Set file permissions:
sudo find /var/www/example.com -type f -exec chmod 644 {} \;Files should be readable by the web server but writable only by the owner. Directories require execute permissions for traversal.
Enable HTTPS
Configure TLS/SSL certificates to encrypt traffic between clients and your server. HTTPS prevents credential interception and protects session data.
For TLS/SSL certificate configuration on Akamai cloud compute, see Use Certbot to Enable HTTPS with NGINX on Ubuntu. Although the linked Akamai guide references Ubuntu 18.04/20.04, the Certbot installation and NGINX integration steps are identical on Ubuntu 22.04. You can safely follow the Akamai guide as written.
For users who prefer the most current upstream reference, Certbot’s official Ubuntu 22.04 instructions follow the same workflow and may be used interchangeably.
Remove Default Content
Remove default NGINX content to prevent exposing server details and reduce your attack surface. Default welcome pages and example configurations can reveal information about your environment and should be removed on production systems.
sudo rm /var/www/html/index.nginx-debian.htmlRemove or disable the default NGINX server block if not in use:
sudo rm /etc/nginx/sites-enabled/defaultReload NGINX after removing default content:
sudo systemctl reload nginxProduction Environment Considerations
Critical: Disable PHP Error Display in Production
Displaying PHP errors in production exposes internal paths, configuration details, and environment information that attackers can exploit. Configure PHP to log errors privately instead.
Edit the PHP configuration file (scroll or page down to the end of the file to place these directives):
sudo nano /etc/php/8.1/fpm/php.iniSet the following directives:
1 2 3display_errors = Off log_errors = On error_log = /var/log/php-fpm/error.log
Be sure to save: Ctrl X, “Y”, Enter.
Errors are logged to /var/log/php-fpm/error.log for debugging without exposing details to users.
Restart PHP-FPM after making changes:
sudo systemctl reload php8.1-fpmNever deploy phpinfo() or similar diagnostic scripts in production. These scripts expose details about your PHP environment–including file paths, loaded modules, extensions, environment variables, and configuration values–all of which can be used by attackers to map your system and target vulnerabilities.
Logging and Monitoring
Monitor NGINX and PHP-FPM through log files and system metrics to identify errors, performance issues, and security events.
NGINX Logs
NGINX stores access and error logs in /var/log/nginx/ by default.
Log locations:
- Access log:
/var/log/nginx/access.log- Records all requests - Error log:
/var/log/nginx/error.log- Records server errors and warnings
View recent NGINX errors:
sudo tail -f /var/log/nginx/error.logUse Ctrl+ C to stop following the log and return to the shell prompt.
If a command opens in a pager (showing a : at the bottom), press q to exit.
Searching logs
Use grep to search for specific errors or keywords in large log files:
sudo grep -i "error" /var/log/nginx/error.log
sudo grep -i "timeout" /var/log/nginx/error.log
sudo grep -i "php" /var/log/nginx/error.logThis helps locate relevant entries quickly when logs are long or noisy.
Custom log locations
Configure custom log locations in server block configurations using the access_log and error_log directives. For example.
| |
PHP-FPM Logs
PHP-FPM logs process manager events and PHP application errors separately from NGINX.
Log locations:
- PHP-FPM process log:
/var/log/php8.1-fpm.log- pool manager lifecycle events - PHP application error log: Defined by the
error logdirective inphp.ini
View PHP-FPM process events:
sudo tail -f /var/log/php8.1-fpm.logExpected output:
When PHP-FPM restarts (for example, after a system reboot or a configuration reload), the process log records normal lifecycle events such as:
NOTICE: Terminating ...NOTICE: exiting, bye-bye!NOTICE: fpm is running, pid <PID>NOTICE: ready to handle connectionsNOTICE: systemd monitor interval set to 10000ms
These messages indicate that PHP-FPM stopped and started cleanly. The tail -f command will remain open and display new events as they occur.
PHP application-level errors are written to the file specified by the error_log directive in /etc/php/8.1/fpm/php.ini.
Performance Monitoring
Monitor CPU, memory, and network usage through Cloud Manager’s built-in metrics dashboard. Track PHP-FPM process counts and memory consumption to identify resource constraints as your application begins handling real traffic.
Key metrics to monitor:
- CPU usage: Sustained high CPU means the instance is too small for the workload or the application is doing more work than expected.
- Memory usage: High memory usage forces the system to swap to disk, which significantly slows request processing.
- PHP-FPM process count: Reaching
pm.max_childrenmeans all workers are busy, so new requests queue and may slow down or time out (configuration adjustments needed).
For deeper visibility into request behavior and PHP-FPM saturation, integrate with external observability platforms. See the NGINX monitoring documentation for enabling the stub status module.
These metrics don’t require a test step during deployment; they become relevant once your application is serving real traffic. For help interpreting these metrics and resolving issues such as PHP-FPM saturation or slow requests, see the Troubleshooting section that follows.
Troubleshooting
If your PHP-FPM and NGINX configuration isn’t working as expected, use the steps below to identify where the issue is occurring and how to resolve it. PHP, PHP-FPM, and NGINX each log different types of errors, so knowing which component to check helps you interpret problems quickly and accurately.
These steps don’t produce output unless an issue is present. Use them when your application shows errors, slowdowns, or unexpected behavior.
- Check the NGINX Error Log
NGINX logs routing, FastCGI, and upstream connection issues. Common symptoms include:
- 502 Bad Gateway → NGINX cannot reach PHP-FPM
- 403 or 404 errors → incorrect root path or permissions
- PHP file downloads instead of executing → PHP module not loaded
View the log:
sudo tail -f /var/log/nginx/error.log- Check the PHP-FPM Service Log
PHP-FPM logs process-level issues such as pool misconfiguration, socket failures, crashes, or resource exhaustion.
sudo tail -f /var/log/php8.1-fpm.logRestart PHP-FPM if needed:
sudo systemctl restart php8.1-fpm- Check PHP Application Errors
PHP application level errors (syntax errors, fatal errors, exceptions) are written to the file defined by the error_log directive in:
/etc/php/8.1/fpm/php.iniSome frameworks override this setting. If the file is empty, check your application’s log directory or the NGINX error log.
- Verify the PHP-FPM Socket or Port
If NGINX cannot reach PHP-FPM, you may see:
- 502 Bad Gateway
- Connection refused
- No such file or directory
Confirm the socket exists:
ls -l /run/php/php8.1-fpm.sockIf your configuration uses TCP instead of a socket:
fastcgi_pass 127.0.0.1:9000;Ensure PHP-FPM is listening on that address.
- Check File and Directory Permissions
Incorrect ownership or permissions can prevent PHP-FPM from reading or executing files. A safe baseline for most deployments:
sudo chown -R www-data:www-data /var/www/example.com
sudo find /var/www/example.com -type d -exec chmod 755 {} \;
sudo find /var/www/example.com -type f -exec chmod 644 {} \;AppArmor Restrictions (Ubuntu Only)
If you’re using custom directories or non-standard paths, AppArmor may block PHP-FPM from reading files even when permissions are correct. Check for denials:
sudo journalctl -xe | grep DENIEDIf AppArmor is the cause, update the PHP-FPM AppArmor profile or place your files in approved locations.
- Check for PHP-FPM worker saturation
If your application slows down or returns 504 errors, PHP-FPM may have reached pm.max_children. This means all workers are busy, new requests are waiting in a queue, and some may slow down or time out.
Look for messages such as:
• server reached pm.max_children setting
• pool seems busy
These indicate that PHP-FPM cannot spawn additional workers and is under load. See the Performance Monitoring section for guidance on watching process counts and memory usage.
- Reload or Restart Services
After making configuration changes:
sudo systemctl reload nginx
sudo systemctl restart php8.1-fpmReloading NGINX applies configuration changes without dropping active connections.
Next Steps
Expand your PHP-FPM deployment with database connectivity, advanced performance tuning, and high-availability configurations as your application grows.
Database Integration
Connect your PHP application to a database server:
- MySQL on Ubuntu 22.04 - Install and configure MySQL for PHP applications
- PostgreSQL on Ubuntu 22.04 - Install PostgreSQL from official Ubuntu packages
- Akamai Managed Databases - Fully managed database clusters for production workloads
Performance Optimization
Improve performance for production environments:
- NGINX Performance Tuning: Tips and Tricks - Worker processes, connection limits, and buffer sizing
- PHP-FPM Configuration - Process manager tuning and OPcache settings
- PHP OPcache Configuration - Bytecode caching for PHP execution
Security Hardening
Strengthen your deployment beyond basic hardening:
- PHP Security Best Practices - Official PHP security guidance
- NGINX Security Configuration - TLS settings and security headers
High Availability
Scale your deployment across multiple instances:
- Getting Started with NodeBalancers - Load balancing for PHP-FPM instances
- Cloud Firewall Advanced Configuration - Security rules for multi-instance deployments
More Information
You may wish to consult the following resources for additional information on this topic. While these are provided in the hope that they will be useful, please note that we cannot vouch for the accuracy or timeliness of externally hosted materials.
This page was originally published on