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