Статья про оптимизацию Drupal. В статье описано как можно настроить веб-сервер Nginx фронтэндом к Apache. В данном случае Nginx принимает все пользовательские запросы и сам отдает всю статику, а динамические запросы отправляет на Apache.
Продолжаем серию статей по обучению системных администраторов для Drupal проектов.
В предыдущей статье Настройка веб-сервера на Debian и установка Drupal мы сделали базовую настройку веб-сервера и установили Drupal.
У этого решения есть некоторые недостатки:
- При работе с клиентами, у которых медленные каналы связи, оперативная память сервера будет занята процессом Apache до тех пор пока он полностью не отдаст запрошенный контент.
- Каждый раз когда клиент запрашивает статический контент будет запущен процесс Apache для выдачи этого контента, что тоже будет "отъедать" драгоценную оперативную память сервера.
Отличным способом устранения недостатков нашего решения является использования веб-сервера Nginx в качестве front-end к Apache. Все запросы к статике будет обслуживать Nginx, а запросы к динамических страницам Nginx будет проксировать на Apache. В этой статье мы рассмотрим подробную настройку этого решения.
Почему Nginx?
Nginx — это быстрый HTTP сервер и обратный прокси-сервер (reverse proxy), разработанный Игорем Сысоевым. Основным функционалом Nginx является обслуживание статических запросов, обратное проксирование (reverse proxy) и балансировка нагрузки. С этими задачами веб-сервер Nginx справляется значительно лучше, чем Apache, за счет своей архитектуры. Поэтому в нашей задаче мы вынесем обработку статических запросов из Apache в Nginx и настроим Nginx как обратный прокси-сервер (reverse proxy) для остальных запросов.
Схема работы Nginx в качество front-end к Apache
В результате внедрения в работу Nginx схема работы нашего веб-сервера изменится:

Из схемы видно, что все запросы принимает Nginx, после чего динамические запросы Nginx отправляет на Apache, а все статические запросы Nginx обрабатывает самостоятельно.
Конфигурация Apache
Настраиваем в Apache возможность прослушивания порта 8080 В файле /etc/apache2/ports.conf изменяем строки NameVirtualHost и Listen на следующие:
NameVirtualHost 127.0.0.1:8080 Listen 8080
Вносим изменения в конфигурацию Apache в файле /etc/apache2/sites-enabled/drupaladmin-example.com . Настраиваем Apache на порт 8080, т.к. на порту 80 будет слушать запросы Nginx
<VirtualHost 127.0.0.1:8080>
ServerAdmin info@drupaladmin-example.com
ServerName www.drupaladmin-example.com
ServerAlias drupaladmin-example.com
DocumentRoot /home/webmaster/domains/drupaladmin-example.com/html
<Directory /home/webmaster/domains/drupaladmin-example.com/html>
AllowOverride All
Options -Indexes +FollowSymLinks
Require all granted
</Directory>
ErrorLog /home/webmaster/domains/drupaladmin-example.com/logs/apache_errors.log
# Possible values include: debug, info, notice, warn, error, crit,
# alert, emerg.
# LogLevel warn
CustomLog /home/webmaster/domains/drupaladmin-example.com/logs/apache_access.log combined
php_admin_value upload_tmp_dir "/home/webmaster/domains/tmp"
php_admin_value session.save_path "/home/webmaster/domains/tmp"
AddType application/x-httpd-php .php .php3 .php4 .php5 .phtml
AddType application/x-httpd-php-source .phps
</VirtualHost>Перезапускаем Apache
/etc/init.d/apache2 restart
Установка и настройка Nginx
Устанавливаем Nginx из пакетов Debian:
apt-get install nginx
Создаем виртуальный хост Nginx для сайта drupal-admin.ru в файле /etc/nginx/sites-available/drupaladmin-example.com
server {
listen 80;
server_name drupaladmin-example.com www.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;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_hide_header 'X-Drupal-Cache';
proxy_hide_header 'X-Generator';
if ($bad_bot) {
return 444;
}
if ($bad_referer) {
return 444;
}
if ($not_allowed_method) {
return 405;
}
proxy_http_version 1.1;
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/ {
proxy_pass http://127.0.0.1:8080/index.php?q=$uri;
proxy_set_header Connection '';
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 {
proxy_pass http://127.0.0.1:8080/index.php?q=$uri;
proxy_set_header Connection '';
}
location = /authorize.php {
proxy_pass http://127.0.0.1:8080;
}
location = /cron.php {
proxy_pass http://127.0.0.1:8080;
}
location = /index.php {
proxy_pass http://127.0.0.1:8080;
}
location = /install.php {
proxy_pass http://127.0.0.1:8080;
}
location = /update.php {
proxy_pass http://127.0.0.1:8080;
}
location = /xmlrpc.php {
proxy_pass http://127.0.0.1:8080;
}
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 путем установки ссылки
ln -s /etc/nginx/sites-available/drupaladmin-example.com /etc/nginx/sites-enabled/drupaladmin-example.com
Создаем файл конфигурации 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;
}Перезапускаем Nginx
/etc/init.d/nginx restart
Готово. Мы оптимизировали наш веб-сервер, мы снизили нагрузку на Apache с помощью веб-сервера Nginx, который позволил нам быстро обрабатывать запросы по выдаче пользователям статического контента.
Но еще есть над чем работать, в следующих статьях будем разбираться что еще можно необходимо сделать для веб-сервера.