Php-fpm + nginx на Debian 7: устанавливаем и настраиваем
В Debian Wheezy php-fpm присутствует в основном репозитории. А это значит, что больше не приходится пользоваться сторонними репозиториями, типа DotDeb, для настройки и использования этого замечательного модуля.
Статья посвящается, большей частью, настройке php-fpm на debian, не рассматривая установку дополнительных сервисов, типа mysql, nginx и чего-то там ещё. Для nginx будет приведён лишь пример используемой мной конфигурации.
Установка
Как и в любом другом случае, первым делом нужно установить требуемые пакеты. Касательно дополнительных модулей, выбор, в основном, зависит от технических требований к сайту. В этом примере будет установлен как сам модуль php-fpm, так и модули для работы с mysql, изображениями (библиотека gd), curl, который требуется для многих cms.
apt-get install php5-fpm php5-mysqlnd php5-curl php5-gd
Конфигурационные файлы располагаются в каталоге /etc/php5/fpm/.
Настройка
Php-fpm изначально поставляется с одним пулом www в качестве примера работы. Можно отредактировать конфигурационный файл этого пула для себя, либо создать новый пул, основываясь на конфигурации существующего.
Давайте откроем конфигурационный файл /etc/php5/fpm/pool.d/www.conf, рассмотрим некоторые переменные и подберём для них значения.
Первая переменная — это имя пула. Имя заключается в квадратные скобки.
[www]
Если вам нужно создать новый пул, то создайте в папке /etc/php5/fpm/pool.d/ файл, poolname.conf, и укажите в нём имя пула в квадратных скобках: [poolname]. Имя файла может не совпадать с именем пула. Сделано это только для удобства. 🙂
Следует иметь в виду, что имя пула не может совпадать с именем пользователя — владельца сайтов или любого другого пользователя, существующего в системе.
Далее следуют переменные:
user = www-data
group = www-data
В качестве значения этих переменных указывается пользователь и группа, от имени которых будет работать пул. Здесь установите имя пользователя и группы, кто является владельцем файлов вашего сайта. То есть, пользователь, в чьей домашней директории хранится ваш сайт.
Это решит проблему с правами доступа к файлам сайта. Вам не придётся беспокоиться, выставлять каждый раз права на запись в какую-нибудь папку сайта для веб-сервера, и так далее.
listen = /var/run/php-$pool.sock
Оставляем unix-сокет. Переменная $pool будет заменена на имя пула.
listen.owner = www-data
listen.group = www-data
Тоже не требует изменений. Указывается пользователь и группа, которые становятся владельцами unix-сокета fpm при запуске. Необходимо, чтобы веб-сервер имел права на чтение сокета. Если изменить значения этих переменных на что-то другое, то пользователя www-data нужно будет добавить в группу владельца сокета и выставить права для чтения сокета группой.
В свою очередь, права на сокет устанавливаются переменной listen.mode. Не рекомендуется выставлять права 0666 из соображений безопасности.
pm = static. При старте fpm создаётся определённое количество процессов пула, которые обслуживают все поступающие запросы. Существуют также и другие варианты контроля дочерних процессов: dynamic и onedemand.
pm.max_children — количество создаваемых процессов. Необходимо вычислить сколько памяти занимает один процесс, потом разделить тот объем памяти который вы хотите выделить для php5-fpm, на объем одного процессора, получите количество pm.max_children (наример 1000мб/50мб=20)
Почему именно такой выбор? 🙂 Это самый экономный вариант. Каждый процесс пула будет занимать объём оперативной памяти, выделенный переменной memory_limit плюс несколько мегабайт на подключённые модули и т.п. При статичном варианте все запросы будут обрабатываться только созданными процессами, а новые порождаться (и занимать драгоценную память) не будут. В итоге получим фиксированное потребление памяти.
Вариант onedemand, по субъективным соображениям, не подходит потому, что каждый раз создание дочерних процессов при поступлении запросов будет занимать определённое время. Что скажется на работе сайтов.
pm.min_spare_servers = этот параметр начать с количество ядер процессора умножить на 2 (пример 1 ядро * 2 = 2)
pm.max_spare_servers = этот параметр количество ядер процессора * 1 (пример 1 *4 =4)
pm.start_servers = этот параметр вычисляется по формуле (pm.min_spare_servers+pm.max_spare_servers)/2 (пример (2+4)/2=4)
Итого на выходе получаем примерно конфигурацию для 1 ядерного процессора 1гб памяти (выделенные только под PHP5-FPM, возможно у вас 2Гб общей)
pm.max_children = 20
pm.start_servers = 4
pm.min_spare_servers = 2
pm.max_spare_servers = 4
pm.max_requests — количество обработанных запросов, после которого процессы php-fpm будут перезагружены. Позволяет избежать утечек памяти при использовании сторонних библиотек. 1000—3000 запросов в зависимости от загруженности и объёма памяти на сервере.
При разработке сайтов очень может пригодиться лог медленных запросов для оптимизации скриптов. Отредактируйте переменную slowlog, указав полный путь к логу.
slowlog = /var/log/php-$pool-slow.log
Определять, какие запросы считать медленными, поможет переменная request_slowlog_timeout. Здесь нужно указать время, по истечении которого информация о медленном запросе будет записана в лог-файл. Например:
request_slowlog_timeout = 10s
Последним шагом в настройке php-fpm будет установка некоторых дополнительных параметров php.ini, которые будут прописаны непосредственно в конфигурационном файле пула.
Каталог для размещения временных файлов:
php_admin_value[upload_tmp_dir] = "/var/tmp_dir"
Каталог для хранения файлов сессий:
php_admin_value[session.save_path] = "/var/save_path"
По соображениям безопасности, доступ к этим каталогам должен быть только у пользователя, с правами которого запускается пул php-fpm. Также не следует использовать один каталог и для хранения файлов сессий, и для временных файлов.
Ограничение памяти для выполнения скриптов следует подбирать, исходя из требований сайта. Для начала:
php_admin_value[memory_limit] = 50M
Обязательный параметр, который устраняет [urlspan]уязвимость[/urlspan]:
php_admin_value[cgi.fix_pathinfo] = 0
Переменные sendmail_path и open_basedir не указываются специально. Они будут переданы в качестве параметров fast-cgi в конфигурационном файле nginx. Таким образом, для каждого конкретного сайта можно определить свою настройку. 🙂
После того, как все необходимые параметры прописаны, следует перезагрузить конфигурацию php-fpm командой:
service php5-fpm reload
Обработка php скриптов посредством nginx
Остаётся настроить nginx для работы с php-fpm. Конфиг не представляет собой какую-то особо сложную конструкцию.
location / { root /var/www ... location ~ .php$ { try_files $uri =404; fastcgi_pass unix:/run/php-www.sock; fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_ignore_client_abort off; fastcgi_param PHP_VALUE "sendmail_path=/usr/sbin/sendmail -t -i -fmail@example.com"; fastcgi_param PHP_ADMIN_VALUE "open_basedir=/var/www/example.com/:/var/save_path/:/var/tmp_dir/"; } ... }
Давайте рассмотрим детально некоторые параметры.
try_files $uri =404; отобразит ошибку 404 в браузере пользователя, вместо сообщения no input file specified, в случае, когда данная ошибка имеет место.
fastcgi_pass — путь к сокету php-fpm. Помните, какое имя мы ему дали в конфиге? /run/php-$pool.sock. Только вот nginx не понимает переменных fpm, поэтому указываем путь как есть: /run/php-www.sock. 🙂
fastcgi_pass unix:/run/php-www.sock;
Следующая переменная устанавливает путь к sendmail и параметр, указывающий адрес электропочты администратора сайта. Замените mail@example.com на что-то своё.
fastcgi_param PHP_VALUE "sendmail_path=/usr/sbin/sendmail -t -i -fmail@example.com";
Перечисляем каталоги для open_basedir: каталог с сайтом, каталог для сохранения временных файлов, каталог для файлов сессий.
fastcgi_param PHP_ADMIN_VALUE "open_basedir=/var/www/example.com/:/var/save_path/:/var/tmp_dir/";
Если требуется передать несколько параметров, до делать это следует так:
fastcgi_param PHP_ADMIN_VALUE "sendmail_path=/usr/sbin/sendmail -t -i -fmail@example.comnopen_basedir=/var/www/example.com/:/var/save_path/:/var/tmp_dir/";
Как можно заметить, параметры разделяются при помощи переноса строки: n.
Сохраняем все проделанные изменения и перезапускаем nginx.
service nginx reload Посмотреть память отведенную PHP-FPM child processes ps -ylC php5-fpm --sort:rss | awk '!/RSS/ { s+=$8 } END { printf "%s\n", "Total memory used by PHP-FPM child processes: "; printf "%dM\n", s/1024 }'
Так же ,можем настроить PHP-FPM, для автоматической перезагрузки, если есть проблемы. В этом примере перезапуск будет произведен, если десять дочерних процессов умирают в течение 1 минуты, и мы ожидаем 10 секунд перед перезапуском.
Это глобальная конфигурация и принадлежит /etc/php5/fpm/php-fpm.conf
:
emergency_restart_threshold 10 emergency_restart_interval 1м process_control_timeout 10s