Руководство по настройке блога WordPress на nginx.

Данное руководство рассчитано на вебмастеров, стремящихся решить проблему недостаточной производительности сайтов, построенных на платформе WordPress. В нем описана пошаговая настройка сервера с ограниченными ресурсами (1 ядро, 512 RAM на примере минимального тарифа Flops.ru) для использования в связке LEMP (Linux + nginx + MySQL + PHP). Для комфортного использования материала вы должны иметь общие представления о работе сайтов и серверов на базе Linux.

Данное руководство рассчитано на вебмастеров, стремящихся решить проблему недостаточной производительности сайтов, построенных на платформе WordPress. В нем описана пошаговая настройка сервера с ограниченными ресурсами (1 ядро, 512 RAM на примере минимального тарифа Flops.ru) для использования в связке LEMP (Linux + nginx + MySQL + PHP). Для комфортного использования материала вы должны иметь общие представления о работе сайтов и серверов на базе Linux.

Эволюция требований к хостингу при увеличении масштабов проекта.

Наиболее популярным решением для веб серверов по прежнему остается связка LAMP (Linux, Apache, MySQL, PHP). Подобный вариант легок в настройке, хорошо документирован, часто используется для небольших проектов. Но за простоту использования приходится платить чрезмерным потреблением ресурсов и высокими рисками даунтайма при увеличении нагрузки (возросшее число посетителей, большое количество материалов, тяжелые плагины).

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

Часто в качестве следующего шага развития используется LAMP за proxy сервером nginx, обеспечивающим быструю отдачу статики, тем самым снижая нагрузку на Apache. Подобное решение позволяет с минимальными усилиями и поддержкой специфических для Apache возможностей (например .htaccess) существенно повысить производительность. Для ускорения динамики в ход идут исполнение PHP в режиме CGI, средства кэширования байт-кода и SQL запросов. При этом в подобной связке все равно остается узкое место — производительность Apache.

Следующим витком эволюции в погоне за производительность стает полный отказ от Apache, использование FPM, полное кэширование страниц сайта.

Это руководство подробно рассказывает о настройке WordPress, выдерживающей нагрузки в несколько сотен конкурентных запросов в секунду в условиях крайне ограниченных серверных ресурсов. Руководство описывает все шаги установки, включая первичную настройку сервера, обеспечивающую защиту от стандартных угроз, установку и настройку LEMP, настройку WordPress. Выполнение всех пунктов гарантирует получение работоспособного сервера.

ВАЖНО: В руководстве не описана процедура резервного копирования, так как Flops.ru обеспечивает создание резервных копий и снэпшотов, а использование сторонних мест хранения сугубо индивидуально.

ВАЖНО: Набор предустановленных пакетов у разных хостинг-провайдеров может варьироваться. Руководство подразумевает наличие схожих с Flops.ru пакетов.

ЗАМЕЧАНИЕ: В интернете гуляет множество статей по использованию в подобной связке Varnish, но nginx отдает статику не хуже, а конфигурация, представленная ниже, преимущественно будет работать именно со статикой, так что не вижу смыла усложнять проект еще одной прослойкой, тем более сильно отягчающей жизнь проектам, использующим SSL. Для формирования статической выдачи будет использоваться плагин WP Super Cache.

Требования к серверу.

В руководстве приводятся примеры конфигурации для сервера VPS с одним ядром, 512Mb Ram, SSD. Тестовые сервера были развернуты у хостинг-провайдера Flops.ru, но вы можете воспользоваться любыми другими. Так как приведенные ниже настройки рассчитаны на максимальное использование кэшированных на дисках объектов, наиболее важным параметром будет производительность дисковой подсистемы.

Для установки сервера был выбран дистрибутив Debian 7 x86, так как в микроинстялляциях он обеспечивает более экономное использование памяти по сравнению с x64 версиями.

Подготовка серверного окружения.

После установки сервера установим с ним соединение по ssh.

Сразу после установки не назначены локали по умолчанию. Укажем основной локалью en_US.UTF-8.

1
2
echo LC_ALL=en_US.UTF-8 >>/etc/environment
echo LANG=en_US.UTF-8 >>/etc/environment

Для того, чтобы изменения вступили в силу, необходимо завершить сеанс SSH и начать его заново.

Обновим ПО сервера.

1
2
apt-get update
apt-get upgrade

Установим и настроим sudo.

1
apt-get install sudo

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

1
2
useradd -m -U -s /bin/bash webmaster
passwd webmaster

Настроим sudo.

1
nano /etc/sudoers
# При авторизации под root будет спрашивать пароль root, 
# а не пользователя.
Defaults rootpw
# Разрешить пользователю webmaster присваивать root права.
webmaster ALL=(ALL) ALL

Теперь перелогинимся под новым пользователем и убедимся, что все хорошо. Если проблем не возникло ограничим доступ root пользователю к SSH.

1
sudo nano /etc/ssh/sshd_config

Найдем строку

PermitRootLogin Yes

и заменим ее на

PermitRootLogin no

После внесения изменений перезагрузим OpenSSH.

1
sudo service ssh restart

Ограничим возможности потенциальных злоумышленников к подбору паролей SSH. Воспользуемся утилитой fail2ban. Также позже мы настроим fail2ban для блокирования возможности подбора пароля к WordPress.

1
sudo apt-get install fail2ban

Для нашей задачи дополнительные настройки fail2ban не требуются. Теперь при шестикратном неправильном вводе пароля ssh, пользователь будет блокироваться с помощью iptables на 600 секунд.

Настроим синхронизацию времени.

1
2
3
4
5
6
#Установка необходимых пакетов
sudo apt-get install ntp ntpdate
#Установка сервера синхронизации
sudo ntpdate -s pool.ntp.org
#Запуск демона ntp
sudo service ntp start

Настроим exim4 для отправки писем с сайта.

1
2
sudo apt-get install exim4
sudo dpkg-reconfigure exim4-config

General type of mail configuration: Выберем верхний пункт internet site; mail is sent and received directly using SMTP.

System mail name: Укажем полное имя сервера, например admins.su.

IP-addresses to listen on for incoming SMTP connections: 127.0.0.1

Other destinations for which mail is accepted: Оставим пустым.

Domains to relay mail for: Оставим пустым.

Machines to relay mail for: Оставим пустым.

Keep number of DNS-queries minimal (Dial-on-Demand)? No

Delivery method for local mail: Любое значение.

Split configuration into small files? Yes


Резюме выполненных действий:

  1. Создан пользователь webmaster для доступа по ssh.
  2. Для повышения привилегий до root требуется дополнительный ввод пользователем webmaster пароля root.
  3. Настроена защита от перебора пароля по ssh.
  4. Настроена синхронизация времени.
  5. Настроена почта для отправки писем с сайта.

Установка LEMP.

Мы будем использовать установку из пакетов для простого управления обновлениями. Для того, чтобы получить более свежий nginx (стандартно ставится nginx 1.2.1), мы подключим родной репозиторий nginx.

Скачаем и установим PGP ключ сервера nginx.

1
2
3
4
mkdir ~/installfiles
cd ~/installfiles
wget http://nginx.org/keys/nginx_signing.key
sudo apt-key add nginx_signing.key

Добавим репозиторий nginx в список sources.list менеджера apt.

1
sudo nano /etc/apt/sources.list
deb http://nginx.org/packages/debian/ wheezy nginx
deb-src http://nginx.org/packages/debian/ wheezy nginx

Обновим данные о доступных пакетах.

1
sudo apt-get update

Теперь настало время установки необходимых для работы веб сервера пакетов.

1
sudo apt-get install nginx mysql-server php5-fpm php5-mysql php5-gd php-apc unzip

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

Настройка LEMP.

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

Вместо %SITENAME% необходимо указать имя сайта без http и www. Например admins.su или blog.admins.su

1
2
sudo mkdir /srv/%SITENAME%
sudo chown -R www-data:www-data /srv/%SITENAME%

Создадим базу данных для сайта.

ВАЖНО: В листинге требуется изменить название базы, имя пользователя и его пароль.

1
mysql -uroot -p
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
#Создание базы
#вместо имени базы blog укажем желаемое.
CREATE DATABASE blog;

#Создание пользователя
#вместо user укажем имя пользователя, вместо testpass 
#его пароль.
CREATE USER 'user'@'localhost' IDENTIFIED BY 'testpass';

#Предоставление пользователю полного доступа в базу
#Не забудьте сменить user и blog в строке ниже на 
#указанные в предыдущих запросах.
GRANT ALL PRIVILEGES ON blog . * TO 'user'@'localhost';

#Сброс привилегий
FLUSH PRIVILEGES;

#Выход из MySQL
EXIT;

Теперь настроим FPM.

Удалим стандартную конфигурацию.

1
sudo rm /etc/php5/fpm/pool.d/www.conf

Создадим новую конфигурацию.

1
sudo nano /etc/php5/fpm/pool.d/blog.conf

ВАЖНО: В листинге необходима замена параметра %SITENAME% на название сайта без www.

# PHP-FPM conf
# Это конфигурация для эффективной работы Wordpress на сервере 1CPU, 512 RAM.
# Если на сервере вы хотите использовать более одного сайта, скопируйте данный файл 
# и замените в нем все вхождения названия старого сайта на называние нового.
# Подробно о настройке вы можете прочитать, перейдя по ссылке 
# https://admins.su/rukovodstvo-po-nastrojke-bloga-wordpress-na-nginx

# Замените %SITENAME% на имя вашего сайта без http и www.
# Например admins.su или blog.admins.su

[%SITENAME%]

# Имя пользователя и группы, от которых будет производиться
# запуск процессов php-fpm
user = www-data
group = www-data

#Путь до сокета
listen = /var/run/$pool.sock
listen.owner = www-data
listen.group = www-data
listen.mode = 0660

# Режим управления worker процессами.
pm = dynamic

# Максимальное количество worker процессов. Этот параметр устанавливает
# ограничение на число одновременных запросов, которые будут обслуживаться.
pm.max_children = 8

# Количество worker процессов при старте.
pm.start_servers = 3

# Минимальное количество поддерживаемых свободных worker процессов.
pm.min_spare_servers = 2

# Максимальное количество поддерживаемых свободных worker процессов.
pm.max_spare_servers = 4

# Число запросов дочернего процесса, после которого процесс будет перезапущен.
# Это полезно для избежания утечек памяти при использовании сторонних библиотек.
pm.max_requests = 600

# Ограничивает указанным деревом каталогов файлы, которые могут быть
# доступны для PHP, включая сам файл.
php_admin_value[open_basedir] = /srv/$pool:/tmp

# Настройка записи медленных скриптов.
request_slowlog_timeout = 5s
slowlog = /var/log/php-fpm-slowlog-$pool.log

После того, как мы создали файл конфигурации php-fpm, необходимо перезагрузить сервис.

1
sudo service php5-fpm restart

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

Теперь настроим nginx.

1
sudo nano /etc/nginx/nginx.conf

Изменим имя пользователя с nginx на www-data.

1
2
# user nginx;
user www-data;

Найдем и раскомментируем строки.

1
2
#tcp_nopush on;
tcp_nopush on;

Настроим gzip.

1
2
3
4
5
6
7
#tcp_nopush on;
gzip  on;
gzip_min_length  1000;
gzip_proxied     any;
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript text/x-js;
gzip_disable "MSIE [1-6]\.(?!.*SV1)";
gzip_comp_level  6;

Изменим время таймаута keepalive.

1
2
#keepalive_timeout 65;
keepalive_timeout 10;

Удалим стандартные конфигурационные файлы:

1
sudo rm /etc/nginx/conf.d/default.conf /etc/nginx/conf.d/example_ssl.conf

Создадим новый конфигурационный файл.

1
sudo nano /etc/nginx/conf.d/blog.conf

ВАЖНО: В листинге необходима замена параметра %SITENAME% на название сайта без www.

# nginx site conf
# Это конфигурация для эффективной работы Wordpress на сервере 1CPU, 512 RAM.
# Если на сервере вы хотите использовать более одного сайта, скопируйте данный файл 
# и замените в нем все вхождения названия старого сайта на называние нового.
# Подробно о настройке вы можете прочитать, перейдя по ссылке
# https://admins.su/rukovodstvo-po-nastrojke-bloga-wordpress-na-nginx

# Замените %SITENAME% на имя вашего сайта без http и www.
# Например admins.su или blog.admins.su.

server {

    listen *:80;


    server_name %SITENAME% www.%SITENAME%;

    access_log /var/log/nginx/%SITENAME%.access.log;
    error_log /var/log/nginx/%SITENAME%.error.log;

    root /srv/%SITENAME%;
    index index.php;


# Не сообщать о отсутствии favicon, не писать информацию о доступе к нему в access лог .
location = /favicon.ico {
        log_not_found off;
        access_log off;
}

# Не сообщать о отсутствии robots.txt, не писать информацию о доступе к нему в access лог. 
location = /robots.txt {
        allow all;
        log_not_found off;
        access_log off;
}

# Запретить доступ к файлам, начинающимся с точки. Например .htaccess
location ~ /\. {
        deny all;
}
# Запретить доступ к файлам php в директориях uploads, files.
location ~* /(?:uploads|files)/.*\.php$ {
        deny all;
}


rewrite /wp-admin$ $scheme://$host$uri/ permanent;

# Для файлов отключить логирование, установить максимальный срок жизни кэша. 
location ~* ^.+\.(ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|rss|atom|jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf)$ {

       access_log off; log_not_found off; expires 90d;
}


set $cache_uri $request_uri;

# Запретить кэширование, если используются POST запросы.
if ($request_method = POST) {
        set $cache_uri 'null cache';
}


if ($query_string != "") {
        set $cache_uri 'null cache';
}

# Запретить кэширование при доступе к служебным скриптам.
if ($request_uri ~* "(/wp-admin/|/xmlrpc.php|/wp-(app|cron|login|register|mail).php|wp-.*.php|/feed/|index.php|wp-comments-popup.php|wp-links-opml.php|wp-locations.php|sitemap(_index)?.xml|[a-z0-9_-]+-sitemap([0-9]+)?.xml)") {
        set $cache_uri 'null cache';
}

# Запретить кэширование, если используются cookie.
if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_logged_in") {
        set $cache_uri 'null cache';
}

# Отдавать кэш.
location / {
        try_files /wp-content/cache/supercache/$http_host/$cache_uri/index.html $uri $uri/ /index.php?$args ;
}

# Для файлов php отдавать обработку FASTCGI серверу.
location ~ [^/]\.php(/|$) {
        root /srv/%SITENAME%;
        fastcgi_split_path_info ^(.+?\.php)(/.*)$;
        if (!-f $document_root$fastcgi_script_name) {
                return 404;
        }


        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_pass unix:/var/run/%SITENAME%.sock;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        #fastcgi_param  SCRIPT_FILENAME  /srv/%SITENAME%/$fastcgi_script_name;

    }
}

После сохранения конфигурационного файла необходимо проверить работоспособность конфигурации.

1
sudo nginx -t

Если ошибок не обнаружено перезагрузим nginx

1
sudo service nginx restart

Резюме выполненных действий:

  1. Установлена БД MySQL. Создана база для WordPress, создан пользователь, заданы привилегии.
  2. Установлен и настроен php-fpm.
  3. Установлен и настроен nginx.

Установка WordPress.

Установка WordPress на сервер ничем не отличается от установки на Apache.

Загрузим последнюю версию WordPress на сервер, распакуем ее и изменим владельца файлов на www-data.

1
2
3
4
5
cd ~/installfiles/
wget http://wordpress.org/latest.zip
unzip latest.zip
sudo mv wordpress/* /srv/%SITENAME%/
sudo chown -R www-data:www-data /srv/%SITENAME%

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

Сразу после этого установим и активируем 2 необходимых для нормальной работы в LEMP плагина: Nginx Helper и WP Super Cache.

Плагин Nginx Helper в нашем случае не требует настройки , важен лишь факт его присутствия и активации. В условиях того, что за кэш будет отвечать плагин WP Super Cache, кнока Purge сверху работать не будет.

WP Super Cache требует незначительной настройки.

После активации необходимо выбрать нужный вид ЧПУ на странице http://%SITENAME%/wp-admin/options-permalink.php

В настройке самого плагина перейдем на вкладку «Настройки»

Выставим следующие настройки (с остальных галки необходимо снять):

[V]Кэшировать сессии просмотров для быстрого доступа. (Рекомендовано)

[V]Использовать mod_rewrite для обслуживания кэша. (Рекомендовано)

[V]Сжимать файлы кэша чтобы ускорить работу. (Рекомендовано)

[V]Ошибка 304. Данная ошибка возникает тогда, когда страница не была изменена со времени прошлого запроса. (Рекомендовано)

[V]304 support is disabled by default because some hosts have had problems with the headers used in the past.

[V]Авто перестройка кэша. Гости блога увидят устаревшие версии страниц кэша пока новые будут генерироваться. (Рекомендовано)

[V]Clear all cache files when a post or page is published or updated.

[V]Дополнительная сверка кэша (очень редко может нарушить работу кэширования). (Рекомендовано)

[V]Обновлять страницу при добавлении нового комментария к ней

После внесения изменений нажмите кнопку «Обновить».

При попытке сохранения сверху вы увидите следующее сообщение:

Права на запись должны быть обновлены

Необходимые для работы плагина права были изменены или отсуствуют. Прокрутите страницу вниз и нажмите кнопку Обновить правила Mod_Rewrite.

WP Super Cache не знает, что используется nginx и сообщает, что требуется изменить файл .htaccess. Для того, чтобы все заработало, надо разрешить ему сделать это. Прокрутим страницу вниз и нажмем кнопку Обновить правила mod_rewrite.

На вкладке «Обслуживание» установим галочку:

[V]Очищать кэш при ошибке.

И также нажмем кнопку “Обновить”.

Теперь перейдем на вкладку Кэш и проверим, что все работает нажатием кнопки “Проверить”.

Если вы увидели надпись “Временные штампы обоих вариантов страницы совпадают!", значит все настройки сделаны правильно.


Резюме выполненных действий:

  1. Установлен WordPress.
  2. Установлены и настроены плагины WP Super Cache и Nginx helper.

На этом настройка завершена.

На заметку:

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

В руководстве не упоминается тюнинг MySQL. Это отдельная большая тема, про которую я обязательно напишу.


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

comments powered by Disqus