惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

IT之家
IT之家
Microsoft Azure Blog
Microsoft Azure Blog
人人都是产品经理
人人都是产品经理
博客园 - 聂微东
博客园_首页
阮一峰的网络日志
阮一峰的网络日志
V
V2EX
小众软件
小众软件
F
Fortinet All Blogs
Microsoft Security Blog
Microsoft Security Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
H
Hackread – Cybersecurity News, Data Breaches, AI and More
量子位
Google DeepMind News
Google DeepMind News
Jina AI
Jina AI
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
aimingoo的专栏
aimingoo的专栏
B
Blog RSS Feed
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
宝玉的分享
宝玉的分享
有赞技术团队
有赞技术团队
J
Java Code Geeks
WordPress大学
WordPress大学
The Cloudflare Blog

DigitalOcean Community Tutorials

It's Time to Break Up with Your Cloud: Why AI Teams are Switching We Built a Private-Document AI App to Test Platform Security. Here Is What We Could Actually Verify. PostgreSQL Explained: A Complete Beginner-to-Advanced Guide How To Install and Configure Postfix on Ubuntu How To Build a Web Application Using Flask in Python 3 Build AI Reading List with DigitalOcean Functions and Mistral How To Concatenate Strings in Python How to Allow MySQL Remote Access Securely How To Install and Use Docker on Rocky Linux How To Build a Multi-Agent AI System with Docker Agent DSPy Use Cases: Build Optimized LLM Pipelines How To Submit AJAX Forms with jQuery Build an AI-Powered GPU Fleet Optimizer with the DigitalOcean AI Platform ADK Monitor GPU Utilization in Real Time: A Complete Guide Reduce File Size of Images in Linux - CLI and GUI methods Reduce PDF File Size in Linux: Tools and Methods How To Set Up a Private Docker Registry on Ubuntu How To Troubleshoot Terraform: Errors and Fixes How to Use Go Modules Python Multiprocessing Example: Process, Pool & Queue Convert Class Components to Functional Components with React Hooks How To Install and Configure Ansible on Ubuntu LLM Tokenizers Simplified: BPE, SentencePiece, and More How To Monitor System Authentication Logs on Ubuntu How to Use Traceroute and MTR to Diagnose Network Issues How to Deploy Postgres to Kubernetes Cluster Importing Packages in Go: A Complete Guide Create RAID Arrays with mdadm on Ubuntu How To Make an HTTP Server in Go How To Set Up Time Synchronization on Ubuntu
How to Configure PHP-FPM with NGINX
Anish Singh Walia · 2026-06-18 · via DigitalOcean Community Tutorials

Introduction

PHP-FPM with NGINX is the standard way to run PHP on Nginx. Nginx has no built-in PHP module like Apache’s mod_php. Nginx serves static files and forwards .php requests to PHP-FPM over FastCGI, usually through a Unix socket.

In this tutorial you install PHP-FPM on Ubuntu, create a dedicated pool, connect Nginx with fastcgi_pass, test the stack, and troubleshoot 502 errors.

Version note: Commands were checked against Ubuntu 22.04 LTS (Jammy), 24.04 LTS (Noble Numbat), and 26.04 LTS (Resolute Raccoon) with PHP from the default Ubuntu repositories. Default PHP versions per release: 8.1 on 22.04, 8.3 on 24.04, and 8.5 on 26.04. Confirm your host with lsb_release -rs and php -v before you edit paths or service names.

Ubuntu LTS version reference

Use this table to swap package names, sockets, and config paths on your server. Default PHP versions come from the Ubuntu archive. See php-fpm on Noble (24.04) and php-fpm on Resolute (26.04).

Ubuntu Codename PHP FPM package Service Socket
22.04 Jammy 8.1 php8.1-fpm php8.1-fpm /run/php/php8.1-fpm.sock
24.04 Noble 8.3 php8.3-fpm php8.3-fpm /run/php/php8.3-fpm.sock
26.04 Resolute 8.5 php8.5-fpm php8.5-fpm /run/php/php8.5-fpm.sock

Pool configs live under /etc/php/<version>/fpm/pool.d/. On 24.04 and 26.04, sudo apt install php-fpm installs the default metapackage for that release.

The step-by-step examples below use PHP 8.1 on Ubuntu 22.04. Replace 8.1 with 8.3 or 8.5 when you work on 24.04 or 26.04.

Key takeaways

  • Nginx does not execute PHP. PHP-FPM runs worker processes and receives requests through FastCGI.
  • Install the FPM package for your PHP version: php8.1-fpm on 22.04, php8.3-fpm on 24.04, or php8.5-fpm on 26.04.
  • Point Nginx at the pool socket with fastcgi_pass unix:/run/php/php8.1-fpm.sock (swap 8.1 for 8.3 or 8.5 as needed) inside a location ~ \.php$ block.
  • Pool files live in /etc/php/<version>/fpm/pool.d/. Each [pool_name] section controls user, socket path, and process manager settings.
  • A 502 Bad Gateway usually means a socket mismatch, stopped PHP-FPM service, or wrong file permissions on the socket.
  • Unix sockets work for Nginx and PHP-FPM on the same server. TCP port 9000 fits containers or remote FPM hosts.
  • Separate pools let you run different sites under different Unix users and PHP versions.

Prerequisites

Before you start, confirm you have:

What is PHP-FPM?

PHP-FPM (FastCGI Process Manager) is a PHP SAPI that manages a pool of worker processes. A master process listens on a socket or TCP port. Worker processes execute PHP scripts and return output to the web server.

Role Responsibility
Nginx Terminates HTTP, serves static files, proxies PHP to FPM
PHP-FPM master Manages workers, listens on socket or port
PHP-FPM workers Run index.php and other scripts

PHP-FPM vs mod_php

PHP-FPM + Nginx mod_php + Apache
Architecture Separate PHP worker processes PHP inside Apache workers
Memory PHP memory isolated from web server Shared Apache process memory
Typical use Nginx, high-traffic PHP sites Legacy Apache stacks
Nginx support Required pattern Not available

How PHP-FPM and Nginx work together

  1. A browser requests https://example.com/index.php.
  2. Nginx matches location ~ \.php$ and passes the request to PHP-FPM through FastCGI.
  3. PHP-FPM assigns an idle worker or spawns one based on pool settings.
  4. The worker runs the script and sends the response back to Nginx.
  5. Nginx returns the response to the client.

For the official Nginx integration notes, see Nginx on Unix systems.

Step 1: Install PHP-FPM

Check your Ubuntu and PHP versions:

lsb_release -rs
php -v

Install the FPM package that matches your release:

Ubuntu LTS Install command
22.04 sudo apt install php8.1-fpm
24.04 sudo apt install php8.3-fpm
26.04 sudo apt install php8.5-fpm

On 24.04 and 26.04 you also have the option to run sudo apt install php-fpm, which installs the default PHP FPM metapackage for that release.

The 22.04 example continues below:

sudo apt update
sudo apt install php8.1-fpm

Enable and start the service. Swap the service name on 24.04 (php8.3-fpm) or 26.04 (php8.5-fpm):

sudo systemctl enable php8.1-fpm
sudo systemctl start php8.1-fpm
sudo systemctl status php8.1-fpm

You should see active (running). Confirm the default socket:

ls -l /run/php/php8.1-fpm.sock

Expected socket paths by release:

Ubuntu LTS Default socket
22.04 /run/php/php8.1-fpm.sock
24.04 /run/php/php8.3-fpm.sock
26.04 /run/php/php8.5-fpm.sock

Step 2: Configure a PHP-FPM pool

The default pool file is /etc/php/8.1/fpm/pool.d/www.conf on Ubuntu 22.04. On 24.04 use /etc/php/8.3/fpm/pool.d/www.conf. On 26.04 use /etc/php/8.5/fpm/pool.d/www.conf. For a single site, editing www is enough. For multiple apps, create one pool per site.

This example creates a pool named wordpress_site under a dedicated user.

Create the user and group:

sudo groupadd wordpress_user
sudo useradd -g wordpress_user -d /var/www/wordpress -s /usr/sbin/nologin wordpress_user

Create the pool file:

sudo nano /etc/php/8.1/fpm/pool.d/wordpress_pool.conf

Add the following configuration. Keep the PHP version consistent in the socket path:

[wordpress_site]
user = wordpress_user
group = wordpress_user
listen = /run/php/php8.1-fpm-wordpress.sock
listen.owner = www-data
listen.group = www-data
listen.mode = 0660

php_admin_value[disable_functions] = exec,passthru,shell_exec,system
php_admin_flag[allow_url_fopen] = off

pm = dynamic
pm.max_children = 20
pm.start_servers = 4
pm.min_spare_servers = 2
pm.max_spare_servers = 8
pm.max_requests = 500

Pool directives explained:

Directive Purpose
[wordpress_site] Unique pool name
user / group Unix account for worker processes
listen Socket file Nginx connects to
listen.owner / listen.group Must allow Nginx (www-data) to connect
pm Process manager mode: dynamic, static, or ondemand
pm.max_children Upper limit on concurrent workers
pm.max_requests Recycle workers after N requests

Reload PHP-FPM after changes. Use the service name for your PHP version:

sudo systemctl reload php8.1-fpm

On 24.04 run sudo systemctl reload php8.3-fpm. On 26.04 run sudo systemctl reload php8.5-fpm.

Verify the new socket exists:

ls -l /run/php/php8.1-fpm-wordpress.sock

Step 3: Configure Nginx for PHP-FPM

Create or edit a server block in /etc/nginx/sites-available/. Point fastcgi_pass at the pool socket from Step 2.

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

    access_log /var/log/nginx/example.com-access.log;
    error_log  /var/log/nginx/example.com-error.log;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php8.1-fpm-wordpress.sock;
    }

    location ~ /\.ht {
        deny all;
    }
}

snippets/fastcgi-php.conf ships with the Ubuntu Nginx package. It sets fastcgi_split_path_info and SCRIPT_FILENAME using $document_root$fastcgi_script_name.

Enable the site and test the config:

sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
NGINX Server Block PHP-FPM
NGINX Server Block

Set ownership on the web root so the pool user reads the files:

sudo chown -R wordpress_user:wordpress_user /var/www/wordpress

For Nginx troubleshooting patterns, see Nginx Essentials.

Step 4: Test the PHP-FPM and Nginx setup

Create a test file in the web root:

echo '<?php phpinfo(); ?>' | sudo tee /var/www/wordpress/info.php

Open http://example.com/info.php in a browser. Confirm $_SERVER['USER'] shows wordpress_user, which means Nginx routed the request through your custom pool.

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

Delete info.php after testing. phpinfo() exposes server details to anyone who visits the URL.

sudo rm /var/www/wordpress/info.php

Socket vs TCP for fastcgi_pass

Method Example (22.04) When to use
Unix socket unix:/run/php/php8.1-fpm.sock Same server
TCP 127.0.0.1:9000 Docker, remote FPM, or custom listen

On 24.04 use unix:/run/php/php8.3-fpm.sock. On 26.04 use unix:/run/php/php8.5-fpm.sock.

Socket example (default pool):

fastcgi_pass unix:/run/php/php8.1-fpm.sock;

TCP example (set listen = 127.0.0.1:9000 in the pool file first):

fastcgi_pass 127.0.0.1:9000;

Fix 502 Bad Gateway errors

Nginx returns 502 Bad Gateway when PHP-FPM is unreachable or fails to respond. Work through these checks in order.

1. Confirm PHP-FPM is running. On 22.04:

sudo systemctl status php8.1-fpm

On 24.04 check php8.3-fpm. On 26.04 check php8.5-fpm.

2. Match the socket path in Nginx and the pool listen directive. Swap 8.1 for your PHP version:

grep -r fastcgi_pass /etc/nginx/sites-enabled/
grep listen /etc/php/8.1/fpm/pool.d/*.conf

3. Check socket permissions. Nginx runs as www-data and needs read/write access to the socket:

ls -l /run/php/

4. Read the logs:

sudo tail -f /var/log/nginx/error.log
sudo journalctl -u php8.1-fpm -f

On 24.04 replace the unit with php8.3-fpm. On 26.04 use php8.5-fpm.

5. Raise timeouts if scripts run long. Add inside the location ~ \.php$ block:

fastcgi_read_timeout 300;

Tune PHP-FPM performance

Start with conservative pm values and raise them based on RAM and traffic. Each PHP worker uses memory. A rough starting point on a 2 GB Droplet:

pm = dynamic
pm.max_children = 10
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 4
pm.max_requests = 500

Enable the built-in status page for monitoring. Add to the pool file:

pm.status_path = /fpm-status

Add a matching Nginx location (restrict access to your IP):

location ~ ^/fpm-status$ {
    access_log off;
    allow 127.0.0.1;
    deny all;
    include fastcgi_params;
    fastcgi_pass unix:/run/php/php8.1-fpm.sock;
}

For WordPress on the same stack, follow How To Install WordPress with LEMP on Ubuntu 22.04. The Nginx and PHP-FPM wiring is the same on 24.04 and 26.04 when you use the correct socket path from the version table.

Ubuntu 24.04 and 26.04 LTS notes

Ubuntu 24.04 LTS (Noble) and 26.04 LTS (Resolute) use the same Nginx layout as 22.04: server blocks in /etc/nginx/sites-available/, the snippets/fastcgi-php.conf include, and www-data as the Nginx user.

Differences to watch on newer LTS releases:

Item 24.04 LTS 26.04 LTS
Default PHP 8.3 8.5
FPM package php8.3-fpm or php-fpm php8.5-fpm or php-fpm
Pool directory /etc/php/8.3/fpm/pool.d/ /etc/php/8.5/fpm/pool.d/
Default socket /run/php/php8.3-fpm.sock /run/php/php8.5-fpm.sock

DigitalOcean LEMP tutorials currently target Ubuntu 22.04. The install and config steps in this guide apply to 24.04 and 26.04 when you substitute package names, service units, and socket paths from the version table. I have not re-tested every command on a fresh 26.04 image in this refresh, so run php -v and ls -l /run/php/ on your Droplet to confirm paths before you go live.

FAQs

1. Does NGINX use PHP-FPM?

Yes. Nginx has no embedded PHP engine. For .php files, Nginx forwards the request to PHP-FPM through FastCGI. You wire the connection with fastcgi_pass in a location ~ \.php$ block.

2. How do you install NGINX and PHP-FPM on Ubuntu?

Install Nginx, then the FPM package for your LTS release:

Ubuntu LTS Commands
22.04 sudo apt install nginx php8.1-fpm
24.04 sudo apt install nginx php8.3-fpm
26.04 sudo apt install nginx php8.5-fpm

Enable both services (example for 22.04):

sudo apt update
sudo systemctl enable --now nginx php8.1-fpm

Add a server block with fastcgi_pass pointing at the socket for your PHP version. The full LEMP walkthrough for 22.04 is in How To Install Linux, Nginx, MySQL, PHP (LEMP stack) on Ubuntu 22.04.

3. What does PHP-FPM do?

PHP-FPM is a process manager for PHP. A master process controls worker processes that execute scripts. Pools define sockets, users, and scaling rules. PHP-FPM is the required PHP handler when you use Nginx.

4. What causes a 502 error with PHP-FPM?

A 502 means Nginx could not get a valid response from PHP-FPM. Common causes include a stopped PHP-FPM service (php8.1-fpm, php8.3-fpm, or php8.5-fpm), a wrong socket path in fastcgi_pass, socket permission errors, or PHP crashes in the worker. Check /var/log/nginx/error.log and journalctl -u php8.1-fpm (swap the unit name for your PHP version).

5. Is PHP-FPM necessary with NGINX?

Yes, if you want Nginx to run PHP. Without PHP-FPM (or another FastCGI PHP handler), Nginx serves only static files. PHP-FPM also separates PHP memory from the web server process, which is why most production Nginx stacks use it instead of older CGI methods.

Conclusion

You installed PHP-FPM, created a custom pool, connected Nginx with fastcgi_pass, and learned how to test the stack and fix 502 errors. Separate pools give you per-site users, sockets, and worker limits.

For multiple PHP versions on one host, see multiple PHP versions on Ubuntu. For HTTPS, follow How To Secure Nginx with Let’s Encrypt on Ubuntu 22.04.

What’s next

Keep building with these PHP tutorials and Nginx tutorials:

Deploy from GitHub with DigitalOcean App Platform or run the full stack on a Droplet. Choose an Ubuntu 26.04 LTS image when you create the VM if you want the newest LTS with PHP 8.5 in the default repositories.

Creative CommonsThis work is licensed under a Creative Commons Attribution-NonCommercial- ShareAlike 4.0 International License.