Fix “502 Bad Gateway” error on NGINX server after upgrading PHP

I check my servers for upgrades on a regular basis and when I noticed yesterday that PHP was upgraded to version 5.5.12, I backed up everything of course (backup guide) and decided to upgrade which can easily be done with sudo apt-get dist-upgrade. Unfortunately I’ve ran into quite an annoying issue which I had not encountered before, all pages returned “502 Bad Gateway” errors.

I’ve done this a numerous time and the upgrade went very smoothly. I was even asked if I wanted to keep local configuration files or not. I choose yes and the installation proceeded. After installation was completed php got restarted and I received a notice that the upgrade was successful. Unfortunately when I went to check my website I got annoying 502 Bad Gateway” errors on every single page.


What does this error message mean? A gateway, is like an access point, a bridge that communicate one service with another, in this case the gateway can be a service/application (WordPress, running on PHP) that is working and recieving requests from NGINX web server. So there is a communication issue between PHP and NGINX.

Problem Solving 1: is PHP-FPM running?

As you can see I am also running the latest version of NGINX (1.6.0 as of May 10th 2014) which was updated a few days earlier. It was clearly an issue with PHP so I started to think of what could’ve gone wrong. The first thing that you should always do is check if PHP is even running. Perhaps something went wrong while restarting PHP. Use the following command to check whether PHP-FPM is running.

ps aux | grep php

ps aux will output all processes that are running, so we add | grep php to only output processes with php in the name. If you see PHP processes, then this is not the the issue. Otherwise try to stop/start/restart PHP.

sudo service php5-fpm stop
sudo service php5-fpm start
sudo service php5-fpm restart

If there are still no PHP-FPM processes running, you might try to remove PHP and reinstall it. If PHP-FPM is running correctly, skip this step and go to the following section.

sudo apt-get remove php5 php5-cgi php5-fpm
sudo apt-get install php5 php5-cgi php5-fpm
Problem Solving 2a: is PHP-FPM listening correctly?

A common issue is that the PHP-FPM service is not listening to the host/port which is configured in NGINX. Find the www.conf file on your server in the PHP folder. On Ubuntu this can be found here:


Search for the listen parameter and make note of it:

; The address on which to accept FastCGI requests.
; Valid syntaxes are:
;   ''    - 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 =

As you can see this is set to, but it is also commonly set to/var/run/php5-fpm.sock. In my config this was set to the latter and I found out that php5-fpm.sock was simply missing (removed during the upgrade), so I changed it to

Now find your NGINX server configuration file, usually located at/etc/nginx/sites-available, and open it. Look for something like this (location ~ \.php$):

location ~ \.php$ {
	try_files $uri =404;
	fastcgi_index index.php;
	include fastcgi_params;       

The parameter we are looking for is fastcgi_pass. This has to be the samevalue as in the listen parameter in the www.conf file. Change it accordingly. In my case I changed fastcgi_pass unix:/var/run/php5-fpm.sock; tofastcgi_pass;.

Of course you may never forget to restart the NGINX and PHP5-FPM services! You would be surprised how many people forget this step. It is necessary to do this so that the updated configuration files are loaded.

sudo service php5-fpm restart
sudo service nginx restart
Problem Solving 2b: permanently fix the issue

While the above fix works perfectly, it is not ideal since we need to change parameters which were probably changed for a reason. It turns out that issues like this are very common due to file permissions and owner issues. That is way php-fpm.sock was missing. The bug report can be found here. Follow these steps to fix permissions and owner on Ubuntu.

So first of all, make sure that your virtual hosts NGINX files are usingfastcgi_pass unix:/var/run/php5-fpm.sock; at the php configuration like this:

location ~ \.php$ {
	try_files $uri =404;
	fastcgi_pass unix:/var/run/php5-fpm.sock;
	fastcgi_index index.php;
	include fastcgi_params;       

Now edit the NGINX configuration file, found at /etc/nginx/nginx.conf and take note of the user (usually located on line 1). This can be www-data, nginx or something else you have set. I will call this “NGINXUSER”.

Now we will change the php-fpm configuration file, located at/etc/php5/fpm/pool.d/www.conf. Simply locate the listen parameter and change/add the appropriate values to match this (change NGINXUSER to the user you have noted down earlier):

listen = /var/run/php5-fpm.sock
listen.owner = NGINXUSER = NGINXUSER

Restart PHP5-FPM and NGINX with the following commands and now you should be able to upgrade PHP without any issues.

sudo service php5-fpm restart
sudo service nginx restart
Problem Solving 3: Change NGINX config

Perhaps the buffer and timeout parameters are configured incorrectly for your server or they don’t suffice anymore. You can find the NGINX configuration file at /etc/nginx/nginx.conf. Try increasing the following parameters.
Increase buffer and timeouts inside http block:

http {
	fastcgi_buffers 8 16k;
	fastcgi_buffer_size 32k;
	fastcgi_connect_timeout 300;
	fastcgi_send_timeout 300;
	fastcgi_read_timeout 300;
Problem Solving 4: Disable APC

APC caching can cause 502 Bad Gateway issues under particular environments causing segmentation faults. I highly suggest using Memcache(d), but XCACHE is also a good alternative.


Getting unexpected are always very annoying and can really cause a lot of issues (decreased potential income, loss of visitors,…). Especially when you have no clue what could be causing the error. Hopefully this article helped you solve this issue.

centOS 7.0 安装lamp 环境

centOS 7.0 安装lamp 环境
# 准备
1. 7.0 防火墙已有firewall作为防火墙
systemctl stop firewalld.service #停止firewall
systemctl disable firewalld.service #禁止firewall开机启动
2. yum install iptables-services #安装
systemctl restart iptables.service #最后重启防火墙使配置生效
systemctl enable iptables.service #设置防火墙开机启动
3. vi /etc/selinux/config
SELINUX=enforcing #注释掉
SELINUXTYPE=targeted #注释掉
SELINUX=disabled #增加
:wq! #保存退出
setenforce 0 #使配置立即生效

# 安装apache
1. yum install httpd #根据提示,输入Y安装即可成功安装
chkconfig httpd on 开机自启动
service httpd start 启动httpd 服务
2. 设置虚拟主机
3. 注意事项
– 删除welcome.conf 不然设置的虚拟主机没用

systemctl start httpd.service #启动apache
systemctl stop httpd.service #停止apache
systemctl restart httpd.service #重启apache
systemctl enable httpd.service #设置apache开机启动
# 安装mysql
1. CentOS 7.0中,已经使用MariaDB替代了MySQL数据库
ystemctl start mariadb.service #启动MariaDB
systemctl stop mariadb.service #停止MariaDB
systemctl restart mariadb.service #重启MariaDB
systemctl enable mariadb.service #设置开机启动
2. 设置mysql的密码
mysqladmin -u root password “123456”

# 安装php
1. 事先确认yum源的链接是不是有效的。
– rpm -Uvh
rpm -Uvh
– 确认安装的php版本
yum list –enablerepo=remi –enablerepo=remi-php56 | grep php
– 安装php5.6
yum install –enablerepo=remi –enablerepo=remi-php56 php php-opcache php-pecl-apcu php-devel php-mbstring php-mcrypt php-mysqlnd php-phpunit-PHPUnit php-pecl-xdebug php-pecl-xhprof php-pdo php-pear php-fpm php-cli php-xml php-bcmath php-process php-gd php-common

# apache 配置
1. 编辑 http.conf(配置文件在 /etc/httpd/conf.d)
AddType application/x-httpd-php .php .phtml .php3 .inc
AddType application/x-httpd-php-source .phps
2. 重启apache service http restart 或者
systemctl restart httpd.service

全解:解决Apache下403 Forbidden错误



DocumentRoot /usr/local/www/data

<directory “/usr/local/www/data”>
Options Indexes FollowSymLinks
AllowOverride None
Order allow,deny
Allow from all
DocumentRoot /var/www
这时往往会忽略了对后面的Directory 项的修改,必须将里面的路径同时修改为 /var/www才行,否则将会访问所有目录都出现 403 forbidden错误。



配置了下php的php.in文件再次localhost打开发现错误:HTTP 错误 403 – 禁止访问,即403 Forbidden:You don’t have permission to access / on this server.权限又不够了?



<Directory />
Options FollowSymLinks
AllowOverride None
Order deny,allow
Deny from all
发现了吧。由于配置了php后,这里的“Deny from all”已经拒绝了一切连接。把该行改成“allow from all”,修改后的代码如下,问题解决。

<Directory />
Options FollowSymLinks
AllowOverride None
Order deny,allow
allow from all



另外一种可能性出现在我们配置了不同的VirtualHost,并且有某个VirtualHost的DocumentRoot不在全局的DocumentRoot目录下,这时必须在全局种单独增加对该目录的Directory 项进行设置,否则该VirtualHost下的所有访问均会出现403 forbidden错误。





第二:看看User Group指定的用户有没有权限访问那个目录,否则用chown修改目录的所有者


1、/usr/sbin/sestatus -v ##如果SELinux status参数为enabled即为开启状态
SELinux status: enabled
2、getenforce ##也可以用这个命令检查
setenforce 0 ##设置SELinux 成为permissive模式
##setenforce 1 设置SELinux 成为enforcing模式
修改/etc/selinux/config 文件

开启: chkconfig iptables on
关闭: chkconfig iptables off 或者 /sbin/chkconfig –level 2345 iptables off

2) 即时生效,重启后失效
service 方式
开启: service iptables start
关闭: service iptables stop
/etc/init.d/iptables status
/etc/init.d/iptables stop
/etc/init.d/iptables restart

apache rewrite 详解




目标 重写设置 说明
规范化URL RewriteRule ^/~([^/]+)/?(.*) /u/$1/$2 [R] 将/~user重写为/u/user的形式
RewriteRule ^/([uge])/([^/]+)$ /$1/$2/ [R] 将/u/user末尾漏掉的/补上
规范化HostName RewriteCond %{HTTP_HOST} !^fully\.qualified\.domain\.name [NC] 域名不合格
RewriteCond %{HTTP_HOST} !^$ 不空
RewriteCond %{SERVER_PORT} !^80$ 不是80端口
RewriteRule ^/(.*){SERVER_PORT}/$1 [L,R] 重写
RewriteCond %{HTTP_HOST} !^fully\.qualified\.domain\.name [NC]
RewriteCond %{HTTP_HOST} !^$
RewriteRule ^/(.*)$1 [L,R]
URL根目录转移 RewriteEngine on
RewriteRule ^/$ /e/www/ [R] 从/移到/e/www/
末尾目录补斜线 RewriteEngine on
(目录范围内) RewriteBase /~quux/
RewriteRule ^foo$ foo/ [R] /~quux/foo是一个目录,补/
RewriteEngine on
RewriteBase /~quux/
RewriteCond %{REQUEST_FILENAME} -d 如果请文件名是个目录
RewriteRule ^(.+[^/])$ $1/ [R] URL末尾不是斜线时补上
Web集群 RewriteEngine on
RewriteMap user-to-host txt:/path/to/map.user-to-host 用户-服务器映射
RewriteMap group-to-host txt:/path/to/ 组-服务器映射
RewriteMap entity-to-host txt:/path/to/map.entity-to-host 实体-服务器映射
RewriteRule ^/u/([^/]+)/?(.*) http://${user-to-host:$1|server0}/u/$1/$2 用户均衡
RewriteRule ^/g/([^/]+)/?(.*) http://${group-to-host:$1|server0}/g/$1/$2 组均衡
RewriteRule ^/e/([^/]+)/?(.*) http://${entity-to-host:$1|server0}/e/$1/$2 实体均衡
RewriteRule ^/([uge])/([^/]+)/?$ /$1/$2/.www/
RewriteRule ^/([uge])/([^/]+)/([^.]+.+) /$1/$2/.www/$3\
URL根目录搬迁 RewriteEngine on
RewriteRule ^/~(.+) http://newserver/~$1 [R,L] 到其它服务器
所用户名首字母分 RewriteEngine on
RewriteRule ^/~(([a-z])[a-z0-9]+)(.*) /home/$2/$1/.www$3 内一层括号为$2
NCSA imagemap移 RewriteEngine on
植为mod_imap RewriteRule ^/cgi-bin/imagemap(.*) $1 [PT]
多目录查找资源 RewriteEngine on
# first try to find it in custom/…
RewriteCond /your/docroot/dir1/%{REQUEST_FILENAME} -f
RewriteRule ^(.+) /your/docroot/dir1/$1 [L]
# second try to find it in pub/…
RewriteCond /your/docroot/dir2/%{REQUEST_FILENAME} -f
RewriteRule ^(.+) /your/docroot/dir2/$1 [L]
# else go on for other Alias or Alias directives,
RewriteRule ^(.+) – [PT]
据URL设置环境变量 RewriteEngine on
RewriteRule ^(.*)/S=([^/]+)/(.*) $1/$3 [E=STATUS:$2]
虚拟主机 RewriteEngine on
RewriteCond %{HTTP_HOST} ^www\.[^.]+\.host\.com$ 基于用户名
RewriteRule ^(.+) %{HTTP_HOST}$1 [C]
RewriteRule ^www\.([^.]+)\.host\.com(.*) /home/$1$2
内外人有别 RewriteEngine on
RewriteCond %{REMOTE_HOST} !^.+\.ourdomain\.com$ 基于远程主机
RewriteRule ^(/~.+)$1 [R,L]
错误重定向 RewriteEngine on
RewriteCond /your/docroot/%{REQUEST_FILENAME} !-f 不是regular文件
RewriteRule ^(.+) http://webserverB.dom/$1
程序处理特殊协议 RewriteRule ^xredirect:(.+) /path/to/nph-xredirect.cgi/$1 \ Xredirect协议
最近镜像下载 RewriteEngine on
RewriteMap multiplex txt:/path/to/map.cxan 顶级域名与最近ftp服务器映射
RewriteRule ^/CxAN/(.*) %{REMOTE_HOST}::$1 [C]
RewriteRule ^.+\.([a-zA-Z]+)::(.*)$ ${multiplex:$1|ftp.default.dom}$2 [R,L] 据顶级域名不同提供不同的FTP服务器
基于时间重写 RewriteEngine on
RewriteCond %{TIME_HOUR}%{TIME_MIN} >0700
RewriteCond %{TIME_HOUR}%{TIME_MIN} <1900
RewriteRule ^foo\.html$ 白天为早晚7点间
RewriteRule ^foo\.html$ foo.night.html 其余为夜间
向前兼容扩展名 RewriteEngine on
RewriteBase /~quux/
# parse out basename, but remember the fact
RewriteRule ^(.*)\.html$ $1 [C,E=WasHTML:yes]
# rewrite to phtml if exists
RewriteCond %{REQUEST_FILENAME}.phtml -f 如果存在$1.phtml则重写
RewriteRule ^(.*)$ $1.phtml [S=1]
# else reverse the previous basename cutout
RewriteCond %{ENV:WasHTML} ^yes$ 如果不存在$1.phtml,则保持不变
RewriteRule ^(.*)$ $1.html
文件改名(目录级) RewriteEngine on 内部重写
RewriteBase /~quux/
RewriteRule ^foo\.html$ bar.html
RewriteEngine on 重定向由客户端再次提交
RewriteBase /~quux/
RewriteRule ^foo\.html$ bar.html [R]
据浏览器类型重写 RewriteCond %{HTTP_USER_AGENT} ^Mozilla/3.*
RewriteRule ^foo\.html$ foo.NS.html [L]
RewriteCond %{HTTP_USER_AGENT} ^Lynx/.* [OR]
RewriteCond %{HTTP_USER_AGENT} ^Mozilla/[12].*
RewriteRule ^foo\.html$ foo.20.html [L]
RewriteRule ^foo\.html$ foo.32.html [L]
动态镜像远程资源 RewriteEngine on
RewriteBase /~quux/
RewriteRule ^hotsheet/(.*)$$1 [P] 利用了代理模块
RewriteEngine on
RewriteBase /~quux/
RewriteRule ^usa-news\.html$ [P]
反向动态镜像 RewriteEngine on
RewriteCond /mirror/of/remotesite/$1 -U
RewriteRule ^http://www\.remotesite\.com/(.*)$ /mirror/of/remotesite/$1
负载均衡 RewriteEngine on 利用代理实现round-robin效果
RewriteMap lb prg:/path/to/
RewriteRule ^/(.+)$ ${lb:$1} [P,L]
$| = 1;
$name = “www”; # the hostname base
$first = 1; # the first server (not 0 here, because 0 is myself)
$last = 5; # the last server in the round-robin
$domain = “foo.dom”; # the domainname
$cnt = 0;
while (<STDIN>) {
$cnt = (($cnt+1) % ($last+1-$first));
$server = sprintf(“%s%d.%s”, $name, $cnt+$first, $domain);
print “http://$server/$_”;
静态页面变脚本 RewriteEngine on
RewriteBase /~quux/
RewriteRule ^foo\.html$ foo.cgi [T=application/x-httpd-cgi]
阻击机器人 RewriteCond %{HTTP_USER_AGENT} ^NameOfBadRobot.*
RewriteCond %{REMOTE_ADDR} ^123\.45\.67\.[8-9]$
RewriteRule ^/~quux/foo/arc/.+ – [F]
阻止盗连你的图片 RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^*$ [NC] 自己的连接可不能被阻止
RewriteRule .*\.gif$ – [F]
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !.*/foo-with-gif\.html$
RewriteRule ^inlined-in-foo\.gif$ – [F]
拒绝某些主机访问 RewriteEngine on
RewriteMap hosts-deny txt:/path/to/hosts.deny
RewriteCond ${hosts-deny:%{REMOTE_HOST}|NOT-FOUND} !=NOT-FOUND [OR]
RewriteCond ${hosts-deny:%{REMOTE_ADDR}|NOT-FOUND} !=NOT-FOUND
RewriteRule ^/.* – [F]
用户授权 RewriteCond %{REMOTE_IDENT}@%{REMOTE_HOST} !^friend1@client1.quux-corp\.com$
RewriteCond %{REMOTE_IDENT}@%{REMOTE_HOST} !^friend2@client2.quux-corp\.com$
RewriteCond %{REMOTE_IDENT}@%{REMOTE_HOST} !^friend3@client3.quux-corp\.com$
RewriteRule ^/~quux/only-for-friends/ – [F]
外部重写程序模板 RewriteEngine on
RewriteMap quux-map prg:/path/to/
RewriteRule ^/~quux/(.*)$ /~quux/${quux-map:$1}
$| = 1;
while (<>) {
print $_;
搜索引擎友好 RewriteRule ^/products$ /content.php
RewriteRule ^/products/([0-9]+)$ /content.php?id=$1
RewriteRule ^/products/([0-9]+),([ad]*),([0-9]{0,3}),([0-9]*),([0-9]*$) /marso/content.php?id=$1&sort=$2&order=$3&start=$4



2、在Mac OS X Yosemite下搭建Apache+PHP+Mysql

3、Apache错误日志[warn] child process * still did not exit, sending a SIGTERM解决办法





使用<Directory>… </Directory>设置指定目录的访问权限,其中可包含:
Options FollowSymLinks Indexes MultiViews
AllowOverride None
为避免用户自行建立.htaccess文件修改访问权限,http.conf文件中默认设置每个目录为: AllowOverride None。
AccessFileName filename
AccessFileName .acl

Allow from all
Allow from

Deny 设定拒绝访问Apache服务器的主机 Deny from all 拒绝来自所有主机的访问 Deny from 拒绝指定IP地址主机的访问

Order Order allow,deny Order用于指定allow和deny的先后次序。