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

推荐订阅源

C
CERT Recently Published Vulnerability Notes
U
Unit 42
T
The Blog of Author Tim Ferriss
H
Hackread – Cybersecurity News, Data Breaches, AI and More
B
Blog RSS Feed
Microsoft Azure Blog
Microsoft Azure Blog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
S
Securelist
L
Lohrmann on Cybersecurity
Blog — PlanetScale
Blog — PlanetScale
Recorded Future
Recorded Future
D
DataBreaches.Net
Spread Privacy
Spread Privacy
T
Threat Research - Cisco Blogs
I
Intezer
P
Palo Alto Networks Blog
Simon Willison's Weblog
Simon Willison's Weblog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
I
InfoQ
宝玉的分享
宝玉的分享
Security Latest
Security Latest
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
T
Threatpost
Cisco Talos Blog
Cisco Talos Blog
P
Proofpoint News Feed
博客园 - 司徒正美
H
Hacker News: Front Page
Y
Y Combinator Blog
爱范儿
爱范儿
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
NISL@THU
NISL@THU
月光博客
月光博客
有赞技术团队
有赞技术团队
Cloudbric
Cloudbric
酷 壳 – CoolShell
酷 壳 – CoolShell
G
Google Developers Blog
A
Arctic Wolf
博客园 - 【当耐特】
W
WeLiveSecurity
V
Visual Studio Blog
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
V
V2EX
C
Cyber Attacks, Cyber Crime and Cyber Security
S
SegmentFault 最新的问题
The GitHub Blog
The GitHub Blog
The Cloudflare Blog
Stack Overflow Blog
Stack Overflow 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 Use Struct Tags in Go apt-key Deprecation: Add Repositories with GPG on Ubuntu Linux ps Command: 20 Real-World Examples Python struct.pack and struct.unpack for Binary Data Deadlock in Java: Examples, Detection, and Prevention How To Use Find and Locate to Search for Files on Linux Structured Resume Skill Extraction Using Mistral-7B Inference How to Use the Python Main Function How to Set Up NemoClaw on a DigitalOcean Droplet with 1-Click Build an End-to-End RAG Pipeline for LLM Applications From Single to Multi-Agent Systems: Key Infrastructure Needs Back Up Data to Object Storage Using Restic How to Generate Videos with LTX-2.3 on DigitalOcean GPU Droplets How To Install LAMP Stack (Apache, MySQL, PHP) on Ubuntu How to Download Files with cURL How To Use Variadic Functions in Go Generate UUIDs with uuidgen on Linux How To Use EJS to Template Your Node Application How to Install Node.js on Ubuntu (Step-by-Step Guide) MongoDB Indexes: Improve Query Performance with Node.js LLM Tool Calling with DigitalOcean AI Platform and Databases What are Text Diffusion Models? - An Overview Crafting a Game from Scratch with GPT-5.4 Building Long-Term Memory in AI Agents with LangGraph and Mem0 How To Install PHP 7.4 and Set Up a Local Development Environment on Ubuntu 20.04 Build a GraphQL API in Go to Upload Files to Spaces How To Lint and Format Code with ESLint in Visual Studio Code Train YOLO26 for Retail Object Detection on DigitalOcean GPUs How To Work with JSON in MySQL How to Use the JavaScript .map() Method Building a Scalable App with MongoDB Using DigitalOcean's MCP Server How to Create an SSH Key in Linux: Easy Step-by-Step Guide Measure MySQL Query Performance with mysqlslap How To Use *args and **kwargs in Python 3 Nemotron 3 helped me find the perfect dish rack? A2A vs MCP - How These AI Agent Protocols Actually Differ How To Install and Manage Supervisor Docker Container Images with Watchtower on Ubuntu Getting Started with Qwen3.5 Vision-Language Models How To Create a New Sudo-Enabled User on Ubuntu How to Use Ansible to Install and Set Up Docker on Ubuntu How To Enable Remote Desktop Protocol Using xrdp on Ubuntu 22.04 How To Convert a String to a List in Python How To Check If a String Contains Another String in Python How to Read a Properties File in Python Python Command Line Arguments: sys.argv, argparse, getopt Mastering Grep command in Linux/Unix: A Beginner's Tutorial Understanding Python Data Types How to Implement a Stack in C With Code Examples Python os.system() vs subprocess: Run System Commands How To Install and Use Docker Compose on Ubuntu How to Add and Delete Users on Ubuntu How To Order Query Results in Laravel Eloquent How To Define and Use Handlers in Ansible Playbooks How To Install and Use SQLite on Ubuntu How To Install and Use Homebrew on macOS How To Manage DateTime with Carbon in Laravel and PHP How To Install Git on Ubuntu How To Install and Secure Redis on Ubuntu How To Build and Install Go Programs on Linux Using ldflags to Set Version Information for Go Applications How To Build a Node.js Application with Docker How To Add JavaScript to HTML How To Reset Your MySQL or MariaDB Root Password How To Add Images in Markdown How To Set Up a Production Elasticsearch Cluster with Ansible How To Set Up a Firewall Using firewalld on CentOS Understanding Systemd Units and Unit Files How To Set Up Replication in MySQL How To Use the .htaccess File
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.