Tag: unix-socket

  • Fixing PHP-FPM Socket Permission Denied: Nginx User/Group Mismatch on Ubuntu 22.04 LTS

    Resolve Nginx 502 Bad Gateway errors caused by PHP-FPM Unix socket permission issues on Ubuntu 22.04 LTS by correcting user, group, and listen mode configurations.

    When deploying or managing web applications on an Ubuntu 22.04 LTS server, it's common to encounter the dreaded "502 Bad Gateway" error. Often, this indicates a communication breakdown between Nginx, your web server, and PHP-FPM, the FastCGI Process Manager that executes your PHP code. A frequent culprit is a permission denied error when Nginx attempts to connect to the PHP-FPM Unix socket, typically stemming from a mismatch in user and group permissions.

    This guide will walk you through diagnosing and resolving this issue by ensuring Nginx has the necessary access to the PHP-FPM socket, restoring your web application's functionality.

    Symptom & Error Signature

    Users attempting to access your website will typically see a "502 Bad Gateway" error page directly from Nginx. On the backend, your Nginx error logs will clearly indicate the permission issue.

    Browser Output: ` 502 Bad Gateway nginx/1.22.1 `

    Nginx Error Log (/var/log/nginx/error.log or similar): `nginx 2023/10/27 10:35:45 [crit] 12345#12345: *1 connect() to unix:/var/run/php/php8.1-fpm.sock failed (13: Permission denied) while connecting to upstream, client: 192.168.1.100, server: example.com, request: "GET /index.php HTTP/1.1", upstream: "fastcgi://unix:/var/run/php/php8.1-fpm.sock:", host: "example.com" `

    The key part of this error is (13: Permission denied) while connecting to upstream. This specifically tells us that Nginx could not establish a connection to the PHP-FPM Unix socket due to insufficient permissions.

    Root Cause Analysis

    The "PHP-FPM socket permission denied" error arises from a security mechanism designed to prevent unauthorized processes from interacting with the PHP-FPM service. When Nginx tries to communicate with PHP-FPM via a Unix domain socket, it requires read/write access to that socket file.

    Here's a breakdown of the common underlying reasons:

    1. Nginx User/Group Mismatch:
    2. * By default, Nginx on Ubuntu runs as the www-data user and group.
    3. * PHP-FPM also typically runs its pools as www-data. However, if the PHP-FPM pool is configured to run under a different user or group (e.g., php-fpm, a custom application user, or the root user by mistake), the socket it creates might not be accessible to www-data.
    1. Incorrect PHP-FPM Pool Socket Configuration (listen.owner, listen.group, listen.mode):
    2. * The PHP-FPM pool configuration (e.g., /etc/php/8.1/fpm/pool.d/www.conf) defines how the Unix socket is created.
    3. * If listen.owner or listen.group are set to users/groups other than www-data, and listen.mode is restrictive (e.g., 0600), Nginx (running as www-data) will be denied access.
    4. * The listen.mode directive determines the file permissions for the socket. A common secure setting is 0660, which grants read/write to the owner and group, but denies others. If the Nginx user is not part of the socket's group, this will fail.
    1. Parent Directory Permissions:
    2. * Even if the socket file itself has correct permissions, the directory containing it (e.g., /var/run/php/) must have appropriate permissions for the Nginx user to traverse and access the socket within. Incorrect directory permissions (e.g., 0700 owned by root) can prevent Nginx from even seeing the socket file.
    1. SELinux or AppArmor Interference (Less Common on Ubuntu):
    2. * While less frequent for this specific error on a default Ubuntu setup, security modules like SELinux (on Red Hat-based systems) or AppArmor (on Ubuntu) can enforce additional access controls that might block Nginx from connecting to the socket. This usually manifests with explicit denials in audit logs.

    Step-by-Step Resolution

    Follow these steps to diagnose and correct the PHP-FPM socket permission issue. We'll assume PHP 8.1 for the examples, adjust versions as needed (e.g., php8.2-fpm).

    1. Verify Nginx User and PHP-FPM Socket Path

    First, confirm the user Nginx is running as and the exact socket path Nginx is configured to use.

    1. Check Nginx User:
    2. Typically, Nginx runs as www-data. You can verify this in your main Nginx configuration (/etc/nginx/nginx.conf) or by inspecting running processes.
        grep "user" /etc/nginx/nginx.conf
        ```
        Expected output:
        ```
        user www-data;
        ```
        If not explicitly set, Nginx defaults to the user it was started by (often `root`, then it drops privileges to `www-data`).
        You can also check process ownership:
        ```bash
        ps aux | grep nginx | grep -v grep
        ```
    1. Confirm PHP-FPM Socket Path in Nginx Configuration:
    2. Navigate to your Nginx site configuration (e.g., /etc/nginx/sites-available/example.com.conf) and locate the fastcgi_pass directive.
        grep -r "fastcgi_pass" /etc/nginx/sites-enabled/
        ```
        Example output from a config file:
        ```nginx
        # /etc/nginx/sites-available/example.com.conf
        location ~ .php$ {
            include snippets/fastcgi-php.conf;
            fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
        }
        ```

    2. Inspect PHP-FPM Pool Configuration

    The most common cause is incorrect settings in the PHP-FPM pool configuration. We'll edit the www.conf file, which manages the default PHP-FPM pool.

    1. Open the PHP-FPM Pool Configuration:
    2. `bash
    3. sudo nano /etc/php/8.1/fpm/pool.d/www.conf
    4. `
    1. Verify user and group Directives:
    2. Ensure the user and group directives match the Nginx user (www-data).
        ; Unix user/group of processes
        ; Note: The user and group specified here are used for all processes of this pool.
        ;       This also affects the ownership of the socket if listen.owner/listen.group
        ;       are not set, or set to '0'.
        user = www-data
        group = www-data
    1. Verify listen Directives (Crucial):
    2. These directives control the ownership and permissions of the Unix socket file itself.
        ; The address on which to accept FastCGI requests.
        ; Valid syntaxes are:
        ;   'ip.add.re.ss:port'    - to listen on a TCP socket to a specific address on a specific port;
        ;   'port'                 - to listen on a TCP socket to all addresses on a specific port;
        ;   '/path/to/unix/socket' - to listen on a Unix socket.
        ; Note: This value is in effect only when the listening domain is a Unix socket.
        ;       The file created is owned by the user/group specified in 'listen.owner' and 'listen.group'.

    ; Set permissions for unix socket, if one is used. In general to make it work ; with Nginx you will want to set it to 0660 or 0666. ; listen.owner = www-data ; listen.group = www-data ; listen.mode = 0660 `

    Ensure these lines are uncommented (no leading semicolon ;) and configured as follows:

        listen.owner = www-data
        listen.group = www-data
        listen.mode = 0660
    • listen.owner = www-data: Sets the owner of the socket file to www-data.
    • * listen.group = www-data: Sets the group of the socket file to www-data.
    • * listen.mode = 0660: Sets the file permissions to rw-rw----. This means the owner (www-data) and the group (www-data) have read and write access, while others have no access. Since Nginx runs as www-data, it will have full access.

    [!WARNING] > Do not set listen.mode = 0777 or similarly permissive modes unless absolutely necessary and you understand the security implications. 0660 with correct owner/group is typically secure and sufficient.

    1. Save and Exit:
    2. Save the changes (Ctrl+O, then Enter) and exit nano (Ctrl+X).

    3. Restart PHP-FPM and Nginx

    After modifying the PHP-FPM configuration, you must restart the PHP-FPM service for changes to take effect. It's also good practice to restart Nginx.

    sudo systemctl restart php8.1-fpm
    sudo systemctl restart nginx

    [!IMPORTANT] If systemctl restart php8.1-fpm fails, check the PHP-FPM logs for syntax errors: sudo journalctl -u php8.1-fpm -f

    4. Verify Socket File Permissions

    After restarting PHP-FPM, the socket file should be recreated with the new permissions. Verify its ownership and mode.

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

    Expected output (or similar, depending on PHP version): ` srw-rw—- 1 www-data www-data 0 Oct 27 10:45 /var/run/php/php8.1-fpm.sock ` The s at the beginning indicates it's a socket file. Crucially, the owner and group should both be www-data, and the permissions should be rw-rw----.

    If the group is something other than www-data (e.g., php-fpm), you have two main options: 1. Change listen.group in www.conf to www-data (as done in Step 2, and recommended). 2. Add the www-data user to that specific group. For example, if the socket's group is php-fpm: `bash sudo usermod -aG php-fpm www-data sudo systemctl restart nginx ` Then, ensure listen.mode = 0660 is set in www.conf and restart php8.1-fpm.

    5. Check Parent Directory Permissions

    While less common to be the primary cause for this specific error after correcting FPM config, incorrect directory permissions for /var/run/php/ can also contribute. Ensure the Nginx user can traverse this directory.

    ls -ld /var/run/php

    Expected output: ` drwxr-xr-x 2 root root 60 Oct 27 10:45 /var/run/php ` The drwxr-xr-x (755) permissions allow root full access, and all other users (including www-data) read and execute (traverse) access. This is generally sufficient. If the permissions are more restrictive (e.g., drwx------), you might need to adjust them:

    sudo chmod 755 /var/run/php
    ```

    6. Test Your Website

    After completing the steps and restarting services, try accessing your website again. The "502 Bad Gateway" error should now be resolved, and your PHP application should load correctly.

    If the issue persists, review the Nginx and PHP-FPM error logs again (e.g., sudo tail -f /var/log/nginx/error.log and sudo journalctl -u php8.1-fpm -f) for any new errors or clues. There might be a different underlying problem, or a subtle configuration mistake.

  • Troubleshooting Nginx 502 Bad Gateway with php-fpm Unix Socket on Windows WSL2 Ubuntu

    Resolve Nginx 502 Bad Gateway errors on WSL2 Ubuntu when using php-fpm with a Unix socket. Debug common config, permission, and service issues.

    A 502 Bad Gateway error from Nginx typically indicates that Nginx, acting as a reverse proxy, failed to get a valid response from the upstream server – in this case, PHP-FPM. When working within a Windows Subsystem for Linux 2 (WSL2) Ubuntu environment, using a Unix socket for Nginx-PHP-FPM communication, several specific factors can contribute to this common yet frustrating error. This guide will walk you through diagnosing and resolving the issue.

    Symptom & Error Signature

    When you attempt to access your PHP-powered website in a browser, you will see a generic "502 Bad Gateway" message.

    <html>
    <head><title>502 Bad Gateway</title></head>
    <body>
    <center><h1>502 Bad Gateway</h1></center>
    <hr><center>nginx/1.24.0</center>
    </body>
    </html>

    The most crucial information for diagnosis, however, is found in your Nginx error logs. On Ubuntu, these are typically located at /var/log/nginx/error.log. You'll likely see entries similar to these:

    2023/10/27 10:35:15 [crit] 1234#1234: *6 connect() to unix:/var/run/php/php8.2-fpm.sock failed (13: Permission denied) while connecting to upstream, client: 127.0.0.1, server: yourdomain.com, request: "GET /index.php HTTP/1.1", upstream: "fastcgi://unix:/var/run/php/php8.2-fpm.sock:", host: "yourdomain.com"

    2023/10/27 10:35:18 [error] 1234#1234: *7 connect() to unix:/var/run/php/php8.2-fpm.sock failed (111: Connection refused) while connecting to upstream, client: 127.0.0.1, server: yourdomain.com, request: "GET /index.php HTTP/1.1", upstream: "fastcgi://unix:/var/run/php/php8.2-fpm.sock:", host: "yourdomain.com" `

    Root Cause Analysis

    A 502 Bad Gateway with PHP-FPM via a Unix socket points to a communication breakdown between Nginx and the PHP-FPM service. The error messages in the Nginx log provide specific clues:

    • (2: No such file or directory): This indicates that Nginx is looking for the PHP-FPM Unix socket at a specified path, but the file simply does not exist. This is usually due to PHP-FPM not running, or it's configured to create the socket at a different path than Nginx expects.
    • (13: Permission denied): Nginx found the socket, but the nginx user (typically www-data) does not have the necessary read/write permissions to access it or the directory containing it.
    • (111: Connection refused): This is the most common 502 indicator. Nginx found the socket, had permissions to access it, but PHP-FPM either refused the connection (e.g., it's not listening on that socket, it's crashed, or it's overwhelmed), or the socket itself is misconfigured within PHP-FPM.

    Common underlying reasons include:

    1. PHP-FPM Service Not Running: The most frequent culprit. If the php-fpm service isn't active, the Unix socket won't be created, and Nginx has nothing to connect to.
    2. Mismatched Socket Paths: The fastcgi_pass directive in your Nginx site configuration must precisely match the listen directive in your PHP-FPM pool configuration (www.conf). A minor typo can lead to a No such file or directory error.
    3. Incorrect Socket Permissions: PHP-FPM creates the Unix socket. If its listen.owner, listen.group, or listen.mode directives are restrictive, the www-data user (which Nginx runs as) may not be able to interact with the socket, leading to Permission denied.
    4. PHP-FPM Configuration Errors: Syntax errors in php-fpm.conf or a pool configuration file can prevent the service from starting or operating correctly.
    5. WSL2 Specifics: While WSL2's Ubuntu environment behaves largely like native Linux, ensure that systemd (if used for service management) is running correctly within your WSL2 instance, especially if you manually installed or configured services in older WSL versions that didn't enable systemd by default. Newer Ubuntu versions on WSL2 support systemd out-of-the-box.

    Step-by-Step Resolution

    Follow these steps sequentially to diagnose and resolve your Nginx 502 error.

    1. Verify PHP-FPM Service Status

    Start by checking if your PHP-FPM service is running. This is the most common reason for the socket not existing or refusing connections.

    sudo systemctl status php8.2-fpm

    Replace php8.2-fpm with your specific PHP version (e.g., php7.4-fpm, php8.1-fpm).

    • If it's active (running): Proceed to step 2.
    • If it's inactive (dead) or failed: Start it and check its logs.
        sudo systemctl start php8.2-fpm
        sudo systemctl status php8.2-fpm
        sudo journalctl -xeu php8.2-fpm # Check service specific logs for failures

    If it fails to start, investigate the output of journalctl for specific errors, which often point to configuration issues in PHP-FPM.

    2. Check Nginx Error Logs for Specific Clues

    As discussed in the "Symptom & Error Signature" section, the Nginx error log /var/log/nginx/error.log is your primary diagnostic tool.

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

    While running this command, try accessing your site in the browser. Pay close attention to the specific error message: No such file or directory, Permission denied, or Connection refused. This will guide your next steps.

    3. Inspect Nginx Site Configuration

    Ensure Nginx is configured to use the correct Unix socket path. Your site's Nginx configuration file is typically in /etc/nginx/sites-available/your_domain.conf.

    sudo nano /etc/nginx/sites-available/your_domain.conf

    Look for a location ~ .php$ block and the fastcgi_pass directive. It should look something like this:

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

    location / { try_files $uri $uri/ =404; }

    location ~ .php$ { include snippets/fastcgi-php.conf; fastcgi_pass unix:/var/run/php/php8.2-fpm.sock; # <– This path is critical }

    … other configurations } `

    [!IMPORTANT] The path specified in fastcgi_pass unix:/var/run/php/php8.2-fpm.sock; must exactly match the listen directive in your PHP-FPM pool configuration (Step 4).

    If you make changes, always test Nginx configuration syntax and reload:

    sudo nginx -t
    sudo systemctl reload nginx

    4. Inspect PHP-FPM Pool Configuration

    Next, verify that PHP-FPM is configured to listen on the Unix socket Nginx expects and with appropriate permissions. The default pool configuration is usually at /etc/php/8.2/fpm/pool.d/www.conf.

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

    Find the listen directive and verify its path. Also, check listen.owner, listen.group, and listen.mode.

    ; Set listen to the path where the Unix socket will be created

    ; Set permissions for the Unix socket. ; Nginx's www-data user typically needs to be able to read/write to this socket. ; 'www-data' user is usually part of 'www-data' group. listen.owner = www-data listen.group = www-data listen.mode = 0660 ; 0660 gives owner/group read/write access. `

    [!NOTE] Ensure the listen.owner and listen.group match the user Nginx runs as (usually www-data). The listen.mode = 0660 is generally safe and recommended for Unix sockets. If you're still having permission issues, you might temporarily try 0666 for testing, but revert to 0660 or more restrictive after diagnosing.

    If you made changes, restart PHP-FPM to apply them:

    sudo systemctl restart php8.2-fpm

    5. Verify Socket Existence and Permissions

    If PHP-FPM is running and configured correctly, the Unix socket file should exist. Check its presence and permissions.

    ls -l /var/run/php/php8.2-fpm.sock

    Expected output:

    srw-rw---- 1 www-data www-data 0 Oct 27 10:45 /var/run/php/php8.2-fpm.sock
    • s at the beginning indicates it's a socket.
    • www-data www-data indicates the owner and group.
    • rw-rw---- (0660) indicates permissions.

    Troubleshooting No such file or directory: If the file doesn't exist and PHP-FPM is running, double-check the listen path in www.conf (Step 4). There might be a typo.

    Troubleshooting Permission denied: 1. Mismatched Owner/Group: Ensure listen.owner and listen.group in www.conf are set to www-data (or whatever user Nginx runs as). 2. Insufficient Mode: Ensure listen.mode is at least 0660. 3. Nginx User not in Group: Less common, but ensure the www-data user is actually a member of the www-data group: `bash groups www-data # Output should include 'www-data' ` If not, you might need to add it (though usually it's implicit for the user of the same name): `bash sudo usermod -aG www-data www-data ` You would need to restart Nginx and PHP-FPM after changing user groups.

    6. Check for PHP-FPM Process Issues

    If PHP-FPM is running, the socket exists, and permissions seem correct, but you still get Connection refused, PHP-FPM might be overloaded or silently failing to process requests.

    • Check PHP-FPM logs:
    • `bash
    • sudo tail -f /var/log/php8.2-fpm.log # or equivalent, check php-fpm configuration for log path
    • `
    • Look for errors indicating memory limits, max children reached, or other critical issues.
    • Check PHP-FPM process count:
    • `bash
    • ps aux | grep php-fpm
    • `
    • You should see several php-fpm: pool www processes. If you see very few, or they're constantly dying and restarting, it indicates an underlying problem with your PHP application or PHP-FPM configuration.

    7. WSL2 Specific Considerations (Systemd)

    Modern Ubuntu versions on WSL2 (e.g., Ubuntu 22.04 LTS) include systemd support by default. If you're on an older setup or manually configured WSL, systemd might not be the default init system, potentially causing issues with services not starting or being managed correctly.

    • Verify systemd is running:
    • `bash
    • systemctl –user list-units
    • `
    • If this command works and shows services, systemd is likely active. If you get an error like "Failed to connect to bus", systemd might not be running.
    • Enable systemd (if not already): For older WSL2 Ubuntu installations, you might need to enable systemd. This typically involves modifying /etc/wsl.conf:
        sudo nano /etc/wsl.conf
        ```
        Add or modify the following:
        ```ini
        [boot]
        systemd=true
        ```
        Save the file, exit your WSL2 instance (`exit`), and then shut down WSL2 from PowerShell/CMD:
        ```powershell
        wsl --shutdown
        ```

    After going through these steps, retest your website. One of these resolutions should bring your PHP application back online. Remember to restart Nginx and PHP-FPM after any configuration changes.