PHP-FPM and Nginx: 502 Bad Gateway

170,220

Solution 1

If anyone finds this page by encountering the same problem I had, I found the answer here.

For those of you who can't be bothered to click and work it out for themselves... ;)

The Condition:

Ubuntu or Debian server with NGINX and PHP 5.3 works fine but upgrading PHP to 5.4 gives 502 Bad Gateway errors. Looking for services running on port 9000 (typically running netstat -lp or similar) returns nothing.

The fix:

Open /etc/php5/fpm/pool.d/www.conf and make a note of the 'listen' parameter (in my case /var/run/php5-fpm.sock):

; 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 mandatory.
listen = /var/run/php5-fpm.sock

and replace the fastcgi_pass variable in your vhost with the location you just noted.

So this sample symfony2 configuration (taken from here):

  # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
  location ~ ^/(app|app_dev)\.php(/|$) {
    fastcgi_pass   127.0.0.1:9000;
    fastcgi_split_path_info ^(.+\.php)(/.*)$;
    include fastcgi_params;
    fastcgi_param  SCRIPT_FILENAME    $document_root$fastcgi_script_name;
    fastcgi_param  HTTPS              off;
  }

becomes this:

  # pass the PHP scripts to FastCGI server at /var/run/php5-fpm.sock
  location ~ ^/(app|app_dev)\.php(/|$) {
    fastcgi_pass unix:/var/run/php5-fpm.sock;
    fastcgi_split_path_info ^(.+\.php)(/.*)$;
    include fastcgi_params;
    fastcgi_param  SCRIPT_FILENAME    $document_root$fastcgi_script_name;
    fastcgi_param  HTTPS              off;
  }

Then restart nginx:

sudo /etc/init.d/nginx restart

Note: replace ~ ^/(app|app_dev)\.php(/|$) { with ~ ^/index\.php(/|$) { if you're not on SF2**

Hope this saves someone a little bit of time :)

Edit

Of course, you could change the listen = /var/run/php5-fpm.sock to listen = 127.0.0.1:9000 in /etc/php5/fpm/pool.d/www.conf then restart php5-fpm (which would save you from having to change your vhosts), but you have to assume they changed php5-fpm to run through a socket rather than listening on port 9000 for a reason.

Edit2

If you're still experiencing 502 error see this answer.

Solution 2

Try setting these values, it solves problem in fast-cgi

fastcgi_buffer_size 16k;
fastcgi_buffers 4 16k;

Solution 3

I made all this similar tweaks, but from time to time I was getting 501/502 errors (daily).

This are my settings on /etc/php5/fpm/pool.d/www.conf to avoid 501 and 502 nginx errors… The server has 16Gb RAM. This configuration is for a 8Gb RAM server so…

sudo nano /etc/php5/fpm/pool.d/www.conf

then set the following values for

pm.max_children = 70
pm.start_servers = 20
pm.min_spare_servers = 20
pm.max_spare_servers = 35
pm.max_requests = 500

After this changes restart php-fpm

sudo service php-fpm restart

Solution 4

If you met the problem after upgrading php-fpm like me, try this: open /etc/php5/fpm/pool.d/www.conf uncomment the following lines:

listen.owner = www-data
listen.group = www-data
listen.mode = 0666

then restart php-fpm.

Solution 5

Don't forget that php-fpm is a service. After installing it, make sure you start it:

# service php-fpm start
# chkconfig php-fpm on
Share:
170,220

Related videos on Youtube

zeboidlund
Author by

zeboidlund

Updated on July 05, 2022

Comments

  • zeboidlund
    zeboidlund almost 2 years

    Configuration

    • Ubuntu Server 11.10 64 bit
    • Amazon AWS, Ec2, hosted on the cloud
    • t1.micro instance

    Before I write anything else, I'd like to state that I've checked both nginx 502 bad gateway and Nginx + PHP-FPM 502 Bad Gateway threads, which unfortunately haven't helped me in this regard.

    The issue appears to be rather common: a misconfiguration of nginx or php-fpm can lead to a 502 Bad Gateway error, which is something that I haven't been able to get rid of. Note that this appears even when I go to my domain root, without specifying any particular directory.

    I'm running an Amazon EC2 webserver, with port 9000 enabled, port 80 open, etc.

    The question in particular is, how can I get rid of this nasty error? Or, better yet, how can I get php5-fpm to actually work.

    What I Have Attempted so Far

    Mostly consistent editing of configuration files, notably php-fpm.conf and nginx.conf.

    i. php-fpm.conf

    I've added the following, which hasn't quite helped much:

    ;;;;;;;;;;;;;
    ; Fpm Start ;
    ;;;;;;;;;;;;;
    
    ;pm.start_servers = 20
    ;pm.min_spare_servers = 5
    ;pm.max_spare_servers = 35
    

    Now, afterward I tried including my configuration files:

    include=/etc/php5/fpm/*.conf

    Which only screwed me even further.

    Full Configuration

    ;;;;;;;;;;;;;;;;;;;;;
    ; FPM Configuration ;
    ;;;;;;;;;;;;;;;;;;;;;
    
    ; All relative paths in this configuration file are relative to PHP's install
    ; prefix (/usr). This prefix can be dynamicaly changed by using the
    ; '-p' argument from the command line.
    
    ; Include one or more files. If glob(3) exists, it is used to include a bunch of
    ; files from a glob(3) pattern. This directive can be used everywhere in the
    ; file.
    ; Relative path can also be used. They will be prefixed by:
    ;  - the global prefix if it's been set (-p arguement)
    ;  - /usr otherwise
    ;include=/etc/php5/fpm/*.conf
    
    ;;;;;;;;;;;;;;;;;;
    ; Global Options ;
    ;;;;;;;;;;;;;;;;;;
    
    [global]
    ; Pid file
    ; Note: the default prefix is /var
    ; Default Value: none
    pid = /var/run/php5-fpm.pid
    
    ; Error log file
    ; Note: the default prefix is /var
    ; Default Value: log/php-fpm.log
    error_log = /var/log/php5-fpm.log
    
    ; Log level
    ; Possible Values: alert, error, warning, notice, debug
    ; Default Value: notice
    log_level = notice
    
    ; If this number of child processes exit with SIGSEGV or SIGBUS within the time
    ; interval set by emergency_restart_interval then FPM will restart. A value
    ; of '0' means 'Off'.
    ; Default Value: 0
    ;emergency_restart_threshold = 0
    
    ; Interval of time used by emergency_restart_interval to determine when 
    ; a graceful restart will be initiated.  This can be useful to work around
    ; accidental corruptions in an accelerator's shared memory.
    ; Available Units: s(econds), m(inutes), h(ours), or d(ays)
    ; Default Unit: seconds
    ; Default Value: 0
    emergency_restart_interval = 0
    
    ; Time limit for child processes to wait for a reaction on signals from master.
    ; Available units: s(econds), m(inutes), h(ours), or d(ays)
    ; Default Unit: seconds
    ; Default Value: 0
    ;process_control_timeout = 0
    
    ; Send FPM to background. Set to 'no' to keep FPM in foreground for debugging.
    ; Default Value: yes
    daemonize = no
    
    ;;;;;;;;;;;;;
    ; Fpm Start ;
    ;;;;;;;;;;;;;
    
    ;pm.start_servers = 20
    ;pm.min_spare_servers = 5
    ;pm.max_spare_servers = 35
    
    ;;;;;;;;;;;;;;;;;;;;
    ; Pool Definitions ; 
    ;;;;;;;;;;;;;;;;;;;;
    
    ; Multiple pools of child processes may be started with different listening
    ; ports and different management options.  The name of the pool will be
    ; used in logs and stats. There is no limitation on the number of pools which
    ; FPM can handle. Your system will tell you anyway :)
    
    ; To configure the pools it is recommended to have one .conf file per
    ; pool in the following directory:
    include=/etc/php5/fpm/pool.d/*.conf
    

    ii. nginx.conf

    In all honesty this configuration is a smattering of a few websites I've visited, but I can tell you that before this 502 Bad Gateway business, the server was running fine (without PHP working. Period.).

    The issue primarily lies in the fact that something is terribly, terribly wrong. And now, when I try to do a service php5-fpm restart, it hangs in what I'm guessing is an infinite loop or something, which I can't even CTRL-C out of.

    Full Configuration

    user www-data;
    worker_processes 1;
    pid /var/run/nginx.pid;
    
    events {
        worker_connections 64;
        # multi_accept on;
    }
    
    http {
    
        ##
        # Basic Settings
        ##
    
        sendfile on;
        tcp_nopush off;
        tcp_nodelay on;
        keepalive_timeout 65;
        types_hash_max_size 2048;
        # server_tokens off;
    
        # server_names_hash_bucket_size 64;
        # server_name_in_redirect off;
    
        include /etc/nginx/mime.types;
        default_type application/octet-stream;
    
        ##
        # Logging Settings
        ##
    
        access_log /var/log/nginx/access.log;
        error_log /var/log/nginx/error.log;
    
        ##
        # Gzip Settings
        ##
    
        gzip on;
        gzip_disable "msie6";
    
        # gzip_vary on;
        # gzip_proxied any;
        # gzip_comp_level 6;
        # gzip_buffers 16 8k;
        # gzip_http_version 1.1;
        # gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
    
        ##
        # Virtual Host Configs
        ##
    
        include /etc/nginx/conf.d/*.conf;
        include /etc/nginx/sites-enabled/*;
    
        server {
            listen 80;
            server_name ec2-xx-xx-xx-xx.compute-x.amazonaws.com;
    
            location ~ ^(.+\.php)(.*)$ {
                root   /home/wayvac/public;
                fastcgi_pass   unix:/var/run/php5-fpm.pid;  
                #fastcgi_pass   127.0.0.1:9000; #Un-comment this and comment "fastcgi_pass   unix:/var/run/php-fpm/php-fpm.sock;" if you are not using php-fpm.
                fastcgi_index  index.php;
                set $document_root2 $document_root;
                if ($document_root2 ~ "^(.*\\\\).*?[\\\\|\/]\.\.\/(.*)$") { set $document_root2 $1$2; }
                if ($document_root2 ~ "^(.*\\\\).*?[\\\\|\/]\.\.\/(.*)$") { set $document_root2 $1$2; }
                if ($document_root2 ~ "^(.*\\\\).*?[\\\\|\/]\.\.\/(.*)$") { set $document_root2 $1$2; }
                if ($document_root2 ~ "^(.*\\\\).*?[\\\\|\/]\.\.\/(.*)$") { set $document_root2 $1$2; }
                if ($document_root2 ~ "^(.*\\\\).*?[\\\\|\/]\.\.\/(.*)$") { set $document_root2 $1$2; }
                fastcgi_split_path_info ^(.+\.php)(.*)$;
                fastcgi_param   SCRIPT_FILENAME $document_root2$fastcgi_script_name;
                fastcgi_param   PATH_INFO   $fastcgi_path_info;
                fastcgi_param   PATH_TRANSLATED $document_root2$fastcgi_path_info;
                include fastcgi_params;
                fastcgi_param  DOCUMENT_ROOT      $document_root2;
            }       
    
            access_log /var/log/nginx/access.log;
            error_log /var/log/nginx/error.log;
    
            location / {
                root /home/wayvac/public;   
                index index.html index.htm index.php;
            }
    
            location ~* \.(?:ico|css|js|gif|jpe?g|png)$ {
                # Some basic cache-control for static files to be sent to the browser
                expires max;
                add_header Pragma public;
                add_header Cache-Control "public, must-revalidate, proxy-revalidate";
            }
    
            #include drop.conf;
            #include php.conf;
        }
    }
    
  • Desmond Hume
    Desmond Hume almost 11 years
    Unix sockets are only marginally faster and could fail under heavy load drupal.org/node/1635622#comment-6814968
  • jrhorn424
    jrhorn424 over 10 years
    This did it for me. It was quite difficult to pin down since the fastcgi error was truncated in the nginx log. Thanks!
  • Stefan
    Stefan over 10 years
    go ahead and set it to 64k for Symfony2.3 :) the error output of Symfony just seems to overwhelm the buffers...
  • vsync
    vsync about 10 years
    didn't help, it was already set like that, and I keep experiencing 502 all the time.
  • nealio82
    nealio82 about 10 years
    Bad gateway just means Nginx can't find PHP. Are you sure the php-fpm service is installed and running? Try restarting it if it is running, perhaps it's hanging.
  • user111671
    user111671 about 10 years
    @Nealio I'm using ubuntu server running nginx. do you know where exactly I can find the file referring to # pass the PHP scripts to FastCGI server at /var/run/php5-fpm.sock location ~ ^/(app|app_dev)\.php(/|$) { fastcgi_pass unix:/var/run/php5-fpm.sock; fastcgi_split_path_info ^(.+\.php)(/.*)$; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param HTTPS off; }?
  • nealio82
    nealio82 about 10 years
    I'm not quite sure what you're asking. Are you saying you don't know where to find the file with that block in? If so, then that'll be whichever vhost file you're setting up, in /etc/nginx/sites-available. If you mean you can't find the file which tells you the location of the socket file (php5-fpm.sock), it should be /etc/php5/fpm/pool.d/www.conf. If it's not there comment back & I'll set up an ubuntu / nginx instance and let you know.
  • Chu-Siang Lai
    Chu-Siang Lai about 10 years
    I meet some problem, and need fix the /etc/php5/fpm/pool.d/www.conf on Ubuntu 12.04, but Debian 7.0 is not!
  • nealio82
    nealio82 about 10 years
    I've just checked on a Debian 7.2 server (default config) and it's definitely there. Can you search for it with find? find / -iname "www.conf"
  • biphobe
    biphobe almost 10 years
    @Jusfeel These options should be added to nginx's config file.
  • marksyzm
    marksyzm almost 10 years
    They seem to have changed this recently and made it so it always uses the original port numbers i.e. 127.0.0.1:9000
  • jan
    jan over 8 years
    What a miracle solution. Thanks
  • CMCDragonkai
    CMCDragonkai over 8 years
    Why is this the solution? Changing from TCP to Unix Domain Socket or Unix Domain Socket to TCP does nothing for me? I keep getting 502 gateway errors, and the NGINX log says the "Connection reset by peer while reading response header from upstream", in which upstream is PHP-FPM.
  • conradkleinespel
    conradkleinespel over 8 years
    Solved it for me too. The conf file was /etc/php/php-fpm.d/www/conf on Arch Linux. Note that setting permissions to 0666 is probably not suitable for production. Instead, a production server should match the Nginx user and the PHP-FPM user and keep the permissions to 0660 to increase security.
  • akajack
    akajack over 8 years
    I applied to Siwapp installed under nginx and it works great! Thank you very much :)
  • nealio82
    nealio82 over 8 years
    If you're getting 'connection reset by peer' then it surely must have been talking to PHP-FPM initially for each request, and this solution isn't applicable to your problem (read 'The Condition' at the top of my answer - this isn't a catch-all solution for all problems). I think you probably need to find out why PHP-FPM is dying as it's processing your scripts.
  • Crysis
    Crysis about 7 years
    Nailed it :) dude
  • Lucas Bustamante
    Lucas Bustamante almost 7 years
  • Florin
    Florin over 4 years
    this is the right solution if nginx error connect to php5-fpm.sock failed (13: Permission denied)