[Nginx][FastCGI][PHP] Классика жанра - ошибка "502 Bad Gateway"

xintrea

Новичок
[Nginx][FastCGI]
PHP:
 Классика жанра - ошибка "502 Bad Gateway"[/b]

Здравствуйте!


Пытаюсь настроить Nginx на виртуальном хостинге так, чтобы выполнялись php-стрипты. Статика отдается нормально, а результат работы php-нет.

При запросе php-скрипта, в браузере показывается ошибка:

[code]502 Bad Gateway[/code]

В логе появляется строка:

[code][error] 9599#0: *12 recv() failed (104: Connection reset by peer) 
while reading response header from upstream, 
client: 109.165.44.169, 
server: webhamster.ru, 
request: "GET /phpinfo.php HTTP/1.1", 
upstream: "fastcgi://127.0.0.1:8888", 
host: "webhamster.ru"[/code]


Последовательность моих действий по настройке:


[b]1[/b]. Установил php-cgi командой

[code]apt-get install php-cgi[/code]


[b]2[/b]. Сделал скрипт start_php_fcgi.sh для запуска PHP в режиме FastCGI сервера:

[code]#!/bin/bash

## ABSOLUTE path to the PHP binary
PHPFCGI="/usr/bin/php-cgi"

## tcp-port to bind on
FCGIPORT="8888"

## IP to bind on
FCGIADDR="127.0.0.1"

## number of PHP children to spawn
PHP_FCGI_CHILDREN=5

## number of request before php-process will be restarted
PHP_FCGI_MAX_REQUESTS=1000

# allowed environment variables sperated by spaces
ALLOWED_ENV="ORACLE_HOME PATH USER"

## if this script is run as root switch to the following user
USERID=www-data

################## no config below this line

if test x$PHP_FCGI_CHILDREN = x; then
  PHP_FCGI_CHILDREN=5
fi

ALLOWED_ENV="$ALLOWED_ENV PHP_FCGI_CHILDREN"
ALLOWED_ENV="$ALLOWED_ENV PHP_FCGI_MAX_REQUESTS"
ALLOWED_ENV="$ALLOWED_ENV FCGI_WEB_SERVER_ADDRS"

if test x$UID = x0; then
  EX="/bin/su -m -c \"$PHPFCGI -q -b $FCGIADDR:$FCGIPORT\" $USERID"
else
  EX="$PHPFCGI -b $FCGIADDR:$FCGIPORT"
fi

echo $EX

# copy the allowed environment variables
E=

for i in $ALLOWED_ENV; do
  E="$E $i=${!i}"
done

# clean environment and set up a new one
nohup env - $E sh -c "$EX" &> /dev/null &[/code]


[b]3[/b]. Запускаю этот скрипт (start_php_fcgi.sh)


[b]4[/b]. Проверяю, работает ли PHP как сервер. Да, работает:

[code]# ps aux | grep php
root 9665 pts/1 S sh -c /bin/su -m -c "/usr/bin/php-cgi -q -b 127.0.0.1:8888" www-data
www-data  9666 pts/1 S  /bin/su -m -c /usr/bin/php-cgi -q -b 127.0.0.1:8888 www-data
www-data  9667 pts/1 S sh -c /usr/bin/php-cgi -q -b 127.0.0.1:8888
www-data  9668 ? Ss /usr/bin/php-cgi -q -b 127.0.0.1:8888
www-data  9669 ? S /usr/bin/php-cgi -q -b 127.0.0.1:8888
www-data  9670 ? S /usr/bin/php-cgi -q -b 127.0.0.1:8888
www-data  9671 ? S /usr/bin/php-cgi -q -b 127.0.0.1:8888
www-data  9672 ? S /usr/bin/php-cgi -q -b 127.0.0.1:8888
www-data  9673 ? S /usr/bin/php-cgi -q -b 127.0.0.1:8888
root 9727 pts/1 S+ grep php[/code]


[b]5[/b]. Проверяю, слушает ли PHP действительно 8888 порт. Да, слушает:

[code]# netstat -lnp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address      Foreign Address  State  PID/Program name
tcp        0      0 0.0.0.0:80              0.0.0.0:*   LISTEN      9598/nginx
tcp        0      0 0.0.0.0:22              0.0.0.0:*   LISTEN      1417/sshd
tcp        0      0 127.0.0.1:8888          0.0.0.0:*   LISTEN      9668/php-cgi
tcp6       0      0 :::22                        :::*   LISTEN      1417/sshd

udp        0      0 594.527.568.513:123       0.0.0.0:*               1332/ntpd
udp        0      0 127.0.0.1:123           0.0.0.0:*               1332/ntpd
udp        0      0 0.0.0.0:123             0.0.0.0:*               1332/ntpd
udp6       0      0 fe80::216:3eff:fe1b:123 :::*                    1332/ntpd
udp6       0      0 ::1:123                 :::*                    1332/ntpd
udp6       0      0 :::123                  :::*                    1332/ntpd
Active UNIX domain sockets (only servers)
Proto RefCnt Flags       Type       State         I-Node   PID/Program name    Path[/code]


[b]6[/b]. Прописываю в следущую конфигурацию Nginx:

[code]server {
        listen   80;
        server_name  webhamster.ru;

        error_log   /var/log/nginx/webhamster.warn.log warn;
        access_log  /var/log/nginx/webhamster.access.log;

        root   /var/www/webhamster;
        charset utf-8;

        location / {
                root   /var/www/webhamster;
                index  index.html index.htm;
        }

        location ~ \.php$ {
                fastcgi_pass   127.0.0.1:8888;
                fastcgi_index  index.php;
                fastcgi_param  SCRIPT_FILENAME $fastcgi_script_name;
                # include fastcgi_params;
        }
}[/code]


[b]7[/b]. Перезапускаю Nginx:

[code]# /etc/init.d/nginx restart
Restarting nginx: nginx.[/code]


[b]8[/b]. Создаю в каталоге /var/www/webhamster два файла: hello.html и phpinfo.php. 

В hello.html прописываю "Hello" - и при открытии URL "webhamster.ru/hello.html" я вижу эту надпись.

В phpinfo.php прописываю "<?php phpinfo(); ?>" - и при открытии URL "webhamster.ru/phpinfo.php" получаю ошибку "502 Bad Gateway". Установил права на этот файл 777, ошибка осталась.


[b]9[/b]. На просторах интернета узнал, что на VDS хостингах не всегда можно обращаться к IP 127.0.0.1 - это как-то связано с особенностью виртуализации. И нужно работать с IP хоста. Поэтому я дал команду ifconfig, и узнал IP - 94.127.68.213.

В скрипте, запускающем PHP, я вместо 127.0.0.1 прописал:

[code]FCGIADDR="94.127.68.213"[/code]

А так же в конфигурации Nginx прописал вместо 127.0.0.1 прописал:

[code]fastcgi_pass   94.127.68.213:8888;[/code]

Перезапустил PHP и Nginx, проверил процессы, проверил что PHP слушает порт. Однако при открытии URL "webhamster.ru/phpinfo.php" получаю все ту же ошибку: "502 Bad Gateway".


[b]Вопрос[/b]: что еще где нужно крутануть, чтобы Nginx начал нормально коннектиться к серверу PHP Fast CGI? Что где проверить? Как узнать - это Nginx цепляется "не туда", или всетаки Nginx цепляется туда, но PHP не хочет отвечать Nginx?

[i]fixxxer: заменил твой IP на смешную фигню. Не надо так делать, когда php-fcgi торчит наружу, тут много кулхацкеров ;) [/i]

[i]xintrea: Спасибо :). Хотя, php всеравно не работает. Кроме того, делаешь ping webhamster.ru и IP у тебя в кармане. Я в конфигах поправил уже на 127.0.0.1. Заменил в сообщении смешную фигню обратно на человеческий IP.[/i]
 

fixxxer

К.О.
Партнер клуба
# include fastcgi_params;

решеточка лишняя.

-~{}~ 03.09.10 18:02:

и еще

-fastcgi_param SCRIPT_FILENAME $fastcgi_script_name;
+fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

-~{}~ 03.09.10 18:04:

>>На просторах интернета узнал, что на VDS хостингах не всегда можно обращаться к IP 127.0.0.1

если в netstat появился - значит можно.

такое ограничение я встречал только у vsdmanager-овского ядра основанного на freebsd.

более того можно использовать unix sockets в этом случае.
 

xintrea

Новичок
Автор оригинала: fixxxer
# include fastcgi_params;

решеточка лишняя.
Хоть комментируй, хоть раскомментируй, толку никакого.

и еще

-fastcgi_param SCRIPT_FILENAME $fastcgi_script_name;
+fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
Это неприципиально. Если бы соединение с PHP работало бы нормально, при неправильном имени PHP-файла была б ошибка вида "No input file specified".

>>На просторах интернета узнал, что на VDS хостингах не всегда можно обращаться к IP 127.0.0.1
Если в netstat появился - значит можно.
Такое ограничение я встречал только у vsdmanager-овского ядра основанного на freebsd.
Более того можно использовать unix sockets в этом случае.
Хостер truevds.ru, XEN виртуализация. То есть, на 127.0.0.1 должно работать?
 

Dovg

Продвинутый новичок
xintrea
а в syslog и php error_log тематических записей нет?

может у тебя php segfaultится, например?
 

MiksIr

miksir@home:~$
В запускающем скрипте пропиши
FCGI_WEB_SERVER_ADDRS="94.127.68.213"
 

fixxxer

К.О.
Партнер клуба
Xen это как раз полноценная виртуализация в отличие от всяких "jail-ов со свистелками и перделками" типа openvz, все будет работать.

>>Это неприципиально. Если бы соединение с PHP работало бы нормально, при неправильном имени PHP-файла была б ошибка вида "No input file specified".

А кстати вот хрен его знает, может он просто соединение закрывает при отсутствии хедеров. Ну, то есть как. При некорректном script_filename- то да, no input file, а вот при отсутствии всего остального, я даже так просто и не помню.

Ну вообще тут я бы пошел смотреть логи.

MiksIr
О, в cgi-fcgi есть проверка адреса клиента? :D

Но вообще конечно вместо этих плясок с бубном проще взять и поставить php-fpm, тем более что оно есть в dotdeb (это же debian, да?)
 

xintrea

Новичок
Автор оригинала: MiksIr
В запускающем скрипте пропиши
FCGI_WEB_SERVER_ADDRS="94.127.68.213"
Спасибо, помогло!

Работает даже с конфигурацией IP 127.0.0.1.

Вопрос - откуда вы знаете про переменную FCGI_WEB_SERVER_ADDRS? На что она влияет? В интернетах вовсю копипастят скрипт запуска PHP Fast CGI, и в нем нет установки этой переменной. Как же у других людей работает без нее?
 

MiksIr

miksir@home:~$
О, да, зачем в nginx fastcgi_params закоментарили?

-~{}~ 03.09.10 18:52:

> Вопрос - откуда вы знаете про переменную FCGI_WEB_SERVER_ADDRS?

Как-то натыкался в древности, запомнил, что она есть. Погуглил как точно писать.

>На что она влияет?

Список адресов (через запятую можно вроде), _откуда_ можно коннектиться к ПХП. По умолчанию 127.0.0.1. Но поскольку nginx сидит на внешнем интерфейсе, исходящие коннекты от него далются отимени этого интерфейса.

>В интернетах вовсю копипастят скрипт запуска PHP Fast CGI, и в нем нет установки этой переменной. Как же у других людей работает без нее?

А хрен их знает ;))) Может как-то зависит - прибиндился ли nginx к localhost или нет... или еще от чего-то
 

fixxxer

К.О.
Партнер клуба
Интересно, почему тогда не работало с конфигурацией на локалхосте...
 

MiksIr

miksir@home:~$
Глянул исходники. Если FCGI_WEB_SERVER_ADDRS нет вообще - то должно пускать всех. Но если FCGI_WEB_SERVER_ADDRS пустое - то не пускает никого. Дифолтных значений FCGI_WEB_SERVER_ADDRS нет.

Если глянуть запускающий скрипт, можно наблюдать
ALLOWED_ENV="$ALLOWED_ENV FCGI_WEB_SERVER_ADDRS"
и далее цикл по этим переменным который генерирует в итоге строку с FCGI_WEB_SERVER_ADDRS= ну и это скармливается env - т.е. php в итоге получает пустой FCGI_WEB_SERVER_ADDRS.

Т.е. или указывать FCGI_WEB_SERVER_ADDRS или удалять ALLOWED_ENV="$ALLOWED_ENV FCGI_WEB_SERVER_ADDRS"
 

xintrea

Новичок
Все стало ясно, спасибо.

Получается, что скрипт в стартовой мессаге нерабочий - он запустит PHP FCGI без возможности к нему приконнектиться.
 
Сверху