Слава нації
#StandWithUkraine

Роман Теличко

Блог з програмування, оптимізації та адміністрування систем

Настройка nginx + php5-fpm под Linux/Debian

// | 26282 переглядів

Сегодня я расскажу как настроить связку nginx + php5-fpm под Debian.

Начнём с инсталляции nginx.
И тут же мы сталкиваемся с тем, какой именно пакет ставить, т.к. их существует аж три:

  • nginx-light
  • nginx-full
  • nginx-extras

Отличаются они только поставкой дополнительных модулей.
Вызовем описание пакета nginx-light

aptitude show nginx-light

aptitude покажет какие именно дополнительные модули входят в “лёгкую” версию nginx

STANDARD HTTP MODULES : Core, Access, Auth Basic, Auto Index, Charset, Empty GIF, FastCGI, 
                        Gzip, Headers, Index, Log, Map, Proxy, Rewrite, Upstream. 
OPTIONAL HTTP MODULES : Gzip Precompression, IPv6, SSL, Stub Status.  
THIRD PARTY MODULES   : Echo.

А теперь для сравнения выведем список модулей “расширенной” версии nginx

aptitude show nginx-extras
STANDARD HTTP MODULES : Core, Access, Auth Basic, Auto Index, Browser, Charset, Empty GIF, 
                        FastCGI, Geo, Gzip, Headers, Index, Limit Requests, Limit Zone, Log, 
                        Map, Memcached, Proxy, Referer, Rewrite, SCGI, Split Clients, SSI, 
                        Upstream, User ID, UWSGI.  
OPTIONAL HTTP MODULES : Addition, Debug, Embedded Perl, FLV, GeoIP, Gzip Precompression, 
                        Image Filter, IPv6, MP4, Random Index, Real IP, Secure Link, SSL, 
                        Stub Status, Substitution, WebDAV, XSLT. 
MAIL MODULES          : Mail Core, IMAP, POP3, SMTP, SSL. 
THIRD PARTY MODULES   : Auth PAM, Chunkin, DAV Ext, Echo, Embedded Lua, HttpHeadersMore, 
                        http push, Nginx Development Kit, Upload module, Upload Progress, 
                        Upstream Fair Queue.

Как видите, список модулей и дополнений впечатляет.
С их подробной конфигурацией вы можете ознакомиться здесь и здесь.
Я рекомендую ставить nginx-light, т.к. чем меньше будет доставлено пакетов, тем меньше памяти будет “кушать” ядро nginx. Но также необходимо учитывать нужные модули для работы.

Устанавливаем nginx

aptitude install nginx-full

После успешной инсталляции открываем главный конфигурационный файл /etc/nginx/nginx.conf и приводим его к следующему виду:

user                www-data    www-data;

worker_processes    8;    # указать текущее количество ядер процессора
worker_priority     -20;

pid /var/run/nginx.pid;

error_log  /var/log/nginx/error.log  warn;

events {
    worker_connections              1024;
    accept_mutex                    on;
    multi_accept                    on;
}

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

    reset_timedout_connection       on;
    server_tokens                   off;

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

    sendfile                        on;
    tcp_nopush                      on;
    tcp_nodelay                     on;

    keepalive_timeout  	            65;

    client_max_body_size            512m;

    server_names_hash_max_size      1024;
    server_names_hash_bucket_size   128;

    port_in_redirect                off;

    gzip                            on;
    gzip_vary                       on;
    gzip_min_length                 1024;
    gzip_buffers                    16 8k;
    gzip_comp_level                 5;
    gzip_http_version               1.0;
    gzip_proxied                    any;
    gzip_disable                    "msie6";
    gzip_types                      text/plain text/css application/x-javascript text/xml 
                                    application/xml application/xml+rss text/javascript 
                                    text/json;

    fastcgi_temp_path               /var/cache/nginx/temp/fastcgi;
    proxy_temp_path                 /var/cache/nginx/temp/proxy;

    charset                         utf-8;
    index                           index.php index.html index.htm;

    access_log                      off;
    error_log                       /dev/null;

    set_real_ip_from    	    1.2.3.4/32;  # указать "честный" IP сервера
    real_ip_header      	    X-Real-IP;

    include                         /etc/nginx/sites-enabled/*;
}

Создаём папки для хранения кэша nginx и выставляем на них правильные права

mkdir -p /var/cache/nginx/temp/fastcgi
mkdir -p /var/cache/nginx/temp/proxy
chown -R www-data:www-data /var/cache/nginx

Перейдём в папку /etc/nginx/sites-enabled. Сейчас там по умолчанию лежит только один файл, что является символической ссылкой на файл с таким же именем в папке /etc/nginx/sites-available. Почему символическая ссылка, а не файл? С символическими ссылками очень удобно работать в случае когда вам нужно убрать какой-то виртуальный хост из настроек ядра, но при этом не потерять его на будущее. Вы просто удаляете ссылку на файл из папки /etc/nginx/sites-enabled не удаляя реальный файл. Это очень удобно.

К конфигурации виртуального сервера nginx мы ещё вернёмся после установки php5-fpm.

Устанавливаем php5-fpm:

aptitude install php5-fpm

В главном файле конфигурации php5-fpm /etc/php5/fpm/php-fpm.conf нас всё устраивает по умолчанию.

[global]
pid = /var/run/php5-fpm.pid
error_log = /var/log/php5-fpm/error.log
log_level = warning
daemonize = yes
include=/etc/php5/fpm/pool.d/*.conf

Перейдём к конфигурации виртуальных пулов что лежат в папке /etc/php5/fpm/pool.d/.

Открываем созданный по умолчанию /etc/php5/fpm/pool.d/www.conf
Без комментариев результирующий конфиг должен выглядеть так:

[www]
listen = /var/run/php5-fpm.$pool.sock
listen.allowed_clients = 127.0.0.1
listen.owner = www-data
listen.group = www-data
user = www-data
group = www-data
pm = dynamic
pm.max_children = 24
pm.start_servers = 12
pm.min_spare_servers = 2
pm.max_spare_servers = 24
pm.max_requests = 100
request_terminate_timeout = 90s
request_slowlog_timeout = 5s
slowlog = /var/log/php5-fpm/slow.$pool.log
chdir = /
catch_workers_output = yes
php_flag[display_errors] = off
php_admin_value[error_log] = /var/log/php5-fpm/error.$pool.log
php_admin_flag[log_errors] = on

Обратите внимание что я использовал переменную $pool что будет заменена на текущее имя пула, что задано в квадратных скобках в самом начале. В нашем случаи это будет [www]

Создадим папку для логов php5-fpm

mkdir /var/log/php5-fpm && chown www-data:www-data /var/log/php5-fpm

Немного поправим настройки PHP.
Откроем файл /etc/php5/fpm/php.ini и изменим следующие директивы:

expose_php = Off
cgi.fix_pathinfo = 0
max_execution_time = 90

Запускаем php5-fpm

service php5-fpm restart

Если всё ОК, возвращаемся к конфигурации nginx.
Создадим файл виртуального хоста в /etc/nginx/sites-available/example.com со следующим содержанием:

server {
    listen                  80;
    server_name             example.com *.example.com;

    set 	            $main_host		'example.com';

    if ($host != $main_host) {
        rewrite             ^(.*)$              https://$main_host$1     permanent;
        break;
    }

    access_log              /var/log/nginx/example.com.access.log       main;
    error_log       	    /var/log/nginx/example.com.error.log;
    
    root                    /var/www/$main_host/www;
    index                   index.php;

    # favicon.ico conf
    location = /favicon.ico {
        try_files 	    /favicon.ico    @favicon_empty;
        expires	            7d;
        access_log          off;
        log_not_found       off;
    }

    location @favicon_empty {
        empty_gif;
        expires	            7d;
        access_log          off;
        log_not_found       off;
    }

    location ~* ^.+\.(ico|htm|html|txt|jpg|png|gif|css|js)$ {
        access_log          off;
        autoindex           off;
        expires             30d;
        add_header          Cache-Control       'public';
    }

    location / {
        try_files           $uri    $uri/    /index.php?$args;
    }	

    location ~ \.php$ {
        include             /etc/nginx/conf.d/fastcgi_params.conf;

        fastcgi_param       SCRIPT_FILENAME  	/var/www/$main_host/www$fastcgi_script_name;
        fastcgi_param       DOCUMENT_ROOT       /var/www/$main_host/www;

        fastcgi_param       PHP_ADMIN_VALUE     upload_tmp_dir=/var/www/$main_host/tmp/upload;
        fastcgi_param       PHP_ADMIN_VALUE     session.save_path=/var/www/$main_host/tmp/sessions;
    }

    location ~ /\. {
	deny                all;
	access_log          off;
	log_not_found       off;
    }
}

В конфигурации мы использовали дополнительный конфиг, что не был описаны ранее.
Создадим его.
/etc/nginx/conf.d/fastcgi_params.conf

fastcgi_pass    unix:/var/run/php5-fpm.www.sock;
fastcgi_index   index.php;

fastcgi_split_path_info 		^(.+\.php)(/.+)$;

fastcgi_param   PATH_INFO        	$fastcgi_path_info;

fastcgi_param   QUERY_STRING            $query_string;
fastcgi_param   REQUEST_METHOD          $request_method;
fastcgi_param   CONTENT_TYPE            $content_type;
fastcgi_param   CONTENT_LENGTH          $content_length;

fastcgi_param	SCRIPT_NAME		$fastcgi_script_name;
fastcgi_param	REQUEST_URI		$request_uri;
fastcgi_param	DOCUMENT_URI		$document_uri;
fastcgi_param	SERVER_PROTOCOL		$server_protocol;

fastcgi_param  	SCRIPT_URI         	$scheme://$host$request_uri;

fastcgi_param	GATEWAY_INTERFACE	CGI/1.1;
fastcgi_param	SERVER_SOFTWARE		nginx;

fastcgi_param	REMOTE_ADDR		$remote_addr;
fastcgi_param	REMOTE_PORT		$remote_port;
fastcgi_param	SERVER_ADDR		$server_addr;
fastcgi_param	SERVER_PORT		$server_port;
fastcgi_param	SERVER_NAME		$server_name;

fastcgi_param   Host                    $host;
fastcgi_param   HTTP_X_REAL_IP          $remote_addr;
fastcgi_param   HTTP_X_FORWARDED_FOR	$remote_addr;

fastcgi_param   Range                   "";
fastcgi_param   Request-Range           "";

fastcgi_buffer_size                     128k;
fastcgi_buffers                         4       256k;
fastcgi_busy_buffers_size               256k;
fastcgi_temp_file_write_size            256k;

fastcgi_connect_timeout                 600;
fastcgi_send_timeout                    600;
fastcgi_read_timeout                    600;

Обратите внимание что в параметре fastcgi_pass я указал путь к сокету php5-fpm пула www как unix:/var/run/php5-fpm.www.sock.

Теперь создадим символическую ссылку на созданный нами только что виртуальный хост, чтобы nginx его “увидел”

ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/example.com

Проверяем (тестируем) конфигурации nginx

nginx -t

Результатом должно быть следующее:

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

Теперь мы можем запустить nginx

service nginx restart

Если всё ОК — продолжаем дальше.

Создадим иерархию директорий нашего тестового проекта.

mkdir -p /var/www/example.com/www
mkdir -p /var/www/example.com/tmp/upload
mkdir -p /var/www/example.com/tmp/sessions
chown -R www-data:www-data /var/www/example.com

И создадим index.php файл с проверкой работы php5-fpm

echo " /var/www/example.com/www/index.php

Отроем в браузере. И если вы увидели вывод функции phpinfo(), то вы всё сделали правильно.

Это всё.
Удачи!

P.S. Не забудьте про logrotate для того, чтобы ваши логи не заняли в один прекрасный момент всё дисковое пространство, прекратив тем самым работу всех сайтов на этом веб-сервере.