Перейти к содержанию
  • записи
    3
  • комментариев
    16
  • просмотра
    473

Настройка NGINX в режиме PHP-FPM для работы OpenCart


mpn2005

660 просмотров

Веб сервер nginx позволяет работать в разных режимах, как с использованием интерпретатора php, так и без.
Для работы OpenCart лучше выбирать оптимальный режим работы php-fpm. Многих данный режим пугает тем, что в данном случае
файл htaccess напрочь игнорируется и все необходимые настройки нужно вносить в конфиг nginx.
Но в этом нет ничего сверх сложного. Конфигурационный файл - это обычный текстовый файл на сервере, который 
подчиняется определённым правилам. И по данному поводу можно найти много готовых описаний и инструкций.


Данная статья не претендует на уникальность, а просто представляет краткую выжимку по настройкам, учитывая особенности 
работы с движком OpenCart и сборками на его основе.

 

Для удобства будут приводится примеры настройки с использованием панели ISPmanager.
Основные настройки будут касаться секции location, и зависимость описания от используемой панели будет минимальной.

 

Для начала переведём nginx в режим работы php-fpm. Для этого в панели сделаем следующие настройки разделе WWW-домены для 
нужного сайта:

1. Выбираем в списке нужный сайт, если их несколько, и жмём кнопку "Изменить".
2. Находим настройки PHP и настраиваем следующим образом:
diy003_001.png

Обратите внимание, что версия php у вас может отличаться. При необходимости, можно эту версию изменить на нужную, но этот вопрос выходит за рамки данной статьи.

После сохранения настроек будет работать почти всё, что и раньше. Если в настройках OpenCart отключены ЧПУ ссылки, то всё будет работать, как
и работало до переключения режима работы.
Теперь можно приступать к непосредственной настройке самого конфигурационного файла nginx для текущего сайта.
Для этого в списке www доменов находим нужный нам и нажимаем справа на иконку с тремя точками. В выпадающем меню выбираем
пункт "Конфиг":

Спойлер

diy003_002.png

 

Вот примерный конфигурационный файл, который будет создан у вас по умолчанию:

Спойлер
server {
    server_name test.ru www.test.ru;
    charset off;
    index index.php index.html;
    disable_symlinks if_not_owner from=$root_path;
    include /etc/nginx/vhosts-includes/*.conf;
    include /etc/nginx/vhosts-resources/test.ru/*.conf;
    access_log /var/www/httpd-logs/test.ru.access.log;
    error_log /var/www/httpd-logs/test.ru.error.log notice;
    ssi on;
    set $root_path /var/www/myoc/data/www/test.ru;
    root $root_path;
    location / {
        location ~ [^/]\.ph(p\d*|tml)$ {
            try_files /does_not_exists @php;
        }
        location ~* ^.+\.(jpg|jpeg|gif|png|svg|js|css|mp3|ogg|mpe?g|avi|zip|gz|bz2?|rar|swf)$ {
            expires 365d;
        }
    }
    location @php {
        fastcgi_index index.php;
        fastcgi_param PHP_ADMIN_VALUE "sendmail_path = /usr/sbin/sendmail -t -i -f webmaster@test.ru";
        fastcgi_pass unix:/var/www/php-fpm/myoc.sock;
        fastcgi_split_path_info ^((?U).+\.ph(?:p\d*|tml))(/?.+)$;
        try_files $uri =404;
        include fastcgi_params;
    }
    listen 8.8.8.8:80;
}
server {
    server_name test.ru www.test.ru;
    ssl_certificate "/var/www/httpd-cert/myoc/test.ru.crt";
    ssl_certificate_key "/var/www/httpd-cert/myoc/test.ru.key";
    ssl_ciphers EECDH:+AES256:-3DES:RSA+AES:!NULL:!RC4;
    ssl_prefer_server_ciphers on;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
    add_header Strict-Transport-Security "max-age=31536000;";
    ssl_dhparam /etc/ssl/certs/dhparam4096.pem;
    charset off;
    index index.php index.html;
    disable_symlinks if_not_owner from=$root_path;
    include /etc/nginx/vhosts-includes/*.conf;
    include /etc/nginx/vhosts-resources/test.ru/*.conf;
    access_log /var/www/httpd-logs/test.ru.access.log;
    error_log /var/www/httpd-logs/test.ru.error.log notice;
    ssi on;
    set $root_path /var/www/myoc/data/www/test.ru;
    root $root_path;
    listen 8.8.8.8:443 ssl http2;
    location / {
        location ~ [^/]\.ph(p\d*|tml)$ {
            try_files /does_not_exists @php;
        }
        location ~* ^.+\.(jpg|jpeg|gif|png|svg|js|css|mp3|ogg|mpe?g|avi|zip|gz|bz2?|rar|swf)$ {
            expires 365d;
        }
    }
    location @php {
        fastcgi_index index.php;
        fastcgi_param PHP_ADMIN_VALUE "sendmail_path = /usr/sbin/sendmail -t -i -f webmaster@test.ru";
        fastcgi_pass unix:/var/www/php-fpm/myoc.sock;
        fastcgi_split_path_info ^((?U).+\.ph(?:p\d*|tml))(/?.+)$;
        try_files $uri =404;
        include fastcgi_params;
    }
}


В конфигурации у вас будет две секции server, если у вас включено защищённое соединение SSL (и оно должно быть обязательно включено).
Если у вас включен принудительный редирект с http на https, то можно редактировать только секцию server для https.
Определить её легко: в самом начале есть параметр с указанием сертификата ssl_certificate. Также в этой секции указан параметр listen с указанием порта 443:
 

listen 8.8.8.8:443 ssl

Но лучше делать настройки сразу в двух секциях server, чтобы не допустить механической ошибки.
На данный момент нас интересует вот эта часть конфигурационного файла:

location / {
    location ~ [^/]\.ph(p\d*|tml)$ {
        try_files /does_not_exists @php;
    }
    location ~* ^.+\.(jpg|jpeg|gif|png|svg|js|css|mp3|ogg|mpe?g|avi|zip|gz|bz2?|rar|swf)$ {
        expires 365d;
    }
}


Все дальнейшие изменения мы будем вносить внутри этой секции "location /".

В первую очередь нам не хватает вот такой директивы:

if (!-e $request_filename){
    rewrite ^/(.+)$ /index.php?_route_=$1 last;
}


Данное условие очень простое: если сервер не может найти файл по указанному в запросе пути, то запрос будет переписан на вызов index.php, а в параметр _route_ будет передан запрашиваемый путь. Именно это и позволит корректно отрабатывать всем ЧПУ ссылкам движка.
Это правило является аналогом записи в файле htaccess:

RewriteRule ^([^?]*) index.php?_route_=$1 [L,QSA]


На этом можно было бы и закончить, но стоит внести ещё некоторые изменения для улучшения безопасности.

Рассмотрим более внимательно вот эту секцию:

location ~ [^/]\.ph(p\d*|tml)$ {


Тут отбираются все все подходящие динамические файлы с типами .php (в том числе с числами в окончании) и .phtml
Но у движка OpenCart в штатном режиме есть всего две точки входа для вызова php файлов через web окружение - это index.php и admin/index.php
Есть ещё install/index.php, но она используется только при установке движка.
Учитывая данные обстоятельства, логично запретить прямое выполнение всех остальных php скриптов через web окружение, кроме указанных администратором.
Сделать это можно следующим образом:

location ~ ^/(index|admin/index|install/index)\.php {
    try_files /does_not_exists @php;
}


В скобках через разделитель "|" указываем все php скрипты, которые можно выполнять. После завершения установки можно будет сократить это список 
до такого: (index|admin/index)

ВНИМАНИЕ!!! Очень важный момент! После того, как убрали вызов интерпретатора php для всех файлов, кроме указанных, при попытке запроса любого другого php файла он будет отдан как обычный текстовый файл.
И при запросе https://test.ru/config.php любой желающий сможет получить содержимое вашего конфигурационного файла, где содержится доступ к БД.
Поэтому нам обязательно нужно запретить доступ для всех остальных файлов с расширением php. Ну и заодно к другим типам файлов, которые не
стоит отдавать по запросу извне. Сделать это можно простым правилом:

location ~* \.(php|log|tpl|txt|twig|xml|ini)$ {
    deny all;
}


В скобках через разделитель "|" указываем все расширения файлов, которые мы хотим запретить.
Но у нас есть несколько важных файлов, которые пока попали под запрет, например: robots.txt и sitemap.xml. Этот вопрос мы решим чуть позже.
А сейчас ещё немного запретов. Запретим открывать файлы, которые начинаются с точки, а также все файлы в папке system:

location ~ /\. {
    deny all;
}
location ~ ^/system/ {
    deny all;
}


Этих запретов вполне достаточно, чтобы сделать невозможным выполнение каких-либо несанкционированных скриптов. А также просмотр логов, текстовых и xml файлов.

 

Теперь нам необходимо открыть доступ к файлу robots.txt, для этого нам нужно такое правило:

location = /robots.txt {
    allow all;
}

 

Также пропишем разрешение на открытие sitemap.xml и rewrite правило:

location = /sitemap.xml {
    allow all;
    rewrite ^/(.*)$ /index.php?route=extension/feed/google_sitemap last;
}


Если вы используете сторонний модуль сайтмапа, то нужно указать соответствующий route для данного модуля.
Если у вас несколько файлов sitemap или вы используете фиды для выгрузки данных, то просто пропишите для них права по аналогии.

В итоге мы должны получить вот такую секцию location:

Спойлер
location / {
    if (!-e $request_filename){
        rewrite ^/(.+)$ /index.php?_route_=$1 last;
    }

    location ~ ^/(index|admin/index)\.php {
        try_files /does_not_exists @php;
    }

    location = /sitemap.xml {
        allow all;
        rewrite ^/(.*)$ /index.php?route=extension/feed/google_sitemap last;
    }
    location = /robots.txt {
        allow all;
    }

    location ~ /\. {
        deny all;
    }
    location ~ ^/system/ {
        deny all;
    }
    location ~* \.(php|log|tpl|txt|twig|xml|ini)$ {
        deny all;
    }

    location ~* ^.+\.(jpg|jpeg|gif|png|svg|webp|js|css|mp3|ogg|mpe?g|avi|zip|gz|bz2?|rar|swf)$ {
        expires 365d;
    }
}


Этих настроек достаточно для корректной работы движка OpenCart. И при этом данная конфигурация является безопасной с точки зрения выполнения 
несанкционированных скриптов php через web окружение.

После всех настроек обязательно проверьте правильность работы, сделав запросы по указанному чек-листу (test.ru замените на адрес вашего сайта):

https://test.ru/config.php
https://test.ru/admin/config.php
https://test.ru/admin/1.php
https://test.ru/admin/1.txt
https://test.ru/admin/1.log
https://test.ru/admin/1.xml
https://test.ru/system/modification.xml


Для всех этих ссылок вы должны получить ошибку "403 Forbidden", вне зависимости от того, есть файл по указанному пути на сервере, или нет.

Также проверяем белый список:

https://test.ru/robots.txt
https://test.ru/sitemap.xml


Эти файлы не должны вызывать ошибок и вы должны корректно получать их содержимое.
Дополнительно стоит проверить все ваши дополнительные сайтмапы или фиды, если вы их добавляли.

 

Ещё раз повторюсь, что данная настройка является базовой, с небольшими правилами для улучшения безопасности.
Но даже уже при такой настройке вы в среднем получите выигрыш 100-200ms для параметра TTFB, по сравнению с остальными режимами работы.

5 Комментариев


Рекомендуемые комментарии

Не хватает очень важной настройки.

Да и в принципе не раскрыта тема настройки конфига для самого php-fpm, а его настройка по-умолчанию оставляет желать лучшего.

Как известно, режим nginx+ php-fpm чреват "сюрпризами" в виде утечки памяти. Это в конце концов приводит к тому, что спустя несколько дней память будет использована под 100%, а сервер, соответственно, ляжет.

 

Поиск через поисковики показывает, что проблема эта глобальная и давняя. Т.е. это не единичные случаи, это повальная проблема. Разрастаются в потреблении памяти дочерние процессы php-fpm.

 

Проявляется не на всех версиях php, в частности на 5.6 я этой проблемы не наблюдал, но на 7.* - это будет почти всегда.

 

поэтому к конфигурации  самого php-fpm нужно подходить не менее тщательно, чем к конфигурации nginx.

 

Я неоднократно писал об этой проблеме на разных форумах. И неоднократно же ко мне обращались за решением данной проблемы.

 

pm.max_requests = 1500

 

Слишком малое значение не стоит устанавливать. Это значение зависит от доступного объема памяти сервера. Конечное значение подбирается опытным путем.

Это максимальное количество запросов max_requests до перезапуска процессов FPM.

 

На остальные параметры также обратите внимание. На скриншоте файл конфигурации, редактируемый через панель управления aapanel, но сама панель управления не имеет значения, т.к. принципы едины.

 

sitecreator_ru_ingycEOcfV.png

Изменено пользователем sitecreator
Ссылка на комментарий
В 06.05.2022 в 19:35, sitecreator сказал:

Да и в принципе не раскрыта тема настройки конфига для самого php-fpm, а его настройка по-умолчанию оставляет желать лучшего.

Да. Тут даже и не весь конфиг описан по настройки самого nginx.

Цель была сделать упор именно на особенность настройки для OpenCart.

 

В 06.05.2022 в 19:35, sitecreator сказал:

Как известно, режим nginx+ php-fpm чреват "сюрпризами" в виде утечки памяти. Это в конце концов приводит к тому, что спустя несколько дней память будет использована под 100%, а сервер, соответственно, ляжет.

Кстати уже не на первом проекте замечаю, что такая беда уже имеет не такой повальный характер как раньше. Прогресс всё же не стоит на месте.

И уже не везде встречается пила по потреблению памяти. В последнее время сервера попадались Debian и Ubuntu (для справки).

 

В 06.05.2022 в 19:35, sitecreator сказал:

Слишком малое значение не стоит устанавливать. Это значение зависит от доступного объема памяти сервера. Конечное значение подбирается опытным путем.

Настройке параметров процессов можно отдельную статью посвятить.

Но там уже не всё так просто, т.к. зависит от ресурсов сервера. Да и от посещаемости тоже зависит.

Ссылка на комментарий
В 06.05.2022 в 21:26, mpn2005 сказал:

Настройке параметров процессов можно отдельную статью посвятить.

Но там уже не всё так просто, т.к. зависит от ресурсов сервера. Да и от посещаемости тоже зависит.

 

разумеется, что все имеет значение.

минимально, что стоит сделать - это подстраховаться от утечек памяти.

т.е. это нужно прописывать обязательно.

Даже можно немножко пожертвовать производительностью, но увеличить стабильность.

 

Просто для тех, кто решил перейти на php-fpm, утечка памяти - это самая распространенная неожиданность. Крайне неприятная неожиданность.

И это не зависит от самого веб-сервера, это может быть Апачи или Nginx, в данном случае не имеет значения, т.к. корень проблемы кроется именно в процессах php-fpm, которые в принципе могут быть вообще и без веб-сервера.

 

Тонкую настройку можно сделать после, но подстраховку от утечек нужно делать сразу. Это чтобы не перезапускать весь сервер пару раз в неделю после очередного зависания.

 

 

Ссылка на комментарий

 

В 06.05.2022 в 19:35, sitecreator сказал:

Я неоднократно писал об этой проблеме на разных форумах. И неоднократно же ко мне обращались за решением данной проблемы.

 

pm.max_requests = 1500

 

Слишком малое значение не стоит устанавливать. Это значение зависит от доступного объема памяти сервера. Конечное значение подбирается опытным путем.

Это максимальное количество запросов max_requests до перезапуска процессов FPM.


Все правильно написано, чуть дополню...

Универсальных настроек конечно не существует, каждый сервер настраивается под определенный проект. 

request_terminate_timeout - переменная отвечающая за максимальное время выполнения процесса прежде чем он будет уничтожен. 
pm.max_requests - в данной переменной выставляется максимальное количество запросов, после чего произойдет сброс процесса  и память не будет переполняться. Маленькое значение плохо, так как приведет к частым перезапускам процессов и следовательно к уменьшению производительности.

Узнать потребление памяти Active и Inactive можно командами по SHH:
free -h (в гигабайтах)
free -m (в мегабайтах)
или cat /proc/meminfo
---------------------------
Очистка cashe памяти, три варианта без прерывания каких-либо процессов или служб. 
1. Clear PageCache only.
sync; echo 1 > /proc/sys/vm/drop_caches (очистка кеш страниц PageCache) 
2. Clear dentries and inodes.
sync; echo 2 > /proc/sys/vm/drop_caches 
3. Clear PageCache, dentries and inodes.(очистка сразу всего, не рекомендуется сразу)
sync; echo 3 > /proc/sys/vm/drop_caches
---------------------------
Что потребляет больше всего оперативной памяти? Команды:
top
Сортировка по объёму памяти:
shift+M
Сортировка по времени
shift+T
Cортировка в одну или в другую сторону (использовать, чтобы больший параметр был вверху)
shift+R
Клавиша «Q» — выйти из команды Top.

Ссылка на комментарий
Гость
Добавить комментарий...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...