ПредысторияНа одном сервере с типичной конфигурацией (Apache + php + mysql) живет некоторый проект, написанный довольно давно, не знаю кем. Апач потребляет довольно много RAM, поэтому было решено попробовать перенести проект на сервер с Nginx + php-fpm, чтобы не арендовать все более и более дорогой VPS со временем. Судя по качеству кода, писал сайт такой же непрофессиональный программист, как я — непрофессиональный админ. Но вариант "выкинуть все и переписать с нуля" не рассматривается.
Короче, покурил вот
эту статью и решил, почему бы не провести субботу за настройкой сервера. В принципе, сам веб-сервер nginx и php-fpm настроить удалось, тестовые php-скрипты работают "на ура", статика вся отдается нормально.
Закачал сайт на тестовый поддомен и сразу же появилась
проблема: страница открывается, я вижу шаблон, все стили и статика загружается, но на странице нет контента, который хранится в БД. Я подумал, что какие-то проблемы в соединении с mysql, но в логах (/var/log/nginx/error.log
) обнаружил только это:
Текст ошибки2014/05/11 11:33:59 [error] 23791#0: *8 FastCGI sent in stderr: "PHP message: PHP Notice: Undefined variable: object_id in /var/www/example_ru/data/www/test.example.ru/shablon/web/conteyner/main.php on line 89" while reading response header from upstream, client: xx.xx.xx.xx, server: test.example.ru, request: "GET / HTTP/1.1", upstream: "fastcgi://unix:/var/run/php5-fpm.sock:", host: "test.example.ru"
Вторая проблема, что кроме главной страницы ничего не открывалось, везде возвращало 404 ошибку. Я не перенес rewrite-правила из htaccess и подумал, что по крайней мере эта проблема я знаю откуда растет. Заодно выяснил, что переменная $object_id должна определяться в index.php в мутной конструкции, состоящей из if-ов и isset-ов. Поэтому я полагаю, что переменная не определена по той же причине, что и не открываются второстепенные страницы.
Код htaccess со старого сервераphp_value register_globals Off
ErrorDocument 404 404.html
AddDefaultCharset utf-8
AddCharset utf-8 *
<IfModule mod_charset.c>
CharsetSourceEnc utf-8
CharsetDefault utf-8
</IfModule>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)\.html$ index.php?cat_name=$1 [NC,L,QSA]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?cat_name=$1 [NC,L,QSA]
Код nginx.conf нового сервераuser www-data;
worker_processes auto;
timer_resolution 100ms;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
server_tokens off;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
gzip on;
gzip_http_version 1.1;
gzip_disable msie6;
gzip_types text/plain application/xml application/x-javascript text/css;
include /etc/nginx/conf.d/stub.conf;
include /usr/local/ispmgr/etc/nginx.domain;
client_max_body_size 16M;
log_format isp '$bytes_sent $request_length';
include common/upstream;
include /etc/nginx/sites-enabled/*;
}
Код common/upstreamupstream php-fpm
{
#php5-fpm сервер
server unix:/var/run/php5-fpm.sock;
}
Код /etc/nginx/sites-enabled/test.example.ruserver
{
listen 80;
server_name www.test.example.ru;
rewrite ^ http://test.example.ru$request_uri? permanent; #301 redirect
}
server
{
# Порты
listen 80;
disable_symlinks if_not_owner from=$root_path;
set $root_path /var/www/example_ru/data/www/test.example.ru;
root $root_path;
index index.php index.html index.htm;
server_name test.example.ru;
client_max_body_size 30m; # максимальный объем файла для загрузки 30 mb
location "/"
{
try_files $uri $uri/ =404; # проверить есть ли файл из запроса на диске, иначе 404
}
include common/locations/deny;
# Направление PHP-скрипта для обработки FastCGI или PHP-FPM серверу
location ~ \.php$
{
# Решение проблемы с уязвимостью (см. http://forum.nginx.org/read.php?2,88845,page=3)
# Не будет работать (ошибка 404) если файлы хранятся на другом сервере
try_files $uri $uri/ $uri/index.php?q=$uri&$args $uri/index.php =404;
include common/php-fpm;
}
}
Если добавить следующий код (кстати, так писать
не рекомендуется, но это пока только демонстрация) в "location /", то при попытке зайти на любую страницу, кроме главной, скачивается index.php (с именем XUDadWDM).
spoilerif (!-e $request_filename){
rewrite ^/(.*)\.html$ /index.php?cat_name=$1 break;
}
if (!-e $request_filename){
rewrite ^(.*)$ /index.php?cat_name=$1 break;
}
Этот кусок я взял из
winginx.com/ru/htaccess
Если же этот код не добавлять, то открывается только главная страница, а другие возвращают 404 ошибку.
И наконец, код common/php-fpm# Настройки порта или сокета PHP-FPM производятся в файле "/etc/php5/fpm/pool.d/www.conf"
fastcgi_pass php-fpm;
# Порядок важен - строчка "include fastcgi_params" должна быть первой
include fastcgi_params;
fastcgi_split_path_info ^(.+?\.php)(/.*)?$;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_TRANSLATED $document_root$fastcgi_script_name;
# См. http://trac.nginx.org/nginx/ticket/321
set $path_info $fastcgi_path_info;
fastcgi_param PATH_INFO $path_info;
# Указание дополнительных переменных окружения PHP
fastcgi_param SERVER_ADMIN xxx;
fastcgi_param SERVER_SIGNATURE nginx/$nginx_version;
fastcgi_index index.php;
Собственно, помогите перенести Rewrite-правила из Apache в Nginx, пожалуйста. И если ошибка возникает не из-за этого, то из-за чего тогда?
P.S. На другой поддомен ставил phpMyAdmin, все заработало сразу без единой проблемы, так что проблемы с работой конкретно php или mysql я почти исключаю.