В предыдущей статье Настройка веб-сервера Nginx на Debian как front-end к Apache мы настроили Nginx для обработки статических запросов и Apache для обработки динамических запросов. Теперь попробуем рассмотреть альтернативную конфигурацию сервера для Drupal сайта заменив Apache на Php-fpm. Принцип работы нашего веб-сервера будет следующим:
- Nginx принимает запросы от клиентов
- Статику nginx отдает самостоятельно
- Динамические запросы Nginx передает на php-fpm, который запущен локально на порту 9000.
Первоначальная установка всех компонентов
Обновляем локальный кэш пакетов:
apt-get update
Устанавливаем все компоненты:
apt-get install nginx php7.0-fpm mysql-server php7.0-gd php7.0-mysql
Настройка nginx
Конфигурация nginx выглядит следующим образом:
server {
server_name www.drupaladmin-example.com;
rewrite (.*) http://drupaladmin-example.com$1;
}
server {
listen 80;
server_name drupaladmin-example.com;
root /home/webmaster/domains/drupaladmin-example.com/html;
index index.php;
access_log /home/webmaster/domains/drupaladmin-example.com/logs/nginx_access.log;
error_log /home/webmaster/domains/drupaladmin-example.com/logs/nginx_error.log;
if ($bad_bot) {
return 444;
}
if ($bad_referer) {
return 444;
}
if ($not_allowed_method) {
return 405;
}
fastcgi_keep_conn on;
add_header X-XSS-Protection '1; mode=block';
add_header X-Frame-Options deny;
add_header X-Content-Options nosniff;
location ~* ^/.well-known/ {
allow all;
}
location / {
location ~* /system/files/ {
include /etc/nginx/fastcgi_drupal.conf;
fastcgi_pass 127.0.0.1:9000;
log_not_found off;
}
location ~* /sites/default/files/private/ {
internal;
}
location ~* /imagecache/ {
expires 30d;
try_files $uri @drupal;
}
location ~* /sites/default/files/styles/ {
expires 30d;
try_files $uri @drupal;
}
location ~* /sites/.+/files/.+\.txt {
expires 30d;
tcp_nodelay off;
open_file_cache max=3000 inactive=120s;
open_file_cache_valid 45s;
open_file_cache_min_uses 2;
open_file_cache_errors off;
}
location ~* /sites/.+/files/advagg_css/ {
expires max;
add_header X-XSS-Protection '1; mode=block';
add_header X-Frame-Options deny;
add_header X-Content-Options nosniff;
add_header ETag '';
add_header Last-Modified 'Wed, 20 Jan 1988 04:20:42 GMT';
add_header Accept-Ranges '';
location ~* /sites/.*/files/advagg_css/css[_[:alnum:]]+\.css$ {
try_files $uri @drupal;
}
}
location ~* /sites/.+/files/advagg_js/ {
expires max;
add_header X-XSS-Protection '1; mode=block';
add_header X-Frame-Options deny;
add_header X-Content-Options nosniff;
add_header ETag '';
add_header Last-Modified 'Wed, 20 Jan 1988 04:20:42 GMT';
add_header Accept-Ranges '';
location ~* /sites/.*/files/advagg_js/js[_[:alnum:]]+\.js$ {
try_files $uri @drupal;
}
}
location ~* /admin/reports/hacked/.+/diff/ {
try_files $uri @drupal;
}
location ~* ^.+\.xml {
try_files $uri @drupal;
}
location ~* ^.+\.(?:css|ico|cur|js|jpe?g|gif|htc|ico|png|html|xml|otf|ttf|eot|woff2?|svg|mp3|ogg|mpe?g|avi|zip|gz|bz2?|rar|swf|woff|ogg|mp4|wav|aac|skin)$ {
expires 30d;
tcp_nodelay off;
open_file_cache max=3000 inactive=120s;
open_file_cache_valid 45s;
open_file_cache_min_uses 2;
open_file_cache_errors off;
location ~* ^.+\.svgz$ {
gzip off;
add_header X-XSS-Protection '1; mode=block';
add_header X-Frame-Options deny;
add_header X-Content-Options nosniff;
add_header Content-Encoding gzip;
}
}
location ~* ^.+\.(?:pdf|pptx?)$ {
expires 30d;
tcp_nodelay off;
}
location ~* ^(?:.+\.(?:htaccess|make|txt|yml|twig|engine|inc|info|install|module|profile|po|pot|sh|.*sql|test|theme|tpl(?:\.php)?|xtmpl)|code-style\.pl|/Entries.*|/Repository|/Root|/Tag|/Template|composer\.(json|lock))$|^#.*#$|\.php(~|\.sw[op]|\.bak|\.orig|\.save)$ {
deny all;
}
try_files $uri @drupal;
}
location @drupal {
include /etc/nginx/fastcgi_drupal.conf;
fastcgi_pass 127.0.0.1:9000;
}
location = /authorize.php {
fastcgi_pass 127.0.0.1:9000;
}
location = /cron.php {
fastcgi_pass 127.0.0.1:9000;
}
location = /index.php {
fastcgi_pass 127.0.0.1:9000;
}
location = /install.php {
fastcgi_pass 127.0.0.1:9000;
}
location = /update.php {
fastcgi_pass 127.0.0.1:9000;
}
location = /xmlrpc.php {
fastcgi_pass 127.0.0.1:9000;
}
location ^~ /.bzr {
return 404;
}
location ^~ /.git {
return 404;
}
location ^~ /.hg {
return 404;
}
location ^~ /.svn {
return 404;
}
location ^~ /.cvs {
return 404;
}
location ^~ /patches {
return 404;
}
location ^~ /config {
return 404;
}
location ^~ /backup {
return 404;
}
location = /robots.txt {
try_files $uri @drupal;
}
location = /favicon.ico {
expires 30d;
try_files /favicon.ico @empty;
}
location @empty {
expires 30d;
empty_gif;
}
location ~* ^.+\.php$ {
return 404;
}
}
Создаем файл конфигурации Nginx /etc/nginx/conf.d/nginx_additional.conf с дополнительными настройками для определения переменных:
map $http_user_agent $bad_bot {
default 0;
~*^Lynx 0; # Let Lynx go through
libwww-perl 1;
~(?i)(httrack|htmlparser|libwww) 1;
}
map $http_referer $bad_referer {
default 0;
~(?i)(adult|babes|click|diamond|forsale|girl|jewelry|love|nudit|organic|poker|porn|poweroversoftware|sex|teen|webcam|zippo|casino|replica) 1;
}
map $request_method $not_allowed_method {
default 1;
GET 0;
HEAD 0;
POST 0;
}Теперь создадим файл /etc/nginx/fastcgi_drupal.conf с параметрами fastcgi для Drupal:
## 1. Parameters. fastcgi_param QUERY_STRING q=$uri&$args; fastcgi_param REQUEST_METHOD $request_method; fastcgi_param CONTENT_TYPE $content_type; fastcgi_param CONTENT_LENGTH $content_length; fastcgi_param SCRIPT_NAME /index.php; fastcgi_param REQUEST_URI $request_uri; fastcgi_param DOCUMENT_URI $document_uri; fastcgi_param DOCUMENT_ROOT $document_root; fastcgi_param SERVER_PROTOCOL $server_protocol; fastcgi_param GATEWAY_INTERFACE CGI/1.1; fastcgi_param SERVER_SOFTWARE nginx/$nginx_version; 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 REDIRECT_STATUS 200; fastcgi_param SCRIPT_FILENAME $document_root/index.php; fastcgi_param HTTPS $fastcgi_https if_not_empty; ## 2. Nginx FCGI specific directives. fastcgi_buffers 256 4k; fastcgi_intercept_errors on; fastcgi_read_timeout 14400; fastcgi_index index.php; fastcgi_hide_header 'X-Drupal-Cache'; fastcgi_hide_header 'X-Generator';
Файл параметров /etc/nginx/fastcgi_params оставим без изменений.
Перезапускаем Nginx
/etc/init.d/nginx restart
Настройка php-fpm
В файле /etc/php5/fpm/php-fpm.conf устанавливаем следующие параметры:
syslog.facility = daemon syslog.ident = php-fpm log_level = error emergency_restart_interval = 12h events.mechanism = epoll
Теперь переходим к настройке пула /etc/php5/fpm/pool.d/www.conf
user = www-data group = www-data pm = dynamic pm.max_requests = 1500 pm.max_children = 5 pm.start_servers = 2 pm.min_spare_servers = 1 pm.max_spare_servers = 3 pm.process_idle_timeout = 10s security.limit_extensions = .php catch_workers_output = yes listen = 127.0.0.1:9000 php_admin_value[error_log] = /home/webmaster/domains/drupaladmin-example.com/logs/fpm-php.www.error.log php_admin_flag[log_errors] = on php_admin_value[memory_limit] = 256M php_admin_value[upload_tmp_dir] = "/home/webmaster/domains/tmp" php_admin_value[session.save_path] = "/home/webmaster/domains/tmp"
Перезапускаем php-fpm
/etc/init.d/php7.0-fpm restart
В файле конфигурации /etc/php5/fpm/php-fpm.conf достаточно подробно описаны все параметры. Также для более подробного описания можно обратиться к официальной документации.
На этом настройка завершена и Drupal сайт будет работать без использования веб-сервера Аpache.
Добрый день!
Подскажите пожалуйста, для drupal 8 как включить мультисайтинг на nginx с php-fpm5?
Читал, что связка Nginx + Php-fpm + Apc выигрышная только на тарифах с ограниченной оперативной памятью , если памяти хватает то Nginx + Apache + mod_php + Apc будет тоже хорошим решением т.е. не уступающим.
В чем плюс в остальном Php-fpm перед апачем ?
Я вижу разницу в том, что Nginx + php-fpm + APC будет быстрее, чем Nginx + Apache + mod_php + APC, потому что не используется дополнительное звено Apache, который на каждом запросе будет тратить время на VirtualHost, на .htaccess, до того как обработать динамический запрос.
В целом для повышения производительности можно применять затюненный Apache в режиме Worker MPM. Кстати неплохо было бы сравнить на одном и том же железе Apache Worker MPM + mod_php vs Nginx + php-fpm. На abmysite.com пока что нет такого теста. Обязательно добавим.
Вроде как drupal.ru работает на apache http://www.drupal.ru/about/hostings ...
Да, вижу используется Nginx + Apache. Подозреваю, что это особенность хостинга, где они сейчас размещаются. Я так понимаю этот хостинг использует именно связку Nginx + Apache в продакшн.
Думаю, что нужно проводить тесты разных конфигураций на одном и том же железе, чтобы найти оптимальную конфигурацию. Видимо drupal.ru нашел эту конфигурацию на этом хостинге.
Спасибо за статью, помогло ускорить работу.
Привет!
А друпал ни как не увидит что включен APC? Отчет статусов в Друпале выводит такую запись
С апачем он вроде писал что включен APC.
Попробуйте включить в apc.ini строчку apc.rfc1867 = On и перезапустите php-fpm
Включил в APC поддержку rfc1867
http://i59.fastpic.ru/big/2015/0222/9d/2563281966f6143071e678c867c3479d.png
но Drupal все равно ругается:
http://i60.fastpic.ru/big/2015/0222/8c/2dfd0564b02f0437cf58bee8962d428c.png
Добрый день! У меня nginx выдает 502 ошибку :( В логах
нужно через ps aux проверить что php-fpm запущен, и netstat -an глянуть что порт 9000 занят. Также посмотреть конфиг php-fpm на каком порту он запущен.
Судя по всему, он не запущен. При запуске ничего не сообщает, но статус показывает failed.
В логах php-fpm ничего нет :(
[09-Aug-2013 12:00:54] NOTICE: fpm is running, pid 8601
[09-Aug-2013 12:00:54] NOTICE: ready to handle connections
[09-Aug-2013 12:00:57] NOTICE: configuration file /etc/php5/fpm/php-fpm.conf test is successful
[09-Aug-2013 12:00:57] NOTICE: Finishing ...
[09-Aug-2013 12:00:57] NOTICE: exiting, bye-bye!
[09-Aug-2013 12:00:57] NOTICE: fpm is running, pid 9301
[09-Aug-2013 12:00:57] NOTICE: ready to handle connections
[09-Aug-2013 12:21:48] NOTICE: Finishing ...
[09-Aug-2013 12:21:48] NOTICE: exiting, bye-bye!
скиньте конфиг php-fpm: php-fpm.conf и www.conf
php-fpm.conf:
[global]
pid = /var/run/php5-fpm.pid
error_log = /var/log/php5-fpm.log
syslog.facility = daemon
syslog.ident = php-fpm
log_level = error
emergency_restart_interval = 12h
events.mechanism = epoll
include=/etc/php5/fpm/pool.d/*.conf
www.conf:
[www]
user = dark
group = dark
listen = /var/run/php5-fpm.sock
pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
pm.max_requests = 1500
max_execution_time = 30
request_terminate_timeout = 30
chdir = /
security.limit_extensions = .php
php_admin_value[error_log] = /home/dark/domains/somehost.kz/logs/fpm-php.www.error.log
php_admin_flag[log_errors] = on
php_admin_value[memory_limit] = 256M
php_admin_value[open_basedir] = "/home/dark:."
php_admin_value[upload_tmp_dir] = "/home/dark/tmp"
php_admin_value[session.save_path] = "/home/dark/tmp"
Пробовал ставить в www.conf "listen = 127.0.0.1:9000", но это не помогло
Вы настроили php-fpm на сокете listen = /var/run/php5-fpm.soc, а из nginx подключаетесь по порту. Нужно вместо сокета прописать 127.0.0.1:9000.
Я пробовал ставить вместо сокета айпишник, не помогло:
2013/08/14 12:25:59 [error] 4444#0: *1 connect() failed (111: Connection refused) while connecting to upstream, client: ip-адрес, server: somehost.kz, request$
P.S: отключить бы еще каптчу для авторизованных пользователей
Проблема в была в строке 319 файла www.conf: max_execution_time = 30
Этот параметр для php.ini. Чтобы задать его для php-fpm используйте php_admin_value