В предыдущей статье Настройка веб-сервера 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