Question

Wordpress 502 & 504 Errors NGINX & PHP-FPM

So, my server was doing fine, but recently my Wordpress has been getting a lot of 502 and 504 errors – mostly when making updates to the site. I think it’s a PHP-FPM issue and perhaps how my server is configured since I’ve upgraded a couple times and it should be blazing fast – I have the 4GB / 60 GB / 4TB option.

@jtittle I saw you were an expert in this kind of thing.

Here’s my nginx.conf:

worker_processes 4; worker_rlimit_nofile 20480;

pid /var/run/nginx.pid;

events { worker_connections 2048;

    use epoll;
    multi_accept on;

}

http { set_real_ip_from 127.0.0.1; real_ip_header X-Forwarded-For;

    server_names_hash_bucket_size 64;
    server_name_in_redirect off;

    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    access_log off;
    error_log /var/log/nginx/error.log;

    keepalive_timeout 65;
    keepalive_requests 100000;
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;

    types_hash_max_size 2048;

    client_body_buffer_size      128k;
    client_max_body_size         24m;
    client_header_buffer_size    1k;
    large_client_header_buffers  4 4k;
    output_buffers               1 32k;
    postpone_output              1460;

    client_header_timeout  3m;
    client_body_timeout    3m;
    send_timeout           3m;

    open_file_cache max=1000 inactive=20s;
    open_file_cache_valid 30s;
    open_file_cache_min_uses 5;
    open_file_cache_errors off;

    gzip on;
    gzip_vary on;
    gzip_min_length 1000;
    gzip_types
    application/x-javascript
    application/javascript
    text/css
    text/javascript
    text/plain
    text/xml
    application/json
    application/vnd.ms-fontobject
    application/x-font-opentype
    application/x-font-truetype
    application/x-font-ttf
    application/xml font/eot
    font/opentype font/otf
    image/svg+xml
    image/vnd.microsoft.icon;
    gzip_disable "MSIE [1-6]\.";

    log_format main      '$remote_addr - $remote_user [$time_local]  '
    '"$request" $status $bytes_sent '
    '"$http_referer" "$http_user_agent" '
    '"$gzip_ratio"';

    log_format download  '$remote_addr - $remote_user [$time_local]  '
    '"$request" $status $bytes_sent '
    '"$http_referer" "$http_user_agent" '
    '"$http_range" "$sent_http_content_range"';

    map $status $loggable {
            ~^[23]  0;
            default 1;
    }

    server_tokens off;

    #include /etc/nginx/naxsi_core.rules;


    server {
            listen 80;
            listen 443 ssl http2;
            server_name www.nerdlouisville.org *.nerdlouisville.com;
            
            ssl_protocols TLSv1 TLSv1.1 TLSv1.2;                ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
            ssl_prefer_server_ciphers on;
            ssl_certificate /etc/letsencrypt/live/nerdlouisville.org/fullchain.pem;
            ssl_certificate_key /etc/letsencrypt/live/nerdlouisville.org/privkey.pem;
            ssl_trusted_certificate /etc/letsencrypt/live/nerdlouisville.org/chain.pem;
            ssl_session_cache shared:SSL:128m;
            ssl_session_timeout 1d;
            add_header Strict-Transport-Security "max-age=31557600; includeSubDomains";
            add_header X-Frame-Options "SAMEORIGIN" always;
            add_header X-Content-Type-Options "nosniff" always;
            add_header X-Xss-Protection "1";
            ssl_stapling on;
            ssl_stapling_verify on;
            resolver 8.8.8.8;
            
            return 301 https://nerdlouisville.org$request_uri;
    }
    server {
            server_name     nerdlouisville.org nerdlouisville.com;
            listen 80;
            return 301 https://nerdlouisville.org$request_uri;
    }
    server {
            listen 443 ssl http2;
            server_name nerdlouisville.org;
    
            ssl_protocols TLSv1 TLSv1.1 TLSv1.2;                ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
            ssl_prefer_server_ciphers on;
            ssl_certificate /etc/letsencrypt/live/nerdlouisville.org/fullchain.pem;
            ssl_certificate_key /etc/letsencrypt/live/nerdlouisville.org/privkey.pem;
            ssl_trusted_certificate /etc/letsencrypt/live/nerdlouisville.org/chain.pem;
            ssl_session_cache shared:SSL:128m;
            ssl_session_timeout 1d;
            add_header Strict-Transport-Security "max-age=31557600; includeSubDomains";
            add_header X-Frame-Options "SAMEORIGIN" always;
            add_header X-Content-Type-Options "nosniff" always;
            add_header X-Xss-Protection "1";
            ssl_stapling on;
            ssl_stapling_verify on;
            resolver 8.8.8.8;
    
            if ($http_user_agent ~ "MSIE" ) {
                    return 303 https://browser-update.org/update.html;
            }
    
            charset utf-8;
            
            
                    
        root /var/www/html;
        index index.php index.html index.htm;
        
            location / {
                    try_files $uri $uri/ /index.php?q=$uri&$args;
            }
            
            location /forum {
                try_files $uri @vanilla;
            }
            location @vanilla {
                rewrite ^/forum(/.*) /forum/index.php?p=$uri&$args last;
            }
                            
    
            location ~* \.(jpg|jpeg|gif|png|css|js|ico|xml)$ { expires 5d; }
            location = /favicon.ico { access_log off; log_not_found off; }
            location = /robots.txt { access_log off; log_not_found off; }
            location ~ /\. { log_not_found off; deny all; }
            
            
            location ~ \.php$ {
            include snippets/fastcgi-php.conf;
            fastcgi_pass unix:/run/php/php7.0-fpm.sock;
            }
    
    }
    
    
    
    upstream backend {
            server 127.0.0.1:4567 weight=1;
    }

Submit an answer

This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

Sign In or Sign Up to Answer

These answers are provided by our Community. If you find them useful, show some love by clicking the heart. If you run into issues leave a comment, or add your own answer to help others.

Accepted Answer

@michaelppfaff

The error in the PHP-FPM log:

server reached pm.max_children

When this happens, generally PHP-FPM will restart, which will cause a failed connection if NGINX is attempting to connect at the same time. We can up the limits on this setting as well as others in the www.conf file.

I’d make a backup of your www.conf file:

cp /etc/php/7.0/fpm/pool.d/www.conf /usr/local/src/www.conf

Then modify these values in /etc/php/7.0/fpm/pool.d/www.conf

pm.max_children = 16
pm.start_servers = 8
pm.min_spare_servers = 6
pm.max_spare_servers = 12

That’ll raise the default limits to more usable limits, though depending on traffic and what you’re running, those may need to increase. Generally, all values I use are divisible by 2 (i.e. I won’t use 5, 7, 9, etc) to prevent odd rounding. Details on how to set pm.start_servers is in the configuration comments as well to give you an idea of what it should be set to.

You’d then need to restart PHP-FPM:

service php7.0-fpm restart

@michaelppfaff

Before reposting, let me clean up a bit ;-). When posting a ton of data, sometimes it’ll get flagged, but I can publish on my end :-).

@michaelppfaff

The first thing I’d recommend, before we get started with the configuration, would be to tail the logs.

tail -25 /var/log/nginx/error.log

Also, let’s take a look at the PHP-FPM log, which should be in /var/log as well.

tail -25 /var/log/php7.0-fpm.log

That should give us a clearer indication of anything that may be wrong. You can also run:

nginx -t

To see if there’s anything wrong with your NGINX configuration.

Let’s start there first and we’ll work our way up/down :-).

Hi @michaelppfaff

Please supply the last lines from your error log from when the error happened:

tail -20 /var/log/nginx/error.log

And can you also post your PHP-FPM pool configuration, since you’re most likely either exceeding the memory limit or timeout.

/etc/php/7.0/fpm/pool.d/www.conf