Web Development 3d ago 5 views 6 min read

How to configure PHP-FPM to handle WebSocket connections on Ubuntu

This guide shows you how to set up PHP-FPM to process WebSocket requests on Ubuntu 24.04. You will install the required libraries, configure the pool, and verify the connection.

Riya K.
Updated 1d ago
Sponsored

Cloud Hosting — blazing fast websites

Fully managed cloud hosting with free SSL, auto-backups and a friendly cPanel. Built for WordPress, Laravel and custom PHP apps.

You will configure the PHP-FPM pool to accept WebSocket upgrade headers and process long-polling or SSE requests. These steps target Ubuntu 24.04 with PHP 8.3.8 and require root privileges for system package installation and file edits.

Prerequisites

  • Ubuntu 24.04 LTS server with SSH access.
  • PHP 8.3.x installed via the official PHP repository or APT.
  • Nginx or Apache installed and running as the reverse proxy.
  • Root or sudo privileges to modify the PHP-FPM pool configuration.
  • At least 512 MB of available RAM for the PHP-FPM worker process.

Step 1: Install required system libraries

Install the system libraries needed to handle the WebSocket protocol stack and SSL/TLS encryption. You need the libuv and libevent libraries which PHP-FPM uses to manage non-blocking I/O for long connections.

sudo apt update
sudo apt install libuv1-dev libevent-dev libssl-dev php8.3-sockets

You will see the package manager resolve dependencies and install the libraries.

Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
libuv1-dev is already the newest version (1.44.2-1build1).
libevent-dev is already the newest version (2.1.12-stable-4build1).
libssl-dev is already the newest version (3.0.2-0ubuntu1.10).
php8.3-sockets is already the newest version (8.3.8-1ubuntu20.14).

If the packages are not installed, the output will show the download progress and installation status.

Step 2: Install the PHP WebSocket extension

Install the PHP extension that provides native support for the WebSocket protocol. This extension allows PHP scripts to act as WebSocket clients and servers. On Ubuntu 24.04, you must compile the extension from source or use a PPA that supports PHP 8.3.

First, clone the repository and build the extension for PHP 8.3.

cd /tmp
git clone https://github.com/websocket-php/php-websocket.git
cd php-websocket
git checkout 2.7.x

Configure the build to match your PHP version and install the extension.

phpize
./configure --with-php-config=$(php-config)
make
sudo make install

Add the extension to your PHP configuration file.

echo "extension=websocket" | sudo tee /etc/php/8.3/mods-available/websocket.ini

Enable the extension in the main PHP configuration file.

sudo phpenable 8.3 websocket

Restart the PHP-FPM service to load the new extension.

sudo systemctl restart php8.3-fpm

Step 3: Configure the PHP-FPM pool for WebSocket

Edit the default pool configuration file to allow WebSocket upgrade headers. You must set the correct process manager and memory limits to prevent the worker from crashing under load.

Open the pool configuration file for editing.

sudo nano /etc/php/8.3/fpm/pool.d/www.conf

Add the following lines to the pool configuration to handle the upgrade request.

request_terminate_timeout = 0
slowlog = /var/log/php-fpm/www-slow.log
pm = dynamic
pm.max_children = 15
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 10
pm.max_requests = 500
pm.process_idle_timeout = 10s
pm.process_start_timeout = 60s
pm.max_requests = 1000
request_terminate_timeout = 0
catch_workers_output = yes

Set the `request_terminate_timeout` to 0 to allow indefinite connections for WebSockets.

Ensure the `catch_workers_output` is set to yes to prevent output from crashing the pool.

request_slowlog_timeout = 0
slowlog = /var/log/php-fpm/www-slow.log
pm = dynamic
pm.max_children = 15
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 10
pm.max_requests = 500
pm.process_idle_timeout = 10s
pm.process_start_timeout = 60s
pm.max_requests = 1000
request_terminate_timeout = 0
catch_workers_output = yes

Save the file and exit the editor.

Step 4: Configure Nginx to proxy WebSocket traffic

Configure Nginx to pass WebSocket upgrade headers to the PHP-FPM backend. You must set the `proxy_http_version 1.1` and the `Upgrade` header to enable the connection.

Open the Nginx site configuration file.

sudo nano /etc/nginx/sites-available/default

Add the following location block for WebSocket traffic.

location /ws {
    proxy_pass http://127.0.0.1:9000;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_read_timeout 86400;
    proxy_send_timeout 86400;
}

Reload the Nginx configuration to apply the changes.

sudo nginx -t
sudo systemctl reload nginx

Verify the installation

Verify that the PHP-FPM pool is running and the extension is loaded. Check the PHP-FPM status to ensure the worker processes are active.

sudo systemctl status php8.3-fpm

You will see the service is active and running.

● php8.3-fpm.service - The PHP 8.3 FastCGI Process Manager
   Loaded: loaded (/lib/systemd/system/php8.3-fpm.service; enabled)
   Active: active (running) since Mon 2024-01-01 12:00:00 UTC; 1 day ago

Check that the WebSocket extension is loaded in PHP.

php -m | grep websocket

The output should show the extension name.

websocket

Test the connection by sending a WebSocket handshake request to the server.

curl -v -H "Connection: Upgrade" -H "Upgrade: websocket" http://localhost/ws

You will see the HTTP 101 Switching Protocols response if the configuration is correct.

* Connected to localhost (127.0.0.1) port 80
> GET /ws HTTP/1.1
> Host: localhost
> Connection: Upgrade
> Upgrade: websocket
>
< HTTP/1.1 101 Switching Protocols
< Upgrade: websocket
< Connection: Upgrade
<
* No more headers
* Connection #0 to localhost left intact

Troubleshooting

If the connection fails, check the PHP-FPM error log for syntax errors or missing extensions.

sudo tail -f /var/log/php-fpm/error.log

Look for messages like "cannot load extension" or "syntax error".

Ensure the Nginx configuration is valid before reloading.

sudo nginx -t

If the test fails, correct the syntax in the configuration file and reload Nginx.

sudo systemctl reload nginx

Verify that the PHP-FPM pool is listening on the correct port.

sudo netstat -tlnp | grep 9000

Ensure the port is open and bound to 127.0.0.1 or 0.0.0.0.

If the WebSocket handshake returns a 502 Bad Gateway, check the Nginx error log.

sudo tail -f /var/log/nginx/error.log

Ensure the PHP-FPM worker process has enough memory to handle the connection.

free -m

Increase the `pm.max_children` value if the system runs out of memory.

Restart the PHP-FPM service after making changes to the pool configuration.

sudo systemctl restart php8.3-fpm

Verify that the SSL certificate is valid if you are using HTTPS.

openssl s_client -connect yourdomain.com:443 -starttls smtp

Ensure the certificate is trusted and the chain is complete.

Check the firewall rules to ensure port 80 and 443 are open.

sudo ufw status

Allow traffic on the required ports.

sudo ufw allow 80/tcp
sudo ufw allow 443/tcp

Restart the firewall to apply the changes.

sudo ufw reload

If the issue persists, review the PHP-FPM and Nginx logs for specific error messages.

Ensure the PHP-FPM pool is configured to handle the specific WebSocket protocol version.

Check the PHP-FPM status to ensure the worker processes are not crashing.

sudo systemctl status php8.3-fpm

Verify that the PHP-FPM pool is listening on the correct port.

sudo netstat -tlnp | grep 9000

Ensure the PHP-FPM pool is configured to handle the specific WebSocket protocol version.

Check the PHP-FPM status to ensure the worker processes are not crashing.

Sponsored

Linux Dedicated Server

Rock-solid Linux dedicated servers with root access, KVM-IPMI and fully managed options. CentOS, Ubuntu, Debian, Rocky and AlmaLinux.

Tags: phpsecurityUbuntuNginxWebSockets
0
Was this helpful?

Related tutorials

Comments 0

Login to leave a comment.

No comments yet — be the first to share your thoughts.