Tutorial

How to Configure PHP-FPM with NGINX for Secure PHP Processing

Updated on May 14, 2025
authorauthor

By Meghna Gangwar and Manikandan Kurup

How to Configure PHP-FPM with NGINX for Secure PHP Processing

PHP-FPM (FastCGI Process Manager) is an alternative to FastCGI implementation of PHP with some additional features useful for sites with high traffic. It is the preferred method of processing PHP pages with NGINX and is faster than traditional CGI based methods such as SUPHP or mod_php for running a PHP script. The main advantage of using PHP-FPM is that it uses a considerable amount of less memory and CPU as compared with any other methods of running PHP. The primary reason is that it demonizes PHP, thereby transforming it to a background process while providing a CLI script for managing PHP request.

Understanding how PHP-FPM works

Here’s a simplified overview of how PHP-FPM works:

  1. Request Handling: When a request for a PHP script is received by the web server (e.g., NGINX), it is passed to PHP-FPM through a FastCGI interface.
  2. Process Management: PHP-FPM manages a pool of PHP processes. When a request is received, PHP-FPM selects an available process from the pool to handle the request. If no process is available, PHP-FPM can spawn a new process to handle the request.
  3. Process Types: PHP-FPM can manage different types of processes, including:
    • Master Process: The master process is responsible for managing the pool of PHP processes. It listens for incoming requests and distributes them to available worker processes.
      • Worker Processes: Worker processes are responsible for executing PHP scripts. They can be configured to run in different modes, such as dynamic, static, or ondemand.
  4. Request Execution: When a worker process receives a request, it executes the PHP script and returns the output to the web server.
  5. Process Recycling: PHP-FPM can recycle worker processes after a specified number of requests or a certain amount of time. This helps to prevent memory leaks and maintain performance.

PHP-FPM NGINX Configuration Prerequisites

NGINX PHP-FPM Configuration Steps

  • Install PHP-FPM
  • Configure PHP-FPM Pool
  • Configure NGINX for PHP-FPM
  • Test NGINX PHP-FPM Configuration

1. Install PHP-FPM

Nginx doesn’t know how to run a PHP script of its own. It needs a PHP module like PHP-FPM to efficiently manage PHP scripts. PHP-FPM, on the other hand, runs outside the NGINX environment by creating its own process. Therefore when a user requests a PHP page the nginx server will pass the request to PHP-FPM service using FastCGI. The installation of php-fpm in Ubuntu depends on PHP and its version. Check the documentation of installed PHP before proceeding with installing FPM in your server. Assuming you have already installed the latest PHP 7.3, then you can install FPM using the following apt-get command.

# apt-get install php7.3-fpm

The FPM service will start automatically, once the installation is over. You can verify that using the following systemd command:

# systemctl status php7.3-fpm
● php7.3-fpm.service - The PHP 7.3 FastCGI Process Manager
   Loaded: loaded (/lib/systemd/system/php7.3-fpm.service; enabled; vendor preset: enabled)
   Active: active (running) since Sun 2019-02-17 06:29:31 UTC; 30s ago
     Docs: man:php-fpm7.3(8)
 Main PID: 32210 (php-fpm7.3)
   Status: "Processes active: 0, idle: 2, Requests: 0, slow: 0, Traffic: 0req/sec"
    Tasks: 3 (limit: 1152)
   CGroup: /system.slice/php7.3-fpm.service
           ├─32210 php-fpm: master process (/etc/php/7.3/fpm/php-fpm.conf)
           ├─32235 php-fpm: pool www
           └─32236 php-fpm: pool www

2. Configure PHP-FPM Pool

The php-fpm service creates a default pool, the configuration (<www.conf>) for which can be found in /etc/php/7.3/fpm/pool.d folder. You can customize the default pool as per your requirements. But it is a standard practice to create separate pools to have better control over resource allocation to each FPM processes. Furthermore, segregating FPM pool will enable them to run independently by creating its own master process. That means each php application can be configured with its own cache settings using PHP-FPM. A change in one pool’s configuration does not require you to start or stop the rest of the FPM pools. Let us create an FPM pool for running a PHP application effectively through a separate user. To start with, create a new user who will have exclusive rights over this pool:

# groupadd wordpress_user
# useradd -g wordpress_user wordpress_user

Now navigate to the FPM configuration directory and create a configuration file using your favorite text editor like vi:

# cd /etc/php/7.3/fpm/pool.d
# vi wordpress_pool.conf
[wordpress_site]
user = wordpress_user
group = wordpress_user
listen = /var/run/php7.2-fpm-wordpress-site.sock
listen.owner = www-data
listen.group = www-data
php_admin_value[disable_functions] = exec,passthru,shell_exec,system
php_admin_flag[allow_url_fopen] = off
; Choose how the process manager will control the number of child processes. 
pm = dynamic 
pm.max_children = 75 
pm.start_servers = 10 
pm.min_spare_servers = 5 
pm.max_spare_servers = 20 
pm.process_idle_timeout = 10s

The above FPM configuration options and their values are described below.

  • [wordpress_site]: The name of the pool and must be unique across all pool names.
  • user and group: The user and group under which the pool will run.
  • listen: The name of the socket file for this pool.
  • listen.owner and listen.group: Must match to the user and group on which NGINX is running. In our case it is www-data.
  • php_admin_value: Allows to set custom php configuration values.
  • php_admin_flag: Allows to set PHP boolean flags.
  • pm: The process manager settings and the value is Dynamic means the number of child processes are set dynamically based on the following directives.
  • pm.max_children: The maximum number of children that can be alive at the same time.
  • pm.start_servers: The number of children created on startup.
  • pm.min_spare_servers: The minimum number of children in ‘idle’ state (waiting to process). If the number of idle processes is less than this number then some children will be created.
  • pm.max_spare_servers: The maximum number of children in idle state (waiting to process). If the number of idle processes is greater than this number then some children will be killed.
  • pm.process_idle_timeout: The desired maximum number of idle server processes. Used only when pm value is set to dynamic. Apart from above settings, it is also possible to pass few system environmental variable to php-fpm service using something like env['PHP_FOO'] = $bar. For example, adding the following options in the above configuration file will set the hostname and temporary folder location to the PHP environment.
...
...
env[HOSTNAME] = $HOSTNAME
env[TMP] = /tmp
...
...

Also, the process managers settings in the above pool configuration file are set to dynamic. Choose a setting that best suits your requirement. The other configuration options for process manager are:

  • Static: A fixed number of PHP processes will be maintained.
  • ondemand: No children are created at startup. Children will be forked when new requests are received in the server.

Once you are done with creating the above configuration file, restart fpm service to apply new settings:

# systemctl start php7.3-fpm

The FPM pool will be created immediately to serve php pages. Remember, you can create a separate systemd service by specifying the above FPM configuration file thereby enabling you to start/stop this pool without affecting other pools.

3. Configure NGINX for PHP-FPM

Now create an NGINX server block that will make use of the above FPM pool. To do that, edit your NGINX configuration file and pass the path of pool’s socket file using the option fastcgi_pass inside location block for php.

server {
         listen       80;
         server_name  example.journaldev.com;
         root         /var/www/html/wordpress;

         access_log /var/log/nginx/example.journaldev.com-access.log;
         error_log  /var/log/nginx/example.journaldev.com-error.log error;
         index index.html index.htm index.php;

         location / {
                      try_files $uri $uri/ /index.php$is_args$args;
         }

         location ~ \.php$ {
            fastcgi_split_path_info ^(.+\.php)(/.+)$;
            fastcgi_pass unix:/var/run/php7.2-fpm-wordpress-site.sock;
            fastcgi_index index.php;
            include fastcgi.conf;
    }
}
NGINX Server Block PHP-FPM
NGINX Server Block

Make sure the above configuration setting is syntactically correct and restart NGINX.

# nginx -t
# systemctl restart nginx

4. Test PHP-FPM NGINX Configuration

To test if the above NGINX configuration file is indeed using the newly created FPM pool, create a php info file inside the web root. I have used /var/www/html/wordpress as a web root in the above NGINX configuration file. Adjust this value according to your environment.

# cd /var/www/html/wordpress
# echo "<?php echo phpinfo();?>" > info.php

Once you are done with creating the PHP info page, point your favorite web browser to it. You will notice that the value of $_SERVER['USER'] and $_SERVER['HOME'] variable are pointing to wordpress_user and /home/wordpress_user respectively that we set in the FPM configuration file previously and thus confirms that the NGINX is serving the php pages using our desired FPM pool.

NGINX PHP-FPM Test Php Info Page
NGINX PHP-FPM Testing

FAQs

1. What is PHP-FPM and why use it with NGINX?

PHP-FPM (FastCGI Process Manager) is a process manager for PHP that improves performance and security by efficiently managing PHP processes. Using PHP-FPM with NGINX enhances performance, security, and resource management, making it ideal for high-traffic and demanding PHP applications.

2. How do I connect NGINX to PHP-FPM?

To connect NGINX to PHP-FPM, you need to configure NGINX to use the PHP-FPM service as a FastCGI server. This is typically done by specifying the fastcgi_pass directive in the NGINX configuration file, pointing to the PHP-FPM socket or TCP address. For example: fastcgi_pass unix:/var/run/php/php7.2-fpm.sock; or fastcgi_pass 127.0.0.1:9000;. This allows NGINX to forward PHP requests to the PHP-FPM service for processing.

Here’s an example of how the configuration might look in your NGINX configuration file:

location ~ \.php$ {
    fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME $request_filename;
    include fastcgi_params;
}

3. What is the difference between using a socket and a port?

Using a socket allows for faster communication between NGINX and PHP-FPM as it eliminates the need for network overhead. A port, on the other hand, requires network communication, which can be slower. However, using a port can be beneficial in scenarios where PHP-FPM is running on a different server or container.

For example, if you’re using a socket:

fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;

And if you’re using a port:

fastcgi_pass 127.0.0.1:9000;

4. How can I fix a 502 Bad Gateway error from PHP-FPM?

To fix a 502 Bad Gateway error from PHP-FPM, ensure that PHP-FPM is running and the socket or TCP address specified in the NGINX configuration is correct. Check the PHP-FPM logs for errors and adjust the pool settings as needed. Additionally, verify that the NGINX configuration is correctly passing PHP requests to PHP-FPM.

You can check the PHP-FPM logs by running the following command:

tail -f /var/log/php7.2-fpm.log

5. How do I run multiple PHP versions with NGINX?

To run multiple PHP versions with NGINX, you can configure separate PHP-FPM pools for each version and specify the corresponding pool in the NGINX configuration for each domain or subdomain. This allows you to use different PHP versions for different applications or domains.

For example, if you have two PHP versions, PHP 7.2 and PHP 7.4, you can configure two separate pools in your PHP-FPM configuration file:

# PHP 7.2 pool configuration
[php7.2-fpm]
listen = /var/run/php/php7.2-fpm.sock
user = php7.2-fpm
group = php7.2-fpm

# PHP 7.4 pool configuration
[php7.4-fpm]
listen = /var/run/php/php7.4-fpm.sock
user = php7.4-fpm
group = php7.4-fpm

Then, in your NGINX configuration, you can specify the corresponding pool for each domain or subdomain:

server {
    listen 80;
    server_name example.com;
    root /var/www/html/example.com;

    location ~ \.php$ {
        fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $request_filename;
        include fastcgi_params;
    }
}

server {
    listen 80;
    server_name example.net;
    root /var/www/html/example.net;

    location ~ \.php$ {
        fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $request_filename;
        include fastcgi_params;
    }
}

6. Where is the PHP-FPM pool configuration located?

The PHP-FPM pool configuration is typically located in /etc/php/7.x/fpm/pool.d/ directory, where 7.x is the PHP version.

7. How do I optimize PHP-FPM performance?

To optimize PHP-FPM performance, adjust the pm.max_children, pm.start_servers, and pm.min_spare_servers settings in the PHP-FPM pool configuration to balance the number of processes with available system resources. Additionally, consider enabling pm.status_path for monitoring and pm.max_requests to recycle processes and prevent memory leaks.

Here’s an example of optimized pool configuration:

[www]
user = www-data
group = www-data

listen = /var/run/php/php7.2-fpm.sock

pm = dynamic
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 35

pm.status_path = /status
pm.max_requests = 500

Conclusion

In this article, we learned how to install php-fpm and configure separate pools for different users and applications. We also learned how to configure an NGINX server block to connect to a PHP-FPM service. PHP-FPM provides reliability, security, scalability, and speed along with a lot of performance tuning options. You can now split the default PHP-FPM pool into multiple resource pools to serve different applications. This will not only enhance your server security but also enable you to allocate server resources optimally!

If you’re looking to expand your knowledge of PHP-FPM and NGINX, here are some helpful resources:

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about our products

About the author(s)

Category:
Tutorial

Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?
 
JournalDev
DigitalOcean Employee
DigitalOcean Employee badge
November 6, 2019

Thank you for your tutorial. I am plan to install Nginx server separately with PHP server. Meaning Nginx in one server and PHP is in another server…And the NGINX server will located at DMZ zone and will face the internet. My question is: 1) Which server we need to install PHP-FPM? In Nginx server or in php server? 2) And how these two server will communicate? Which confuguration files need to alter? Sorry if my question is sound silly :). I am new to php-fpm and still in the midst of understanding it. Thank you.

- Paklah

    JournalDev
    DigitalOcean Employee
    DigitalOcean Employee badge
    April 2, 2020

    when ever i m trying to execute php file from browser it gets download

    - aditya

      JournalDev
      DigitalOcean Employee
      DigitalOcean Employee badge
      September 2, 2020

      I have deployed a web app to AWS and php-fpm is occupied most of the CPU cores. sometimes it makes the server crash. Can there be something wrong with the configuration?

      - vishal

        JournalDev
        DigitalOcean Employee
        DigitalOcean Employee badge
        November 18, 2020

        Please add - if necessary: $ cd /project/path $ sudo chwon -R wordpress_user:wordpress_user . Because without that PHP-FPM can’t access to the files ;/

        - Piotr

          Join the Tech Talk
          Success! Thank you! Please check your email for further details.

          Please complete your information!

          Become a contributor for community

          Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

          DigitalOcean Documentation

          Full documentation for every DigitalOcean product.

          Resources for startups and SMBs

          The Wave has everything you need to know about building a business, from raising funding to marketing your product.

          Get our newsletter

          Stay up to date by signing up for DigitalOcean’s Infrastructure as a Newsletter.

          New accounts only. By submitting your email you agree to our Privacy Policy

          The developer cloud

          Scale up as you grow — whether you're running one virtual machine or ten thousand.

          Get started for free

          Sign up and get $200 in credit for your first 60 days with DigitalOcean.*

          *This promotional offer applies to new accounts only.