Переводим сайты WordPress на LEMP (Linux + Nginx + MySQL + php-fpm). Nginx wordpress php fpm


Установка и настройка nginx php-fpm php7.1 на CentOS 7

Я уже писал статью по данной теме, и она формально даже не устарела, если брать все пакеты из официальных репозиториев. Сегодня я настрою производительный веб сервер на свежих версиях nginx, php-fpm, где сам php версии 7.1.  Сейчас использовать версию php54, которую предлагает CentOS по-умолчанию, очень странно, поэтому я решил актуализировать статью и все настроить в соответствии с современными реалиями.

Введение

Ранее я рассказывал о настройке nginx и php-fpm. В принципе, статья полностью актуальна, по ней получится настроить веб сервер, если вас устраивают версии предложенных в стандартном репозитории пакетов. Если же хочется версий посвежее, то читайте далее.

Работать будем на сервере под управлением CentOS 7. Если у вас его еще нет, то читайте мои статьи на тему установки и базовой настройки centos. Не забудьте уделить внимание теме настройки iptables. В данной статье я ее не буду касаться, хотя тема важная для web сервера.

В своей тестовой среде я буду использовать следующие сущности.

hl.zeroxzed.ru имя тестового виртуального хоста и сайта
/web/sites директория для размещения виртуальных хостов
 95.169.190.64  внешний ip адрес сервера
 p1m2a.zeroxzed.ru  имя виртуального хоста для phpmyadmin

Подопытным сервером будет выступать виртуальная машина от keyweb, расположенная на сервере в Германии. Характеристики следующие:

Процессор 2 ядра
Память 8 Gb
Диск 150 Gb SSD

Указанный сервер включает в себя администрирование. То есть вы можете его заказать и прислать в техподдержку ссылку на эту статью. Они за вас все настроят. Если все же хотите настраивать сами, то берите сервер из линейки PRO. Они дешевле, но настраивать все придется самому. Чем я и займусь 🙂

Установка nginx на CentOS 7

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

# rpm -Uvh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm

Если по какой-то причине ссылка изменится или устареет, то можно создать файл с конфигурацией репозитория nginx вручную. Для этого рисуем такой конфиг /etc/yum.repos.d/nginx.repo.

[nginx] name=nginx repo baseurl=http://nginx.org/packages/centos/7/$basearch/ gpgcheck=0 enabled=1

Устанавливаем nginx на сервер.

# yum install nginx

Установка nginx на CentOS 7

Запускаем nginx и добавляем в автозагрузку.

# systemctl start nginx # systemctl enable nginx

Проверяем, запустился ли web сервер. Для этого идем по ссылке http://95.169.190.64/. Вы должны увидеть стандартную страницу заглушку.

Проверка nginx

Если страница не открывается, то скорее всего вы не настроили firewall. Свою статью по его настройке я приводил в самом начале.

Настройка nginx

Расскажу, как настроить nginx для работы разных виртуальных хостов. Создадим виртуальный хост и подготовим директории для размещения исходников сайта и панели управления phpmyadmin.

# mkdir -p /web/sites/hl.zeroxzed.ru/www && mkdir /web/sites/hl.zeroxzed.ru/log # mkdir -p /web/sites/p1m2a.zeroxzed.ru/www && mkdir /web/sites/p1m2a.zeroxzed.ru/log

Создадим конфиги nginx для этих виртуальных хостов. Я сразу буду делать их с учетом https, который мы настроим позже. Так что после создания не надо перезапускать веб сервер и проверять работу — будут ошибки. Виртуальный хост сайта показан на примере wordpress. Конфигурация собрана на основе рекомендаций из официальной документации конкретно для веб сервера nginx.

# mcedit /etc/nginx/conf.d/hl.zeroxzed.ru.conf server { listen 80; server_name hl.zeroxzed.ru; root /web/sites/hl.zeroxzed.ru/www/; index index.php index.html index.htm; access_log /web/sites/hl.zeroxzed.ru/log/access.log main; error_log /web/sites/hl.zeroxzed.ru/log/error.log; location / { return 301 https://hl.zeroxzed.ru$request_uri; } location ~* ^.+.(js|css|png|jpg|jpeg|gif|ico|woff)$ { return 301 https://hl.zeroxzed.ru$request_uri; } location ~ \.php$ { return 301 https://hl.zeroxzed.ru$request_uri; } location = /favicon.ico { log_not_found off; access_log off; } location = /robots.txt { rewrite ^ /robots.txt break; allow all; log_not_found off; access_log off; } location ~ /\.ht { deny all; } } server { listen 80; server_name www.hl.zeroxzed.ru; rewrite ^ https://hl.zeroxzed.ru$request_uri? permanent; } server { listen 443 ssl http2; server_name hl.zeroxzed.ru; root /web/sites/hl.zeroxzed.ru/www/; index index.php index.html index.htm; access_log /web/sites/hl.zeroxzed.ru/log/ssl-access.log main; error_log /web/sites/hl.zeroxzed.ru/log/ssl-error.log; keepalive_timeout 60; ssl_certificate /etc/letsencrypt/live/hl.zeroxzed.ru/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/hl.zeroxzed.ru/privkey.pem; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA'; ssl_dhparam /etc/ssl/certs/dhparam.pem; add_header Strict-Transport-Security 'max-age=604800'; location / { try_files $uri $uri/ /index.php?$args; } location ~* ^.+.(js|css|png|jpg|jpeg|gif|ico|woff)$ { access_log off; expires max; } location ~ \.php$ { try_files $uri =404; fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock; #fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param DOCUMENT_ROOT /web/sites/hl.zeroxzed.ru/www/; fastcgi_param SCRIPT_FILENAME /web/sites/hl.zeroxzed.ru/www$fastcgi_script_name; fastcgi_param PATH_TRANSLATED /web/sites/hl.zeroxzed.ru/www$fastcgi_script_name; include fastcgi_params; fastcgi_param QUERY_STRING $query_string; fastcgi_param REQUEST_METHOD $request_method; fastcgi_param CONTENT_TYPE $content_type; fastcgi_param CONTENT_LENGTH $content_length; fastcgi_param HTTPS on; fastcgi_intercept_errors on; fastcgi_ignore_client_abort off; fastcgi_connect_timeout 60; fastcgi_send_timeout 180; fastcgi_read_timeout 180; fastcgi_buffer_size 128k; fastcgi_buffers 4 256k; fastcgi_busy_buffers_size 256k; fastcgi_temp_file_write_size 256k; } location = /favicon.ico { log_not_found off; access_log off; } location = /robots.txt { allow all; log_not_found off; access_log off; } location ~ /\.ht { deny all; } } server { listen 443 ssl http2; server_name www.hl.zeroxzed.ru; rewrite ^ https://hl.zeroxzed.ru$request_uri? permanent; }

В данной конфигурации настроены все необходимые редиректы, при этом отключен редирект файла robots.txt. Он отдельно отдается по http и https. Это требуется для яндекса во время перехода с http на https и склейки зеркал.

Для phpmyadmin рисуем конфиг попроще.

# mcedit /etc/nginx/conf.d/p1m2a.zeroxzed.ru.conf server { listen 443 ssl http2; server_name p1m2a.zeroxzed.ru; root /web/sites/p1m2a.zeroxzed.ru/www/; index index.php index.html index.htm; access_log /web/sites/p1m2a.zeroxzed.ru/log/ssl-access.log main; error_log /web/sites/p1m2a.zeroxzed.ru/log/ssl-error.log; keepalive_timeout 60; ssl_certificate /etc/letsencrypt/live/p1m2a.zeroxzed.ru/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/p1m2a.zeroxzed.ru/privkey.pem; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA'; ssl_dhparam /etc/ssl/certs/dhparam.pem; add_header Strict-Transport-Security 'max-age=604800'; location ~ \.php$ { fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock; #fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param DOCUMENT_ROOT /web/sites/p1m2a.zeroxzed.ru/www/; fastcgi_param SCRIPT_FILENAME /web/sites/p1m2a.zeroxzed.ru/www$fastcgi_script_name; fastcgi_param PATH_TRANSLATED /web/sites/p1m2a.zeroxzed.ru/www$fastcgi_script_name; include fastcgi_params; fastcgi_param QUERY_STRING $query_string; fastcgi_param REQUEST_METHOD $request_method; fastcgi_param CONTENT_TYPE $content_type; fastcgi_param CONTENT_LENGTH $content_length; fastcgi_intercept_errors on; fastcgi_ignore_client_abort off; fastcgi_connect_timeout 60; fastcgi_send_timeout 180; fastcgi_read_timeout 180; fastcgi_buffer_size 128k; fastcgi_buffers 4 256k; fastcgi_busy_buffers_size 256k; fastcgi_temp_file_write_size 256k; } } server { listen 443 ssl http2; server_name www.p1m2a.zeroxzed.ru; rewrite ^ https://p1m2a.zeroxzed.ru$request_uri? permanent; } server { listen 80; server_name p1m2a.zeroxzed.ru; root /web/sites/p1m2a.zeroxzed.ru/www/; index index.php index.html index.htm; access_log /web/sites/p1m2a.zeroxzed.ru/log/access.log main; error_log /web/sites/p1m2a.zeroxzed.ru/log/error.log; location / { return 301 https://p1m2a.zeroxzed.ru$request_uri; try_files $uri $uri/ /index.php?$args; } }

Сохраняем конфиги виртуальных хостов nginx и продолжаем настройку производительного веб сервера.

Установка php-fpm 7.1

Установка и настройка 7-й версии php на centos не очень простая задача. Ранее я уже рассказывал как обновить php до 7-й версии, но в итоге откатился назад. Прошло прилично времени и откатываться уже не будем, так как большинство проблем исправлены.

Основные трудности возникают с тем, что в официальных репозиториях очень старые версии php, но при этом они часто есть в зависимостях к другим пакетам. В итоге, обновившись неаккуратно до 7.1 можно получить проблемы с установкой и обновлением, к примеру, phpmyadmin или zabbix. В комментариях к моим статьям я иногда вижу эти ошибки и по тексту ошибок сразу понимаю, что проблема с зависимостями.

Вторая проблема в том, что надо определить, какой репозиторий использовать для установки php7. Их существует очень много. К примеру, мой хороший знакомый в своей статье по настройке web сервера использует репозиторий Webtatic. В принципе, чтобы просто поставить php 7-й версии это нормальный вариант. Но если вы после этого захотите установить phpmyadmin через yum уже ничего не получится. Будет ошибка зависимостей, которые нужно будет как-то руками разбирать.

То же самое будет и с другими пакетами. К примеру, zabbix без плясок с бубнами скорее всего не встанет. В сторонних репозиториях есть еще одна проблема. Иногда они закрываются. И это станет для вас большой проблемой на боевом сервере. Так что к выбору репозитория нужно подходить очень аккуратно и внимательно. Я до сих пор иногда встречаю настроенные сервера centos 5 с очень популярным в прошлом репозиторием centos.alt.ru, который закрылся. Сейчас это уже не так актуально, так как таких серверов осталось мало, но некоторое время назад мне это доставляло серьезные неудобства.

Для установки свежей версии php я буду использовать репозиторий Remi. Это известный и популярный репозиторий, который ведет сотрудник RedHat. И хотя надежность репозитория, который ведет один человек не так высока, но ничего лучше и надежнее remi лично я не нашел для своих целей. Если вы можете что-то посоветовать на этот счет — комментарии в вашем распоряжении. Буду благодарен за дельный совет.

Подключаем remi репозиторий для centos 7.

# rpm -Uhv http://rpms.remirepo.net/enterprise/remi-release-7.rpm

Я получил ошибку:

Retrieving http://rpms.remirepo.net/enterprise/remi-release-7.rpm warning: /var/tmp/rpm-tmp.nwcDV1: Header V4 DSA/SHA1 Signature, key ID 00f97f56: NOKEY error: Failed dependencies: epel-release = 7 is needed by remi-release-7.3-2.el7.remi.noarch

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

# yum install epel-release

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

# yum repolist

Список репозиториев

У меня такая картинка получилась.

Активируем репу remi-php71, для этого выполняем команду:

# yum-config-manager --enable remi-php71

Если получаете ошибку:

bash: yum-config-manager: command not found

то установите пакет yum-utils.

# yum install yum-utils

Теперь устанавливаем php7.1.

# yum install php71

Установка php 7.1 на CentOS 7

Установим php-fpm и наиболее популярные модули, которые могут пригодится в процессе эксплуатации веб сервера.

# yum install php-fpm php-cli php-mysql php-gd php-ldap php-odbc php-pdo php-pecl-memcache php-pear php-xml php-xmlrpc php-mbstring php-snmp php-soap

Установка php-fpm

Запускаем php-fpm и добавляем в автозагрузку.

# systemctl start php-fpm # systemctl enable php-fpm

Проверяем, запустился ли он.

# netstat -tulpn | grep php-fpm tcp 0 0 127.0.0.1:9000 0.0.0.0:* LISTEN 9084/php-fpm: maste

Все в порядке, повис на порту 9000. Запустим его через unix сокет. Для этого открываем конфиг /etc/php-fpm.d/www.conf и комментируем строку:

;listen = 127.0.0.1:9000

Вместо нее добавляем несколько других:

listen = /var/run/php-fpm/php-fpm.sock listen.mode = 0660 listen.owner = nginx listen.group = nginx

Заодно измените пользователя, от которого будет работать php-fpm. Вместо apache укажите nginx.

user = nginx group = nginx

Перезапускаем php-fpm.

# systemctl restart php-fpm

Проверяем, стартовал ли указанный сокет.

# ll /var/run/php-fpm/php-fpm.sock srw-rw----. 1 nginx nginx 0 Oct 26 18:08 /var/run/php-fpm/php-fpm.sock

На текущий момент с настройкой php-fpm закончили, двигаемся дальше.

Для того, чтобы проверить работу нашего веб сервера, нужно установить ssl сертификаты. Без них nginx с текущим конфигом не запустится. Исправляем это.

Настройка бесплатного ssl сертификата Lets Encrypt

Устанавливаем пакет certbot для получения бесплатного ssl сертификата от let’s encrypt.

# yum install certbot

Запускаем программу для генерации сертификата.

# certbot certonly

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

# certbot certonly Saving debug log to /var/log/letsencrypt/letsencrypt.log How would you like to authenticate with the ACME CA? ------------------------------------------------------------------------------- 1: Spin up a temporary webserver (standalone) 2: Place files in webroot directory (webroot) ------------------------------------------------------------------------------- Select the appropriate number [1-2] then [enter] (press 'c' to cancel): 1 Plugins selected: Authenticator standalone, Installer None Enter email address (used for urgent renewal and security notices) (Enter 'c' to cancel): [email protected] Starting new HTTPS connection (1): acme-v01.api.letsencrypt.org ------------------------------------------------------------------------------- Please read the Terms of Service at https://letsencrypt.org/documents/LE-SA-v1.1.1-August-1-2016.pdf. You must agree in order to register with the ACME server at https://acme-v01.api.letsencrypt.org/directory ------------------------------------------------------------------------------- (A)gree/(C)ancel: A ------------------------------------------------------------------------------- Would you be willing to share your email address with the Electronic Frontier Foundation, a founding partner of the Let's Encrypt project and the non-profit organization that develops Certbot? We'd like to send you email about EFF and our work to encrypt the web, protect its users and defend digital rights. ------------------------------------------------------------------------------- (Y)es/(N)o: N Please enter in your domain name(s) (comma and/or space separated) (Enter 'c' to cancel): hl.zeroxzed.ru Obtaining a new certificate Performing the following challenges: tls-sni-01 challenge for hl.zeroxzed.ru Waiting for verification... Cleaning up challenges IMPORTANT NOTES: - Congratulations! Your certificate and chain have been saved at: /etc/letsencrypt/live/hl.zeroxzed.ru/fullchain.pem Your key file has been saved at: /etc/letsencrypt/live/hl.zeroxzed.ru/privkey.pem Your cert will expire on 2018-01-24. To obtain a new or tweaked version of this certificate in the future, simply run certbot again. To non-interactively renew *all* of your certificates, run "certbot renew" - Your account credentials have been saved in your Certbot configuration directory at /etc/letsencrypt. You should make a secure backup of this folder now. This configuration directory will also contain certificates and private keys obtained by Certbot so making regular backups of this folder is ideal. - If you like Certbot, please consider supporting our work by: Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate Donating to EFF: https://eff.org/donate-le

Для успешного создания бесплатных ssl сертификатов от lets encrypt у вас должны быть корректно настроены DNS записи для доменов, на которые выпускаются сертификаты.

Итак, сертификаты получили. Теперь можно проверить конфигурацию nginx и запустить его. Проверяем конфиг:

# nginx -t

Если получаете ошибку:

nginx: [emerg] BIO_new_file("/etc/ssl/certs/dhparam.pem") failed (SSL: error:02001002:system library:fopen:No such file or directory:fopen('/etc/ssl/certs/dhparam.pem','r') error:2006D080:BIO routines:BIO_new_file:no such file) nginx: configuration file /etc/nginx/nginx.conf test failed

То генерируете необходимый ключ:

# openssl dhparam -out /etc/ssl/certs/dhparam.pem 4096

Генерация будет длиться долго (у меня 20 минут длилось на двух ядрах). Снова проверяйте конфигурацию. Если ошибок нет, то перезапустим nginx.

# systemctl restart nginx

Настройка nginx на этом завершена. Он должен корректно запуститься и работать в рабочем режиме.

Теперь сделаем так, чтобы сертификаты автоматически обновлялись перед истечением срока действия. Для этого необходимо изменить конфигурации доменов. Они располагаются в директории /etc/letsencrypt/renewal. Так как мы генерировали сертификаты с помощью временного веб сервера, наш текущий конфиг hl.zeroxzed.ru.conf выглядит вот так:

# renew_before_expiry = 30 days version = 0.18.1 archive_dir = /etc/letsencrypt/archive/hl.zeroxzed.ru cert = /etc/letsencrypt/live/hl.zeroxzed.ru/cert.pem privkey = /etc/letsencrypt/live/hl.zeroxzed.ru/privkey.pem chain = /etc/letsencrypt/live/hl.zeroxzed.ru/chain.pem fullchain = /etc/letsencrypt/live/hl.zeroxzed.ru/fullchain.pem # Options used in the renewal process [renewalparams] authenticator = standalone installer = None account = e9c86e6aa57b45f9614bc7c0015927a5

Приводим его к следующему виду:

# renew_before_expiry = 30 days version = 0.18.1 archive_dir = /etc/letsencrypt/archive/hl.zeroxzed.ru cert = /etc/letsencrypt/live/hl.zeroxzed.ru/cert.pem privkey = /etc/letsencrypt/live/hl.zeroxzed.ru/privkey.pem chain = /etc/letsencrypt/live/hl.zeroxzed.ru/chain.pem fullchain = /etc/letsencrypt/live/hl.zeroxzed.ru/fullchain.pem # Options used in the renewal process [renewalparams] authenticator = webroot installer = None account = e9c86e6aa57b45f9614bc7c0015927a5 post_hook = nginx -s reload [[webroot_map]] www.hl.zeroxzed.ru = /web/sites/hl.zeroxzed.ru/www hl.zeroxzed.ru = /web/sites/hl.zeroxzed.ru/www

По аналогии делаете с остальными виртуальными хостами, для которых используете бесплатные сертификаты let’s encrypt. Осталось дело за малым — настроить автоматический выпуск новых ssl сертификатов, взамен просроченным. Для этого добавляем в /etc/crontab следующую строку:

# Cert Renewal 30 2 * * * /usr/bin/certbot renew --post-hook "nginx -s reload" >> /var/log/le-renew.log

Все, с сертификатами закончили. Двигаемся дальше в настройке web сервера.

Установка mariadb 10 на CentOS 7

Дошла очередь до установки сервера баз данных для web сервера на CentOS 7 — MariaDB. По аналогии с другим софтом, в официальном репозитории очень старая версия mariadb — 5.5. Я же буду устанавливать последнюю стабильную версию на момент написания статьи — 10.2.

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

В моем случае конфиг получился следующий.

# cat /etc/yum.repos.d/mariadb.repo [mariadb] name = MariaDB baseurl = http://yum.mariadb.org/10.2/centos7-amd64 gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB gpgcheck=1

Устанавливаем последнюю версию mariadb на centos.

# yum install MariaDB-server MariaDB-client

Установка MariaDB 10 на web сервер

Убедитесь, что база данных ставится из нужного репозитория.

Запускаем mariadb и добавляем в автозагрузку.

# systemctl start mariadb # systemctl enable mariadb

Запускаем скрипт начальной конфигурации mysql и задаем пароль для root. Все остальное можно оставить по-умолчанию.

# /usr/bin/mysql_secure_installation

Сервер баз данных mysql для нашего web сервера готов. Продолжаем настройку. Установим панель управления mysql — phpmyadmin.

Установка phpmyadmin

Кратко расскажу про установку phpmyadmin в контексте данной статьи. Подробно не буду останавливаться на этом, так как статья и так получается очень объемная, а я еще не все рассказал. Вопрос настройки phpmyadmin я очень подробно рассмотрел отдельно. За подробностями можно сходить туда.

Устанавливаем phpmyadmin через yum. Если ранее все сделали правильно, то конфликтов с зависимостями быть не должно.

# yum install phpmyadmin

Установка phpmyadmin на nginx и php-fpm

Phpmyadmin по-умолчанию сконфигурирована для работы с httpd. Для того, чтобы в будущем автоматически обновлять ее, просто сделаем символьную ссылку из директории с исходниками панели в наш виртуальный хост.

# rm -df /web/sites/p1m2a.zeroxzed.ru/www # ln -s /usr/share/phpMyAdmin /web/sites/p1m2a.zeroxzed.ru/www

Выставляем правильные права на директорию с php сессиями. Без этого работать phpmyadmin не будет.

# chown nginx:nginx /var/lib/php/session/

Можно заходить и проверять работу phpmyadmin. Ее установка закончена.

Доступ к сайту по sftp

Настройка сервера почти завершена. Если вы администратор и единственный пользователь, то больше можно ничего не делать. Вы и так сможете загрузить на сервер все что нужно тем или иным способом. Если же вы будете передавать управление сайтами другим людям, им нужен доступ к директории с исходниками сайта. Раньше для этих целей повсеместно использовали ftp. Если вы хотите так сделать, у меня есть статья по настройке ftp сервера vsftpd.

Я же предлагаю использовать sftp по нескольким причинам:

  1. Он безопаснее.
  2. Его быстрее настроить.
  3. Не надо отдельно настраивать firewall.

Статью по настройке sftp доступа я уже тоже писал, все подробности там. Здесь без комментариев выполним необходимые действия.

Создаем пользователя для подключения к сайту. Я обычно использую имя пользователя пересекающееся с названием сайта. Так удобнее управлять.

# useradd -s /sbin/nologin hl.zeroxzed.ru # passwd hl.zeroxzed.ru

Открываем конфиг ssh по пути /etc/ssh/sshd_config и комментируем там одну строку, добавляя далее несколько новых.

#Subsystem sftp /usr/libexec/openssh/sftp-server Subsystem sftp internal-sftp Match User hl.zeroxzed.ru ChrootDirectory /web/sites/hl.zeroxzed.ru ForceCommand internal-sftp

Перезапускаем службу sshd.

# systemctl restart sshd

Этого уже достаточно, чтобы вы могли подключиться к сайту, к примеру, с помощью программы winscp. Если что-то пойдет не так и будут какие-то ошибки, то смотреть подробности нужно в логе /var/log/secure. Но тут возникает много нюансов с правами к файлам и директориям. Дальше я расскажу, как их аккуратно и грамотно разрулить, чтобы у нас не было проблем с дальнейшей работой сайтов от разных пользователей.

Работа с сайтами разных пользователей на одном веб сервере

Самый простой способ решить проблему с правами доступа, это сделать владельцем папки с сайтом пользователя, который подключается по sftp. Тогда он сможет нормально работать с файлами, загружать и удалять их. Если доступ в качестве группы установить для nginx, то в целом все будет работать. Для каких-то сайтов такой вариант может оказаться подходящим. То есть сделать надо вот так:

# chown -R hl.zeroxzed.ru:nginx /web/sites/hl.zeroxzed.ru/ # chmod -R 0775 /web/sites/hl.zeroxzed.ru/

Но при такой схеме будут проблемы с движками сайтов, которые автоматом что-то к себе загружают. Какие-то галереи не будут работать. К примеру, wordpress не сможет автоматически загружать плагины, будет просить доступ к ftp. В общем, могут возникнуть некоторые неудобства. Сейчас мы их исправим.

Еще обращаю внимание на один нюанс. Chroot доступ для sftp не будет работать, если владельцем директории, куда чрутимся, будет не root. Только что мы сделали владельцем каталога с сайтом и всего, что внутри него пользователя hl.zeroxzed.ru. Теперь надо вернуть обратно владельцем исходного каталога рута, а все, что внутри него остается как мы и хотим — будет принадлежать hl.zeroxzed.ru.

# chown root:root /web/sites/hl.zeroxzed.ru/ # chmod 0755 /web/sites/hl.zeroxzed.ru/

А теперь сделаем все красиво. Назначаем владельцем содержимого нашего сайта только отдельного пользователя.

# chown -R hl.zeroxzed.ru:hl.zeroxzed.ru /web/sites/hl.zeroxzed.ru/

Возвращаем обратно рута владельцем корня chroot.

# chown root:root /web/sites/hl.zeroxzed.ru/ # chmod 0755 /web/sites/hl.zeroxzed.ru/

Обращаю внимание, что сначала мы рекурсивно назначаем права на все содержимое директорий, а потом возвращаем владельца root только на корень.

Добавляем пользователя nginx в группу hl.zeroxzed.ru.

# usermod -aG hl.zeroxzed.ru nginx

Создаем отдельный pool для php-fpm, который будет обслуживать сайт hl.zeroxzed.ru и будет запускаться от этого пользователя. Для этого копируем существующий конфиг /etc/php-fpm.d/www.conf и изменяем в нем несколько строк.

# cd /etc/php-fpm.d && cp www.conf hl.zeroxzed.ru.conf [hl.zeroxzed.ru] user = hl.zeroxzed.ru group = hl.zeroxzed.ru listen = /var/run/php-fpm/hl.zeroxzed.ru.sock listen.owner = hl.zeroxzed.ru listen.group = hl.zeroxzed.ru

Мы поменяли название пула, запустили его от отдельного пользователя и назначили ему отдельный сокет. Теперь идем в настройки этого виртуального хоста в nginx — /etc/nginx/conf.d/hl.zeroxzed.ru.conf и везде меняем старое значение сокета

fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;

на новое

fastcgi_pass unix:/var/run/php-fpm/hl.zeroxzed.ru.sock;

Перезапускаем nginx и php-fpm и проверяем работу сайта от отдельного пользователя.

# systemctl restart nginx # systemctl restart php-fpm

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

Ротация логов виртуальных хостов

Последний штрих в настройке web сервера — ротация логов виртуальных хостов. Если этого не сделать, то через какое-то, обычно продолжительное, время возникает проблема в связи с огромным размером лог файла.

У нас уже будет файл конфигурации logrotate для nginx, который был создан во время установки — /etc/logrotate.d/nginx. Приведем его к следующему виду:

/var/log/nginx/*log /web/sites/p1m2a.zeroxzed.ru/log/*log { create 0644 nginx nginx size=1M rotate 10 missingok notifempty compress sharedscripts postrotate /bin/kill -USR1 `cat /run/nginx.pid 2>/dev/null` 2>/dev/null || true endscript } /web/sites/hl.zeroxzed.ru/log/*log { create 0644 hl.zeroxzed.ru hl.zeroxzed.ru size=1M rotate 10 missingok notifempty compress sharedscripts postrotate /bin/kill -USR1 `cat /run/nginx.pid 2>/dev/null` 2>/dev/null || true endscript }

Я предлагаю ротировать файлы логов по достижению ими размера в 1Мб, сжимать после ротации и хранить 10 архивов с логом. Для виртуальных хостов, работающих от отдельного пользователя, новые логи создаются сразу с соответствующими правами, чтобы у пользователя был доступ к ним. Для всех остальных хостов можно использовать самое первое правило, просто добавляя туда новые пути для логов.

Это просто пример конфигурации. Все параметры вы можете поменять по своему усмотрению. Примеров конфигурации logrotate в интернете много.

На этом все. Я рассмотрел все основные моменты, которые необходимы для установки и настройки производительного web сервера на основе nginx и php-fpm последних версий. При этом рассказал о некоторых вещах, которые повышают удобство и гибкость эксплуатации сервера.

Заключение

Не понравилась статья и хочешь научить меня администрировать? Пожалуйста, я люблю учиться. Комментарии в твоем распоряжении. Расскажи, как сделать правильно!

Тема настройки веб сервера обширна. Рассмотреть все варианты в одной статье невозможно, так как функционал будет разниться, в зависимости от назначения сервера. Тем не менее приведу еще несколько ссылок на материалы, которые имеют отношение к настройке web сервера:

Если еще что-то полезное вспомню, добавлю ссылки. Пока вроде все. Жду комментариев и отзывов. Написал все по своему опыту, как я обычно настраиваю веб сервера. Возможно что-то можно сделать более удобно и правильно.

Эта статья будет первой из цикла статей по настройке современного веб сервера. Далее мы будем защищать web сервер и готовить его к максимальным нагрузкам.

Помогла статья? Есть возможность отблагодарить автора

serveradmin.ru

nginx, php-fpm, w3c и cd — Сто статей про хостинг

Сегодня мы попробуем выжать из популярного движка WordPress все соки. А для этого нам потребуются:

Кеширование выйдет трехуровневое: cdn, кеш w3, кеш nginx. Таким образом, фактически мы сохраняем только новые данные в базу через HTTP POST-запросы, а отдаем максимально кешированные страницы. Это особо полезно в тех случаях, когда на движке WordPress у вас популярный новостной сайт, куда переодически приходит масса посетителей. Главное — дать им возможность читать сайт, пускай ценой временного перевода авторизованных пользователей в анонимные. Последнее реализуется отдачей сохраненной страницы из кеша залогиненному пользователю, если его динамическая страница не была сгенерирована сервером из-за высокой нагрузки. Приступим:

Настройка php-fpm заключается в прописывании пути к unix-сокету и выставлению разумного числа дочерних процессов, кратное потока mysql. Например если вы указали для mysql 4 потока на процессор, то и число дочерних процессов надо выставить из расчета CPU * 4.

Плагин w3c помимо кеширования предоставляет еще возможность сохранять медиа-библиотеку на CDN-сервисе. Это очень полезно, напормер, если у вас множество фотографий. В таком случае все картинки загружаются на удаленный сервер, а их адреса заменяются на URL вида img.mydomain.com, где img указывает на CDN, который и отдае файлы вместо нас.

Ну а теперь самое главное, конфигурация nginx:

server { listen 80; index index.php; #set $do_not_cache 1; #Если раскомментировать эту строку, nginx перестанет кешировать все страницы для анонимных пользователей server_name mydomain.com www.mydomain.com; root /var/www/html; gzip on; gzip_disable "msie6"; gzip_vary on; gzip_proxied any; gzip_comp_level 5; gzip_buffers 16 8k; gzip_http_version 1.0; gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript image/png image/gif image/jpeg; # Обработка CSS и JS location ~* \.(css|js) { if (!-f $request_filename) { rewrite ^/wp-content/w3tc/min/(.+\.(css|js))$ /wp-content/w3tc/min/index.php?file=$1 last; } } # Сохраним url запрошенной страницы set $cache_uri $request_uri; # POST запросы не кешируются if ($request_method = POST) { set $cache_uri 'no cache'; set $do_not_cache 1; } # Динамические страницы не кешируются if ($query_string != "") { set $cache_uri 'no cache'; set $do_not_cache 1; } # Не кешируем админку, rpc, коментарии и тд. if ($request_uri ~* "(\/wp-admin\/|\/xmlrpc.php|\/wp-(app|cron|login|register|mail)\.php|wp-.*\.php|index\.php|wp\-comments\-popup\.php|wp\-links\-opml\.php|wp\-locations\.php)") { set $cache_uri "no cache"; set $do_not_cache 1; } # Не кешируем зарегистрированных пользователей if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+|wp\-postpass|wordpress_logged_in") { set $cache_uri 'no cache'; set $do_not_cache 1; } # Если страница не закеширована w3c, то отдаемся на милость WordPress location / { try_files /wp-content/w3tc/pgcache/$cache_uri/_index.html $uri $uri/ /index.php?q=$uri&$args; } # Статичный контент отдаем напрямую с диска location ~* \.(xml|ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|css|rss|atom|js|jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf)$ { try_files $uri =404; access_log off; expires 7d; } # Запрещаем доступы к .ht - файлам location ~* /\.ht { deny all; access_log off; log_not_found off; } #И наконец самое главное - обработка PHP location ~ \.php$ { fastcgi_buffers 8 256k; fastcgi_buffer_size 128k; fastcgi_intercept_errors on; include fastcgi.conf; fastcgi_pass unix:/dev/shm/php-fpm-www.sock; fastcgi_ignore_headers Set-Cookie Cache-Control Expires; fastcgi_no_cache $do_not_cache; fastcgi_cache_bypass $do_not_cache; fastcgi_cache staticfilecache; fastcgi_cache_valid 200 20m; fastcgi_cache_key "$server_addr:$server_port$request_uri"; fastcgi_cache_use_stale updating error timeout invalid_header http_500; } }

pro-100host.ru

Настройка php-fpm в шаблонизаторе ISP 5, в режиме nginx + php-fpm

Чтобы написать одно название пришлось вспотеть, так как непросто его сформулировать. Как вы поняли основная суть статьи, рассказать для вас и запомнить для себя, как настроить поддержку php-fpm в работе сайтов, если у вас установлен ISP 5 manager и вы хотите, чтобы ваши сайты правильно обрабатывались конфигурацией nginx. Тема достаточно часто поднимается в вопросах и статьях, но в итоге я не смог найти решения, которое бы просто решало этот вопрос. Я даже расскажу предисторию этого, как всё складывалось изначально у меня.

Описание проблемы с nginx + php-fpm

У меня в работе сервера, где установлены и Centos и Debian. На каждом сервере есть созданные пользователи, которые имеют выбор работать в режиме apache + nginx, или cgi +nginx, или php-fpm + nginx. В итоге получается, что при переключении на режим php-fpm сайты работают только с главной страницей, при переходе на любую внутреннюю страницу возникает ошибка 502 или 404, то есть сайт конфигурация nginx + php-fpm не обрабатывается правильно. Это была проблема номер один.

Вторая проблема появилась после того, как я со специалистами пытался решить первую. Следует понимать, что php-fpm обрабатывает php содержимое иначе и не учитывает .htaccess, поэтому в папке vhosts для site.conf под nginx необходимо добавлять обработку в виде строки: try_files $uri $uri/ /index.php?q=$uri&$args;

Однако тут снова проблема, делать это вручную неудобно, представьте например 50-100 сайтов, которые добавляются, убираются, переключаются и надо отслеживать, чтобы в каждом конфиге была строка добавлена вручную try_files $uri $uri/ /index.php?q=$uri&$args;, тем более с учетом того, что это делать может только root. Надо было решать оба вопроса.

Первые попытки решить натолкнулись на то, что специалисты заявили: Это нельзя сделать автоматически. То есть дилемма такова, что только вручную. Но повезло по мере попыток обговорить этот вопрос с одним более понятливым специалистов, который реализовал ту идею, что была в понимании как сделать. Надо было внедрить в шаблонизатор ISP строчку для подключения режиме конфига в php-fpm. Мне до сих пор непонятно, почему по сути простое решение стало для многих такой трудной задачей. И решение появилось.

Для начала заходим в папку шаблонизаторов ISP manager 5 (неважно бизнес версия у вас или Lite), например в Centos 7.3 правильная папка такая: /localhost/usr/local/mgr5/etc/templates/default/

Далее находим в этой папке файлы шаблонизаторы для настройки конфигурации nginx в папку vhosts. Там будет 2 файла: nginx-vhosts-ssl.template и nginx-vhosts.template. Разница в обработке с ssl сертификатом и без него. Вот содержимое этих файлов, после добавления try_files $uri $uri/ /index.php?q=$uri&$args;

Шаблонизатор nginx-vhosts-ssl.template

server { server_name {% $NAME %} [% $ALIASES %]; ssl on; ssl_certificate [% $SSL_CRT_BUNDLE_PATH %]; ssl_certificate_key [% $SSL_KEY_PATH %]; {% if $STRICT_SSL == on %} ssl_ciphers EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH; ssl_prefer_server_ciphers on; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; add_header Strict-Transport-Security "max-age=31536000;"; {% endif %} charset [% $CHARSET %]; {% if $DIRINDEX != "" %} index [% $DIRINDEX %]; {% endif %} disable_symlinks if_not_owner from=$root_path; include {% $NGINX_VHOST_INCLUDES %}; include {% $INCLUDE_RESOURCE_PATH %}; {% if $LOG_ACCESS == on %} access_log [% $ACCESS_LOG_PATH %]; {% elif $NO_TRAFF_COUNT == on %} access_log off; {% endif %} {% if $LOG_ERROR == on %} error_log {% $ERROR_LOG_PATH %} notice; {% else %} error_log /dev/null crit; {% endif %} {% if $SSI == on %} ssi on; {% endif %} set $root_path {% $VIRTUAL_DOCROOT %}; {% if $AUTOSUBDOMAIN != off and $AUTOSUBDOMAIN != "" %} {% if $AUTOSUBDOMAIN == autosubdomain_subdir %} set $subdomain ""; {% elif $AUTOSUBDOMAIN == autosubdomain_dir %} set $subdomain {% $AUTOSUBDOMAIN_SUBDOMAIN_PART %}; {% endif %} if ($host ~* ^((.*).{% $NAME %})$) { {% if $AUTOSUBDOMAIN == autosubdomain_dir %} set $subdomain $1; {% elif $AUTOSUBDOMAIN == autosubdomain_subdir %} set $subdomain $2; {% endif %} } root $root_path/$subdomain; {% else %} root $root_path; {% endif %} {% if $FOREGROUND == on %} listen {% $NGINX_SSL_LISTEN_ON %} default_server; {% else %} listen {% $NGINX_SSL_LISTEN_ON %}; {% endif %} {% if $USER_RESOURCES %} include {% $USER_NGINX_RESOURCES_PATH %}; {% endif %} {% if $SRV_GZIP == on %} gzip on; gzip_comp_level [% $GZIP_LEVEL %]; gzip_disable "msie6"; gzip_types [% $GZIP_TYPES %]; {% endif %} {% if $REDIRECT_TO_APACHE != on and $SRV_CACHE == on %} expires [% $EXPIRES_VALUE %]; {% endif %} location / { {% if $PHP == on %} try_files $uri $uri/ /index.php?q=$uri&$args; location ~ [^/]\.ph(p\d*|tml)$ { {% if $PHP_MODE == php_mode_fcgi_nginxfpm %} try_files /does_not_exists @php; {% else %} try_files /does_not_exists @fallback; {% endif %} } {% endif %} {% if $REDIRECT_TO_APACHE == on %} location ~* ^.+\.(jpg|jpeg|gif|png|svg|js|css|mp3|ogg|mpe?g|avi|zip|gz|bz2?|rar|swf)$ { {% if $SRV_CACHE == on %} expires [% $EXPIRES_VALUE %]; {% endif %} try_files $uri $uri/ @fallback; } location / { try_files /does_not_exists @fallback; } {% endif %} } {% if $ANALYZER != off and $ANALYZER != "" %} location {% $WEBSTAT_LOCATION %} { charset [% $WEBSTAT_ENCODING %]; index index.html; {% if $PHP == on %} location ~ [^/]\.ph(p\d*|tml)$ { {% if $PHP_MODE == php_mode_fcgi_nginxfpm %} try_files /does_not_exists @php; {% else %} try_files /does_not_exists @fallback; {% endif %} } {% endif %} {% if $REDIRECT_TO_APACHE == on %} location ~* ^.+\.(jpg|jpeg|gif|png|svg|js|css|mp3|ogg|mpe?g|avi|zip|gz|bz2?|rar|swf)$ { {% if $SRV_CACHE == on %} expires [% $EXPIRES_VALUE %]; {% endif %} try_files $uri $uri/ @fallback; } location {% $WEBSTAT_LOCATION %} { try_files /does_not_exists @fallback; } {% endif %} } {% endif %} {% if $REDIRECT_TO_APACHE == on %} location @fallback { proxy_pass {% $BACKEND_BIND_URI %}; proxy_redirect {% $BACKEND_BIND_URI %} /; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; {% if $NO_TRAFF_COUNT == on %} access_log off; {% endif %} } {% endif %} {% if $REDIRECT_TO_PHPFPM == on %} location @php { fastcgi_index index.php; fastcgi_param PHP_ADMIN_VALUE "sendmail_path = /usr/sbin/sendmail -t -i -f {% $EMAIL %}"; fastcgi_pass {% $PHPFPM_USER_SOCKET_PATH %}; fastcgi_split_path_info ^((?U).+\.ph(?:p\d*|tml))(/?.+)$; try_files $uri =404; include fastcgi_params; } {% endif %} }

Шаблонизатор nginx  – nginx-vhosts.template

server { server_name {% $NAME %} [% $ALIASES %]; charset [% $CHARSET %];{% if $DIRINDEX != "" %} index [% $DIRINDEX %];{% endif %} disable_symlinks if_not_owner from=$root_path; include {% $NGINX_VHOST_INCLUDES %}; include {% $INCLUDE_RESOURCE_PATH %};{% if $LOG_ACCESS == on %} access_log [% $ACCESS_LOG_PATH %];{% elif $NO_TRAFF_COUNT == on %} access_log off;{% endif %}{% if $LOG_ERROR == on %} error_log {% $ERROR_LOG_PATH %} notice;{% else %} error_log /dev/null crit;{% endif %}{% if $SSI == on %} ssi on;{% endif %}{% if $REDIRECT_HTTP == on %} return 301 https://$host:{% $SSL_PORT %}$request_uri;{% endif %} set $root_path {% $VIRTUAL_DOCROOT %};{% if $AUTOSUBDOMAIN != off and $AUTOSUBDOMAIN != "" %}{% if $AUTOSUBDOMAIN == autosubdomain_subdir %} set $subdomain "";{% elif $AUTOSUBDOMAIN == autosubdomain_dir %} set $subdomain {% $AUTOSUBDOMAIN_SUBDOMAIN_PART %};{% endif %} if ($host ~* ^((.*).{% $NAME %})$) {{% if $AUTOSUBDOMAIN == autosubdomain_dir %} set $subdomain $1;{% elif $AUTOSUBDOMAIN == autosubdomain_subdir %} set $subdomain $2;{% endif %} } root $root_path/$subdomain;{% else %} root $root_path;{% endif %}{% if $FOREGROUND == on %} listen {% $NGINX_LISTEN_ON %} default_server;{% else %} listen {% $NGINX_LISTEN_ON %};{% endif %}{% if $USER_RESOURCES %} include {% $USER_NGINX_RESOURCES_PATH %};{% endif %}{% if $SRV_GZIP == on %} gzip on; gzip_comp_level [% $GZIP_LEVEL %]; gzip_disable "msie6"; gzip_types [% $GZIP_TYPES %];{% endif %}{% if $REDIRECT_TO_APACHE != on and $SRV_CACHE == on %} expires [% $EXPIRES_VALUE %];{% endif %} location / {{% if $PHP == on %}try_files $uri $uri/ /index.php?q=$uri&$args; location ~ [^/]\.ph(p\d*|tml)$ {{% if $PHP_MODE == php_mode_fcgi_nginxfpm %} try_files /does_not_exists @php;{% else %} try_files /does_not_exists @fallback;{% endif %} }{% endif %}{% if $REDIRECT_TO_APACHE == on %} location ~* ^.+\.(jpg|jpeg|gif|png|svg|js|css|mp3|ogg|mpe?g|avi|zip|gz|bz2?|rar|swf)$ {{% if $SRV_CACHE == on %} expires [% $EXPIRES_VALUE %];{% endif %} try_files $uri $uri/ @fallback; } location / { try_files /does_not_exists @fallback; }{% endif %} }{% if $ANALYZER != off and $ANALYZER != "" %} location {% $WEBSTAT_LOCATION %} { charset [% $WEBSTAT_ENCODING %]; index index.html;{% if $PHP == on %} location ~ [^/]\.ph(p\d*|tml)$ {{% if $PHP_MODE == php_mode_fcgi_nginxfpm %} try_files /does_not_exists @php;{% else %} try_files /does_not_exists @fallback;{% endif %} }{% endif %}{% if $REDIRECT_TO_APACHE == on %} location ~* ^.+\.(jpg|jpeg|gif|png|svg|js|css|mp3|ogg|mpe?g|avi|zip|gz|bz2?|rar|swf)$ {{% if $SRV_CACHE == on %} expires [% $EXPIRES_VALUE %];{% endif %} try_files $uri $uri/ @fallback; } location {% $WEBSTAT_LOCATION %} { try_files /does_not_exists @fallback; }{% endif %} }{% endif %}{% if $REDIRECT_TO_APACHE == on %} location @fallback { proxy_pass {% $BACKEND_BIND_URI %}; proxy_redirect {% $BACKEND_BIND_URI %} /; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme;{% if $NO_TRAFF_COUNT == on %} access_log off;{% endif %} }{% endif %}{% if $REDIRECT_TO_PHPFPM == on %} location @php { fastcgi_index index.php; fastcgi_param PHP_ADMIN_VALUE "sendmail_path = /usr/sbin/sendmail -t -i -f {% $EMAIL %}"; fastcgi_pass {% $PHPFPM_USER_SOCKET_PATH %}; fastcgi_split_path_info ^((?U).+\.ph(?:p\d*|tml))(/?.+)$; try_files $uri =404; include fastcgi_params; }{% endif %}}{% if $SSL == on %}{% import etc/templates/default/nginx-vhosts-ssl.template %}{% endif %}

Строка была добавлена перед обработкой php то есть тут:

{% if $PHP == on %}try_files $uri $uri/ /index.php?q=$uri&$args; location ~ [^/]\.ph(p\d*|tml)$ {

После этого сохраняем, делаем рестарт и проверяем. Для проверки я переключаю сайт на php-fpm и вижу что всё работает прекрасно.

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

1. Работоспособность сайта при переключении в режим php-fpm в ISP 5 2. Автоматическая генерация правильного site.conf nginx при работе с доменом в режиме php-fpm

Обе задачи были решены. Надеюсь и вам этот способ пригодится. Да и скорость работы гораздо выше чем на apache или cgi.

ok2web.ru

Переводим сайты WordPress на LEMP (Linux + Nginx + MySQL + php-fpm) — Sm0k3.Net

web-hosting-linux-nginx-wordpress

Появилось время на оптимизацию своего зоопарка, крутилось всё уже несколько лет на Debian 6 и 7, Apache2, MySQL и т.д. Хотя всем и советовал сразу уходить на Nginx, старые проектики всё никак не мог перевести и оптимизировать.

Работать будем в DigitalOcean на стеке LEMP с минимальным дроплетом за 5$ на 1GB RAM + 1xCORE + 25GB SSD, оптимизировать скорость будем за счет сжатия в Nginx, кеширования в Memcached и в некоторых случаях можно применить CloudFlare в качестве дополнительного кеша и CDN.

Первым делом нужно создать виртуальный сервер (он же droplet) с ОС Debian 9 Stretch

create-droplet

Регион можете выбрать на свое усмотрение, я с учетом моего географического положения (Беларусь) посчитал, что наиоблее оптимальным будет Германия. Из дополнительных опция нам могут пригодиться Private networking и Monitoring, а аутентификацию лучше всего настраивать по ключу (ключ можете сделать с помощью PuTTY Gen). На финальном этапе задаем название для нашего дроплета, жмем кнопку создать и выжидаем порядка минуты (если аутентификация по ключу — письмо о том, что создан дроплет на почту не пришлют).

Заходим на наш дроплет и первым делом обновляемся:

$ apt-get update -y && apt-get upgrade -y

Далее, сразу ставим разные полезные мелочи, которые могут на понадобиться:

$ apt-get install htop nano mc zip unzip

Для загрузки файлов на сервер мы можем использовать либо wget если речь о скачивании из интернета, либо качаем к себе WinSCP и работаем по SFTP для загрузки файлов с компьютера. FTP мы использовать не будем по нескольким причинам: это не безопасно, это дополнительные группы и пользователи, обновлять еще один компонент, лишний открытый порт у нас на сервере.

Теперь приступим к установке нашего стека по шагам и начнем пожалуй с nginx:

$ apt-get install nginx -y

Далее настроим наш веб-сервер:

$ nano /etc/nginx/nginx.conf

Выставим следующие параметры:

Пользователя оставляем «www-data» — с наименьшими привилегиями;

«worker_processes auto;» — можно так же оставить «auto» т.к. 1 у нас все равно одно ядро и особого смысла трогать его нет.

Далее, в events оставляем все как есть:

events { worker_connections 768; # multi_accept on; }

В настройках сжати gzip немного корректируем параметры и включаем сжатие для статики:

## # Gzip Settings ## gzip on; gzip_disable "msie6"; gzip_vary on; gzip_proxied any; gzip_comp_level 6; gzip_buffers 16 8k; gzip_http_version 1.1; gzip_min_length 256; gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript application/vnd.ms-fontobject application/x-font-ttf font/opentype image/svg+xml image/x-icon;

 

В нашем случае выставлять уровень сжатия более 6 не стоит т.к. при максимальном параметре «gzip_comp_level 9» мощностей потребляется больше, а каких-то кардинальных отличий вы не заметите.

Далее нам нужно создать снипет по пути «/etc/nginx/snippets/ssl-params.conf» в котороым мы пропишем некоторые настройки для SSL на нашем сервере:

ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_prefer_server_ciphers on; ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH"; ssl_ecdh_curve secp384r1; ssl_session_cache shared:SSL:10m; ssl_session_tickets off; ssl_stapling on; ssl_stapling_verify on; resolver 8.8.8.8 8.8.4.4 valid=300s; resolver_timeout 5s; add_header Strict-Transport-Security "max-age=63072000"; add_header X-Frame-Options DENY; add_header X-Content-Type-Options nosniff;

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

Далее в конфигурационных файлах наших сайтов мы будем использовать наш заранее заготовленный снипет.

Теперь можно доставить всё остальное:

$ apt-get install php7-fpm php7.0-mysql mysql-server memcached monit certbot sendmail

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

Для начала давайте спрячем наш SSH, изменим порт на что-то, менее стандартное:

$ nano /etc/ssh/sshd_config

Раскоментируем параметр порт и выставим к примеру 2222 (выбирайте любой порт на свое усмотрение, главное чтобы оно не конфликтовало с другими сервисами). Меняем настройку, сохраняем и выходим из файлика конфигурации, рестартуем службу:

$ service ssh restart

Переходим в веб-интерфейс DigitalOcean и в нем активируем приложения файрвола, а так же вносим некоторые корректировки (в веб панели заходим в Networking -> Firewalls):

digitalocean-firewall

На файрволе блокируем все (следуем примеру Amazon) и открываем только нужные нам порты. Как бонус, можно заблокировать еще ICMP и тогда ваш сервер перестанет пинговаться. С одной стороны удобно, немного улучшим защиту от мелких хулиганов, с другой — не совсем понятно, как это может сказаться на SEO оптимизации, по этому лучше не будем рисковать и разрешим ICMP, при надобности отключим если что.

Теперь добиваем наш мониторинг, заходим в Monitoring и создаем там «Alert policy»:

digitalocean-monitoring-alert-policy

Т.к. у нас самый простой и относительно слабенький дроплет, я выставил планку оповещения на 90%, потому что при большом наплыве людей на сайты, загруза будет существенной для ресурса в 1гб памяти и одного ядра.

Да, чуть не забыл, для нас еще актуально создать раздел swap который в трудный момент может нас слегка выручить, создается он выполненим следующих команд:

$ fallocate -l 2G /swap $ chmod 600 /swap $ mkswap /swap $ swapon /swap $ nano /etc/fstab В самом конце файла добавляем строку: /swap none swap sw 0 0

Swap мы сделали на 2GB исходя из объема нашей оперативной памяти (RAM*2). Последней командой мы добавили заставили систему подгружать наш файл подкачки автоматически (удобно при перезагрузках).

Базовый файрвол настроили, минимальный мониторинг загруженности теперь у нас тоже есть, swap добавили, теперь добиваем настройку WordPress, nginx и php с mysql.

Сразу выполним безопасную настройку базы данных с командой «mysql_secure_installation», ну а дальше сделаем для БД себе нового пользователя:

$ mysql -u root -p<ВашПароль> CREATE USER 'user'@'localhost' IDENTIFIED BY 'password'; GRANT ALL PRIVILEGES ON *.* TO 'user'@'localhost'; FLUSH PRIVILEGES;

Посл того, как пользователя добавили и все безопасно настроили, ставим phpMyAdmin:

$ apt-get install phpmyadmin -y

Далее в /etc/nginx/sites-available/default добавляем наш будущий путь к phpmyadmin ну и создаем линк к папке с файлами админки по нужному пути (пускай путь будет myadm):

$ nano /etc/nginx/sites-available/default

Добавляем в «server { … }»:

location /myadm { index index.html index.php; auth_basic "Password protected"; auth_basic_user_file /usr/share/phpmyadmin/password; }

Генерируем пароль для нашей аутентификации:

$ openssl passwd

В примере это «auth_basic_user_file /usr/share/phpmyadmin/password» файл, с пользователем и паролем, у себя можете делать так, как вам будет удобнее и звучнее. После того, как в nginx мы путь уже указали, создаем линк до нашей админки:

ln -s /usr/share/phpmyadmin/ /var/www/html/myadm

Дело остается за малым, донастроить кеш и вордпресс, а так же сказать серверу где лежит наш сайт:

$ cp /etc/nginx/sites-available/default /etc/nginx/sites-available/new_websites.conf $ nano /etc/nginx/sites-available/new_websites.conf

Конфигурацию как видно, мы скопировали из файла по умолчанию и просто внесем несколько корректировок с учетом того, что мы будем использовать SSL, а значит нам понадобится правильный редирект (перенаправление с HTTP на HTTPS), а так же путь до сертификата которого еще нет.

Добавляем нужные нам строки:

server { #Указываем редирект с HTTP на HTTPS listen 80; server_name newwebsite.com www.newwebsite.com; return 302 https://$server_name$request_uri; } server { #Заставляем наш сайт работать на 443 порту по HTTPS listen 443; listen [::]:443; server_name newwebsite.com www.newwebsite.com; #Подгружаем наш снипт с настройками для SSL include snippets/ssl-params.conf; #Включаем SSL и указываем путь к сертификатам нашего сайта ssl on; ssl_certificate /etc/letsencrypt/live/newwebsites.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/newwebsite.com/privkey.pem; #Указываем путь к корневому каталогу нашего сайта root /var/www/html/newwebsite/www; location / { #Учим WordPress работе с красивыми ссылками index index.html index.php; try_files $uri $uri/ /index.php?$args; } location ~ \.php$ { include snippets/fastcgi-php.conf; fastcgi_pass unix:/var/run/php/php7.0-fpm.sock; } location ~ /\.ht { #Запрещаем прямой доступ к файлам конфигурации deny all; } }

Старые строки если мешают можно удалить или закоментировать, либо как вариант — подкорректировать старый конфигурационный файл который мы скорпировали (default). Что к чему в файле конфигурации, можно посмотреть по комментариям из выше приведенного примера.

Правим наш php-fpm:

$ nano /etc/php/7.0/fpm/php.ini

Выставляем параметр cgi.fix_pathinfo = 1 выставляем значение 0 (ноль).  Эти настройки по умолчанию очень небезопасны, потому что благодаря им PHP попытается исполнить ближайший файл, который сможет найти в случае, когда запрашиваемый PHP файл не может быть найден.

Выпускаем для нашего сайта сертификат:

certbot certonly

И далее выполняем шаг за шагом все пункты из интерактивного меню, по окончании у вас в /etc/letsencrypt/live/ должны появиться папки с названием сайтов и сертификатами внутри.

Рестартуем службу ngix и php-fpm:

$ service nginx restart $ service php-fpm restart

WordPress качаем с официального сайта, последнюю версию или если у вас есть сайт, то переносим его к нам на хостинг через SFTP (описано выше). Учтите, что мы работаем с php-fpm версии 7.0, если у вас WordPress был более старой версии и вы его не обновляли, то прдется пойти еще на один маневр:

  1. Бекапируем корень сайта без папок, а так же все в: /wp-admin/ и /wp-includes/
  2. Качаем последнюю версию дистрибутива WordPress и из нее заливаем более свежие файлы в /wp-admin и /wp-includes соответственно, а так же обновляем наш корень сайта, /wp-content/ и файл wp-config.php не трогаем.
  3. Заходим на наш сайт и обновляем нашу БД

Если всё прошло отлично, значит вы уже можете зайти к себе на сайт и поставить плагин «W3 Total Cache».

В последних версиях Debian пакет memcached для кеширования ставился из коробки правильно, но если вдруг что-то пошло не так, то параметры должны быть выставлены следующим образом в файле «/etc/memcached.conf»:

-d -m 64 -p 11211  -u memcache -l 127.0.0.1

Работаем на localhost из под пользователя «memcache». Рестартуем наш сервис: «service memcached restart».

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

$ nano /etc/monit/monitrc

Активируем отправку по почту оповещений, ищем и редактируем:

set mail-format { from: alert@srv-websites-1 } - от кого будет отправлено сообщение set alert [email protected]   - кому будет отправлено сообщение

Сохраняем и закрываем, добавляем следующие шаблоны для интересующих нас сервисов nginx, mysql, memcached в файлики с соответствующими названиями в папке «/etc/monit/conf-available/»:

# Nginx check process nginx with pidfile /run/nginx.pid start program = "/etc/init.d/nginx start" stop program = "/etc/init.d/nginx stop" if failed host 127.0.0.1 port 80 then restart if cpu > 75% for 2 cycles then alert if cpu > 95% for 5 cycles then restart if 10 restarts within 10 cycles then timeout # MySQL check process mysqld with pidfile /run/mysqld/mysqld.pid group database start program = "/etc/init.d/mysql start" stop program = "/etc/init.d/mysql stop" if failed host 127.0.0.1 port 3306 then restart if cpu > 90% for 3 cycles then alert if 5 restarts within 5 cycles then timeout # Memcached check process memcached matching "memcached" start program = "/etc/init.d/memcached start" stop program = "/etc/init.d/memcached stop" if failed host 127.0.0.1 port 11211 then restart if cpu > 75% for 2 cycles then alert if cpu > 98% for 5 cycles then restart if 2 restarts within 3 cycles then timeout

Когда закончили с файликами конфигурации, линукем их в активные и рестартуем monit:

ln -s /etc/monit/conf-available/nginx /etc/monit/conf-enabled/

Так проделываем со всеми нужными файлами конфигурации и далее:

$ service monit restart

monit-monitoring

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

На завершающем этапе нам остается лишь настроить плагин кеширования вордпресс W3 Total Cache. Активируем плагин, заходим в настройки и включаем все возможные опции кеширования, а в доступных вариантах в выпадающем меню выбираем «Memcached».

Если вдруг возникли проблемы на этапе скачивания и инсталяции плагина WordPress, то стоит обратить внимание на права выставленные на папки и соответственно кому они принадлежат. В идеале это пользователь www-data из такой же группы, и права на папку «/wp-content/uploads» на запись (777):

$ chown -R www-data:www-data /var/www/html/newwebsites/www $ chmod -R 777 /var/www/html/newwebsites/www/wp-content/uploads/

Команды выше меняют группу и выставляют права рекурсивно, т.е. проходятся по всем папкам ниже.

wordpress-memcached

Кеширование это с одной стороны друг, с другой может создать некоторые проблемы. Для административных нужд кеширование лучше отключить, данные опции доступны в этом плагине. Заходим в «Page Cache»  и отключаем кеш для администратора и на главной странице при добавлении контента:

dont-cache-w3-total-cache-1

Для главной:

dont-cache-w3-total-cache-2

При небольших нагрузках данный сервер сможет поддерживать до 5 сайтов. В случае, если вдруг нагрузка начнет расти (а это рано или поздно случится), первым делом мы можем попробовать довесить до кучи еще CloudFlare, если это не поможет — то добавить для нашего сервера ресурсов (на DigitalOcean можно добавлять ресурсы на лету) и немного еще увеличить степень сжатия.

Если не полениться и разобраться с сервисом Zapier, то можно делать снапшоты в автоматическом режиме через API DigitalOcean в режиме бекапов и бесплатно (по расписанию).

zapier-digitalocean-snapshot

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

Может быть интересно:

sm0k3.net

Советы по настройке и оптимизации Nginx и PHP-FPM — PEKTOP

От переводчика:Речь пойдет о тонкостях настройки связки Nginx + PHP-FPM в виде небольшого сборника советов. Перевод вольный. Ориентированно на пользователей Linux.

Советы по настройке и оптимизации Nginx

Совет №1 — Организация файлов конфигурации Nginx

Обычно файлы конфигурации Nginx хранятся в /etc/nginx.

Один из удобных способов организации файлов конфигурации в стиле Debian/Ubuntu Apache:

## Главный файл конфигурации /etc/nginx/nginx.conf ## Файлы конфигурации вируальных хостов (virtualhost) ## /etc/nginx/sites-available/ /etc/nginx/sites-enabled/ ## Другие файлы конфигурации (если необходимы) ## /etc/nginx/conf.d/

## Главный файл конфигурации

/etc/nginx/nginx.conf

 

## Файлы конфигурации вируальных хостов (virtualhost) ##

/etc/nginx/sites-available/

/etc/nginx/sites-enabled/

 

## Другие файлы конфигурации (если необходимы) ##

/etc/nginx/conf.d/

Файлы виртуальных хостов разделены на две директории. Директория sites-available может содержать любые файлы: тестовые, старые конфиги, копии конфигов и прочие. А директория sites-enabled содержит только реально работающие конфигурации, в действительности являющиеся только символическими ссылками на файлы в директории sites-available.

Не забудьте добавить следующие строки в файл nginx.conf:

## Загрузка файлов конфигарации виртуальных хостов ## include /etc/nginx/sites-enabled/*; ## Загрузка других конфигов из conf.d/ ## include /etc/nginx/conf.d/*;

## Загрузка файлов конфигарации виртуальных хостов ##

include /etc/nginx/sites-enabled/*;

 

## Загрузка других конфигов из conf.d/ ##

include /etc/nginx/conf.d/*;

Совет №2 — Определить Nginx worker_processes и worker_connections

Настройки по умолчанию  хороши, но их стоит немного оптимизировать: max_clients = worker_processes * worker_connections.

Базовые настройки Nginx могут обрабатывать сотни одновременных соединений:

worker_processes 1; worker_connections 1024;

worker_processes 1;

worker_connections 1024;

Обычно 1000 одновременных соединений на один сервер это хорошо, но порою другие части, например жесткий диск могут оказаться медленными и это приведет к тому, что Nginx будет заблокирован на операции ввода-вывода (I/O). Чтобы избежать блокировки используйте, например, следующие настройки: одни worker_process на ядро процессора:

Worker Processes

worker_processes = [число ядер процессора];

worker_processes = [число ядер процессора];

Чтобы определить сколько ядер имеет ваш процессор, введите:

$ cat /proc/cpuinfo | grep processor processor : 0 processor : 1 processor : 2 processor : 3

$ cat /proc/cpuinfo | grep processor

processor   : 0

processor   : 1

processor   : 2

processor   : 3

В данном случае у меня четыре ядра, поэтому окончательный парамерт worker_processes устанавливаем как 4:

Worker Connections

Лично я придерживаюсь 1024 соединений на один воркер, потому что у меня нет никаких оснований для повышения этого значения. Но если например 4096 соединений в секунду не хватает, то можно попробовать удвоить 2048 соединений на процесс.

Окончательные настройки выглядят седующим образом:

Совет №3 — Скрыть токены Nginx / Скрыть номер версии Nginx

Это хорошо из соображений безопасности — скрыть токены Nginx и скрыть номер версии Nginx, тем более если вы используете устаревшую версию Nginx. Это очень легко сделать — достаточно добавить в секцию http/server/location файла конфигурации следующую строку:

Совет №4 — Ограничение на размер передаваемых данных сервером Nginx

Если вы хотите разрешить пользователям загружать файлы, то вы должны увеличить размер сообщения. Это может быть сделано с помощью значения client_max_body_size, которое находится в секции http/server/location файла конфигурации. По умолчанию он равен 1 Мб, но его можно увеличить, например, до 20 Мб, а также увеличить размер буфера:

client_max_body_size 20m; client_body_buffer_size 128k;

client_max_body_size 20m;

client_body_buffer_size 128k;

Если вы получаете сообщение об ошибке, то вы знаете, что client_max_body_size слишком мало:

«Request Entity Too Large» (413)

Совет №5 — Управление кешем для статических файлов

Кэш браузера сохранит ресурсы и пропускную способность вашего сервера. Это несложная настройка Nginx позволит выключить ведение логов (access log и not found log), и установить срок истечения заголовка в 360 дней.

location ~* \.(jpg|jpeg|gif|png|css|js|ico|xml)$ { access_log off; log_not_found off; expires 360d; }

location ~* \.(jpg|jpeg|gif|png|css|js|ico|xml)$ {

    access_log        off;

    log_not_found     off;

    expires           360d;

}

Если вы хотите более сложный заголовки или другие типы файлов, то вы можете настроить их отдельно.

Совет №6 — Проксируйте PHP запросы к PHP-FPM

Вы можете использовать по умолчанию стек tcp/ip или соединение через Unix-сокет. Также необходимо установить PHP-FPM слушать точно такой же ip:port или Unix-сокет. Вот очень простой пример конфигурации (вариант с Unix-сокетом  закоментирован):

# Pass PHP scripts to PHP-FPM location ~* \.php$ { fastcgi_index index.php; fastcgi_pass 127.0.0.1:9000; #fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param SCRIPT_NAME $fastcgi_script_name; }

# Pass PHP scripts to PHP-FPM

location ~* \.php$ {

    fastcgi_index   index.php;

    fastcgi_pass    127.0.0.1:9000;

    #fastcgi_pass   unix:/var/run/php-fpm/php-fpm.sock;

    include         fastcgi_params;

    fastcgi_param   SCRIPT_FILENAME    $document_root$fastcgi_script_name;

    fastcgi_param   SCRIPT_NAME        $fastcgi_script_name;

}

Это дает возможность запуска PHP-FPM другим сервером.

Совет №7 — Предотвращение (запрет) доступа к скрытым файлам

Это очень распространено, когда корень сервера или другие публичные каталоги имеют скрытые файлы, которые начинаются с точки (.) И, как правило, они не предназначены для пользователей сайта. Публичный каталог может содержать файлы системы контроля версий: .git, .svn; файлы IDE: .idea; .htaccess файлы. Настройки запещают доступ к скрытым файлам и отключают ведение логов:

location ~ /\. { access_log off; log_not_found off; deny all; }

location ~ /\. {

    access_log off;

    log_not_found off;

    deny all;

}

 Советы по настройке и оптимизации PHP-FPM

Совет №1 — Файлы конфигурации PHP-FPM

Обычно конфигурации PHP-FPM расположенны в файле /etc/php-fpm.conf и в каталоге /etc/php-fpm.d/. Весь пулл конфигов расопложен в дикертории /etc/php-fpm.d/. Чтобы это работало, вы должны добавить следующую строку в php-fpm.conf:

include=/etc/php-fpm.d/*.conf

include=/etc/php-fpm.d/*.conf

Совет №2 — Глобальная конфигурация PHP-FPM

Настройки emergency_restart_threshold, emergency_restart_interval и process_control_timeout по умолчанию выключены, но я считаю что их стоит влючить, например, со следующими значениями:

emergency_restart_threshold 10 emergency_restart_interval 1m process_control_timeout 10s

emergency_restart_threshold 10

emergency_restart_interval 1m

process_control_timeout 10s

Что это значит? Если 10 дочерних процессов PHP-FPM завершатся с помощью SIGSEGV или SIGBUS в течении 1 минуты, то PHP-FPM перезагрузится автоматически. А также дочерним процессам  установлен лимит времени реакции в 10 секунд на сигнал от мастера.

Совет №3 — Конфигурация пулов PHP-FPM

В PHP-FPM возможно использовать отденьные пулы для каждого сайта и точно распределять ресурсы, а также использовать разных пользователей и разные группы для каждого пула. Приведем примеры конфигураци трех различнх сайтов (или фактически три части одного сайта):

/etc/php-fpm.d/site.conf/etc/php-fpm.d/blog.conf/etc/php-fpm.d/forums.conf

Примеры конфигурации каждого пула:/etc/php-fpm.d/site.conf

[site] listen = 127.0.0.1:9000 user = site group = site request_slowlog_timeout = 5s slowlog = /var/log/php-fpm/slowlog-site.log listen.allowed_clients = 127.0.0.1 pm = dynamic pm.max_children = 5 pm.start_servers = 3 pm.min_spare_servers = 2 pm.max_spare_servers = 4 pm.max_requests = 200 listen.backlog = -1 pm.status_path = /status request_terminate_timeout = 120s rlimit_files = 131072 rlimit_core = unlimited catch_workers_output = yes env[HOSTNAME] = $HOSTNAME env[TMP] = /tmp env[TMPDIR] = /tmp env[TEMP] = /tmp

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

[site]

listen = 127.0.0.1:9000

user = site

group = site

request_slowlog_timeout = 5s

slowlog = /var/log/php-fpm/slowlog-site.log

listen.allowed_clients = 127.0.0.1

pm = dynamic

pm.max_children = 5

pm.start_servers = 3

pm.min_spare_servers = 2

pm.max_spare_servers = 4

pm.max_requests = 200

listen.backlog = -1

pm.status_path = /status

request_terminate_timeout = 120s

rlimit_files = 131072

rlimit_core = unlimited

catch_workers_output = yes

env[HOSTNAME] = $HOSTNAME

env[TMP] = /tmp

env[TMPDIR] = /tmp

env[TEMP] = /tmp

/etc/php-fpm.d/blog.conf

[blog] listen = 127.0.0.1:9001 user = blog group = blog request_slowlog_timeout = 5s slowlog = /var/log/php-fpm/slowlog-blog.log listen.allowed_clients = 127.0.0.1 pm = dynamic pm.max_children = 4 pm.start_servers = 2 pm.min_spare_servers = 1 pm.max_spare_servers = 3 pm.max_requests = 200 listen.backlog = -1 pm.status_path = /status request_terminate_timeout = 120s rlimit_files = 131072 rlimit_core = unlimited catch_workers_output = yes env[HOSTNAME] = $HOSTNAME env[TMP] = /tmp env[TMPDIR] = /tmp env[TEMP] = /tmp

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

[blog]

listen = 127.0.0.1:9001

user = blog

group = blog

request_slowlog_timeout = 5s

slowlog = /var/log/php-fpm/slowlog-blog.log

listen.allowed_clients = 127.0.0.1

pm = dynamic

pm.max_children = 4

pm.start_servers = 2

pm.min_spare_servers = 1

pm.max_spare_servers = 3

pm.max_requests = 200

listen.backlog = -1

pm.status_path = /status

request_terminate_timeout = 120s

rlimit_files = 131072

rlimit_core = unlimited

catch_workers_output = yes

env[HOSTNAME] = $HOSTNAME

env[TMP] = /tmp

env[TMPDIR] = /tmp

env[TEMP] = /tmp

/etc/php-fpm.d/forums.conf

[forums] listen = 127.0.0.1:9002 user = forums group = forums request_slowlog_timeout = 5s slowlog = /var/log/php-fpm/slowlog-forums.log listen.allowed_clients = 127.0.0.1 pm = dynamic pm.max_children = 10 pm.start_servers = 3 pm.min_spare_servers = 2 pm.max_spare_servers = 4 pm.max_requests = 400 listen.backlog = -1 pm.status_path = /status request_terminate_timeout = 120s rlimit_files = 131072 rlimit_core = unlimited catch_workers_output = yes env[HOSTNAME] = $HOSTNAME env[TMP] = /tmp env[TMPDIR] = /tmp env[TEMP] = /tmp

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

[forums]

listen = 127.0.0.1:9002

user = forums

group = forums

request_slowlog_timeout = 5s

slowlog = /var/log/php-fpm/slowlog-forums.log

listen.allowed_clients = 127.0.0.1

pm = dynamic

pm.max_children = 10

pm.start_servers = 3

pm.min_spare_servers = 2

pm.max_spare_servers = 4

pm.max_requests = 400

listen.backlog = -1

pm.status_path = /status

request_terminate_timeout = 120s

rlimit_files = 131072

rlimit_core = unlimited

catch_workers_output = yes

env[HOSTNAME] = $HOSTNAME

env[TMP] = /tmp

env[TMPDIR] = /tmp

env[TEMP] = /tmp

Это просто примеры как настроить несколько различных пулов.

Совет №4 — Конфигурация менеджера процессов (Pool Process Manager) PHP-FPM

Лучший способ использовать менеджер процессов PHP-FPM — это донамическое управление процессами, поэтому PHP-FPM запускает процессы только при необходимости. Это почти такой же подход как в Nginx с параметрами worker_processes и worker_connections. Таким образом большие значения не обеспечивают хорошего результата. Каждый процесс ест определнное количество памяти и, конечно, если у сайта очень большой трафик  и много оперативной памяти на сервере, то высокие значения — это правильный выбор. Но такие серверы как VPS обычно имеют ограниченное количество памяти: 256 Мб, 512 Мб, 1024 Мб. Такого небольшого объема ОЗУ достаточно даже для очень большого трафика (даже десятки запросов в секунду), если эту память использовать с умом.

Проверим сколько процессов PHP-FPM позволит легко справляться серверу с нагрузкой. Сначала запустим Nginx и PHP-FPM и загрузим несколько страниц PHP, желательно самые тяжелые. Затем проверим сколько использует памяти процесс PHP-FPM — в Linux можно воспользоваться утилитами top или htop. Предположим что наш сервер имеет 512 Мб оперативной памяти и 220 Мб может быть использованно PHP-FPM, каждый процесс использует 24 Мб оператичной памяти (некоторые CMS с плагинами могут легко кушать 20-40 Мб на один запрос или даже больше). Затем просто вычислим значние max_children для сервера:

220 / 24 = 9.17

Приемлемым значнием pm.max_children будет 9. Это значние основанно на среднем значении и возможно далее его необходимо будет изменить, когда вы заметите длительное время использования памяти процессом. После быстрого тестирования несложно выбрать значния pm.start_servers value, pm.min_spare_servers и pm.max_spare_servers.

Окончательная конфигурация нашего примера может выглядеть следующим образом:

pm.max_children = 9 pm.start_servers = 3 pm.min_spare_servers = 2 pm.max_spare_servers = 4 pm.max_requests = 200

pm.max_children = 9

pm.start_servers = 3

pm.min_spare_servers = 2

pm.max_spare_servers = 4

pm.max_requests = 200

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

У вас проблемы с натройкой Nginx или PHP-FPM или есть еще советы?

Не стесняйтеся писать замечания, вопросы и советы в комментариях.

Оригинальный пост на английском языке

pektop.net

Установка nginx+php7-fpm

Ставим nginx

echo "deb https://nginx.org/packages/mainline/ubuntu/ `lsb_release -cs` nginx" &gt;&gt; /etc/apt/sources.list

echo "deb-src https://nginx.org/packages/mainline/ubuntu/ `lsb_release -cs` nginx"  &gt;&gt; /etc/apt/sources.list

curl https://nginx.org/keys/nginx_signing.key | apt-key add -

sudo apt-get update

sudo apt-get install nginx

Ставим php

apt-get install php-cli php-common php-mysql php-gd php-fpm php-cgi php-fpm php-pear php-mcrypt

Настройка

Редактируем файл /etc/nginx

Меняем пользователя на www-data

Редактируем php

sudo nano /etc/php/7.0/fpm/php.ini

Делаем так, не тупим

Здесь

sudo nano /etc/php/7.0/fpm/pool.d/www.conf

делаем так

 

#listen = /run/php/php7.0-fpm.sock

listen = 127.0.0.1:9000

 

Редактим конфиг

sudo nano /etc/nginx/conf.d/default.conf

Вставляем код

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

server {

        listen   80;

 

        root /var/www;

        index index.php index.html index.htm;

        server_name  example.com www.example.com;

 

        location / {

                try_files $uri $uri/ /index.html;

        }

 

        error_page 404 /404.html;

        error_page 500 502 503 504 /50x.html;

        location = /50x.html {

              root /usr/share/nginx/www;

        }

 

        location ~ .php$ {

                try_files $uri =404;

                fastcgi_pass 127.0.0.1:9000;

                fastcgi_index index.php;

                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

                include fastcgi_params;

        }

}

 

Вот еще конфиг, на всякий случай,/etc/nginx/nginx.conf

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

user  www-data;

worker_processes  2;

 

error_log  /var/log/nginx/error.log warn;

pid        /var/run/nginx.pid;

 

 

events {

    worker_connections  1024;

}

 

 

http {

    include       /etc/nginx/mime.types;

    default_type  application/octet-stream;

 

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '

                      '$status $body_bytes_sent "$http_referer" '

                      '"$http_user_agent" "$http_x_forwarded_for"';

 

    access_log  /var/log/nginx/access.log  main;

 

    sendfile        on;

    #tcp_nopush     on;

 

    keepalive_timeout  65;

 

    #gzip  on;

 

    include /etc/nginx/conf.d/*.conf;

}

 

Рестартис сервисы

sudo service nginx restart

sudo service php7.0-fpm restart

 

itc-life.ru


Смотрите также

Prostoy-Site | Все права защищены © 2018 | Карта сайта