Установка nginx+varnish-4.0+apache + MariaDB + PHP5.6 на CentOS 7

Вот наконец-то и добрался до обновления статьи для CentOS7.

Итак, задача старая: поставить LAMP.
Схема тоже старая - nginx - ftontend'ом, varnish - middleend'ом, apache - backend'ом. Первый отдаёт статический контент и занимается различного рода маршрутизацией, добавлением заголовком и пр, если это нужно. Varnish отбивает потоки анонимных запросов, кэшируя целые страницы, ну, и apache уже выполняет код.

Надо сказать, что если вы делаете production версию сайта однозначно надо ставить php-fpm. Он значительно лучше справляется с нагрузками и ощутимо "легче". Apache мы будем тут рассматривать, скорее, "по привычке" - новичкам с ним проще разобраться (ну... точнее сделать так, чтобы сайт работал ;-) ), потому как все популярные CMS, на которых пишутся сайты, заранее готовят файлы .htaccess, где уже настроены необходимые правила перенаправления и обработки запросов. По этой же причине сайт работает медленнее. Для тех, кто сейчас ничего не понял есть ссылочка на Википедию, где более менее объясняют что это такое. Ну, а далее путь ваш лежит в поисковик =)

По поводу Varnish: да, конечно, можно использовать и nginx, как кэширующий сервер. Но если Ваш сайт на CMS Drupal - лучше ставить Varnish, потому как для него есть модуль, позволяющий управлять кэшем веб-сервера Varnish из "админки" сайта. Ну, например, сбрасывать его (кэш). Nginx Вам такого не позволит =) Это, конечно же, не единственное преимущество! Nginx - это веб-сервер, Varnish - нет. Это чисто кэширующий сервер. Крайне мощный инструмент с произвольной настройкой, что кэшировать, при каких условиях и как. В общем, очень хорош, если умеючи =)

MariaDB (ссылочка на Википедию, кому надо)- ответвление с MySQL. Ставить его теперь считается хорошим тоном, после того, как Oracle закрыла часть кода своей СУБД (MySQL). А как вы понимаете, свободное сообщество такого не любит ;-)

Начинаем, как всегда, с подключения репозиториев, так как предполагаем, что ваш сервер "голый" и единственное, что на нём есть это настроенный доступ в Интернет. Статью про подключения полезных реп тоже нужно переписывать =) Но пока нет времени. Ничего лишнего включать не будем - только то, что действительно полезно и нужно.

      Первым, разумеется, epel:
      yum install epel-release -y
      Далее remi, из него мы поставим php-5.6:
      yum install http://rpms.famillecollet.com/enterprise/remi-release-7.rpm -y
      Теперь поставим нормальный репозиторий MariaDB:

      cat << EOF > /etc/yum.repos.d/MariaDB.repo
      # MariaDB 10.0 CentOS repository list - created 2015-08-12 16:24 UTC
      # http://mariadb.org/mariadb/repositories/
      [mariadb]
      name = MariaDB
      baseurl = http://yum.mariadb.org/10.0/centos7-amd64
      gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB
      gpgcheck=1
      EOF
      nginx:
      yum install http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm -y
      И переключимся на ветку с последними версиями:
      sed -i s#packages#packages/mainline# /etc/yum.repos.d/nginx.repo
      Ну, и остался varnish. Берём последнюю версию 4.1:
      yum install https://repo.varnish-cache.org/redhat/varnish-4.1.el7.rpm -y

    Ссылочка на страницу скачивания, если нужно.

Давайте откроем файл репозитория remi и включим его:
vi /etc/yum.repos.d/remi.repo
Да, да - vi =) У нас же "голый" сервер =)

Нажимаем клавишу "i" - таким образом перейдя в режим внесения данных с клавиатуры.
Надо изменить параметры "enabled" в разделах "[remi]" и "[remi-php56]". Находим их и меняем. Для наглядности спойлер ниже:

Spoiler: Highlight to view

[remi]
name=Remi's RPM repository for Enterprise Linux 7 - $basearch
#baseurl=http://rpms.remirepo.net/enterprise/7/remi/$basearch/
mirrorlist=http://rpms.remirepo.net/enterprise/7/remi/mirror
enabled=1
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-remi

[remi-php56]
name=Remi's PHP 5.6 RPM repository for Enterprise Linux 7 - $basearch
#baseurl=http://rpms.remirepo.net/enterprise/7/php56/$basearch/
mirrorlist=http://rpms.remirepo.net/enterprise/7/php56/mirror
# WARNING: If you enable this repository, you must also enable "remi"
enabled=1
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-remi

Всё, остальное нам не интересно. Чтобы сохранить изменения и выйти из этого "чуда", нажмите "ESC", и далее "Shift+z+z". Файл должен закрыться ;-)

Для начала обновим всю систему, если вы этого ещё не сделали:
yum update -y
Если среди обновлённых пакетов есть "kernel" лучше перезагрузиться, чтобы новое ядро применилось. Сделать это можно с помощью команды:
reboot

Начнём!
yum install php php-gd php-mbstring php-mcrypt php-xml php-pear php-pdo php-mysql nginx mysql mysql-server varnish httpd-itk -y

Установиться большая куча пакетов и, в итоге, должно появится Complete! Что же мы вообще ставим?! На самом деле - только всё необходимое. Кому интересно можно посмотреть спойлер:

Spoiler: Highlight to view

  • httpd-itk - Apache HTTP-сервер - наш backend (http://ru.wikipedia.org/wiki/Apache), который будет работать в режиме Apache-ITK;<.li>
  • php - скриптовый язык программирования общего назначения, интенсивно применяемый для разработки веб-приложений (http://ru.wikipedia.org/wiki/Php);
  • php-gd - графическая библиотека GD, содержащая функции для работы с изображениями (http://php.net/manual/ru/book.image.php);
  • php-mbstring - предоставляет расширенную поддержку кодировок (http://php.net/manual/ru/book.mbstring.php‎);
  • php-mcrypt - библиотека, которая поддерживает алгоритмы блочного шифрования (http://www.php.net/manual/ru/book.mcrypt.php);
  • php-xml - данный инструментарий позволяет Вам анализировать, но не проверять XML-документы (http://php.net/manual/ru/book.xml.php);
  • php-pear - это аббревиатура от "PHP Extension and Application Repository" - Репозиторий приложений и модулей PHP (http://pear.php.net/manual/ru/about.pear.php);
  • php-pdo - определяет простой и согласованный интерфейс для доступа к базам данных в PHP (http://php.net/manual/ru/book.pdo.php);
  • php-mysql - эти функции позволяют вам работать с MySQL. Это расширение не рекомендуется использовать при написании собственного нового кода! Смотрите ссылку (http://php.net/manual/ru/book.mysql.php);
  • nginx - простой, быстрый и надёжный сервер, не перегруженный функциями. Применение nginx целесообразно прежде всего для статических веб-сайтов (http://nginx.org/ru/);
  • mysql - клиент mysql-server (http://ru.wikipedia.org/wiki/Mysql);
  • mysql-server - свободная система управления базами данных. Разработку и поддержку MySQL осуществляет корпорация Oracle (http://ru.wikipedia.org/wiki/Mysql);
  • varnish - cache web-сервер (https://www.varnish-cache.org/).

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

systemctl enable nginx  &&
systemctl enable httpd  &&
systemctl enable varnish  &&
chkconfig mysql on

Напомню, что такое MPM-ITK. Это очень удобный режим, позволяющий избежать различных проблем с правами на виртуальных хостах. Т.е. мы ставим владельца корневой папки хоста конкретного пользователя, таким образом даём ему все права на изменение любых файлов внутри и при этом apache так же работает от имени этого пользователя. Включим его:
sed -i s/\#LoadModule/LoadModule/ /etc/httpd/conf.modules.d/00-mpm-itk.conf

Теперь схема того, как всё будет работать. Впереди стоит nginx на 80 порту. Далее varnish на своём порту по умолчанию 6081 и в конце apache на 81 (рекомендация RedHat для backend-серверов). В принципе, конечно, номера портов для varnish и apache можно выбрать и другие - это не принципиально. Сначала закончим с apache'ом. Мне нравится, как организованы виртуальных хосты в семействе debian, поэтому Вам так же предлагаю перенять это. А так же сделать отдельные папки для логов ошибок и доступов. Это очень удобно тем, что не придётся ничего искать. Всё чётко структурировано и очень удобно в управлении и других различных операциях. Создадим несколько папок:

mkdir /etc/httpd/sites-available &&
mkdir /etc/httpd/sites-enabled &&
mkdir /var/log/httpd/error/ &&
mkdir /var/log/httpd/access/ &&
mkdir /var/log/nginx/error/ &&
mkdir /var/log/nginx/access/

Пояснения:

  • Первая папка это созданные, но не "включенные" виртуальные хосты. Иногда бывает полезно, например, когда нужно выключить хост на некоторое время;
  • Вторая папка будет содержать symlink'и (ярлыки) на созданные хосты из первой. Т.е., чтобы временно выключить хост, достаточно удалить symlink, не удаляя конфигурацию виртуального хоста. Кстати, крайне рекомендую свой скрипт для управления виртуальными хостами веб-сервера Apache;
  • Как, думаю, понятно из названия 3, 4, 5, 6 папки нужны для структуризации логов. Очень удобно, особенно когда логи называются по имени хоста. Плюс к этому я написал свой скрипт бэкапов и ротации логов =) Если интересно - милости прошу.

Донастроим apache
Во-первых, изменим прослушивающийся порт и IP-адрес. Сделаем, чтобы apache слушал только 127.0.0.1 - зачем он нам во вне? Это может быть опасно и плохо.
sed -i s#Listen\ 80#Listen\ 127\.0\.0\.1\:81# /etc/httpd/conf/httpd.conf
Во-вторых, добавим строку, чтобы веб-сервер начал читать конфигурационный файлы виртуальных хостов из папки /etc/httpd/sites-enabled:
echo "IncludeOptional sites-enabled/*.conf" >> /etc/httpd/conf/httpd.conf

Создадим быстренько структуру директорий для будущего сайта, на чём мы будет экспериментировать. И, соответствующего пользователя, от имени которого будет работать веб-сервер:

mkdir -p /var/www/domain.ru/{tmp,session,www}
useradd -d /var/www/domain.ru user

Далее переходим к настройкам виртуальных хостов.
Создадим и отредактируем наш виртуальный хост:

Spoiler: Highlight to view

vi /etc/httpd/sites-available/domain.ru.conf
Внутри должно быть, примерно, следующее:

<VirtualHost *:81>
  ServerAdmin admin@domain.ru
  ServerName domain.ru
  ServerAlias www.domain.ru
  ErrorLog /var/log/httpd/error/domain.ru
  CustomLog /var/log/httpd/access/domain.ru combined
  DocumentRoot /var/www/domain.ru/www/
  <Directory /var/www/domain.ru/www>
    Options FollowSymLinks
    AllowOverride All
    Order allow,deny
    Allow from All
 </Directory>
  AssignUserID user group
  php_admin_value open_basedir "/var/www/domain.ru/"
  php_admin_value upload_tmp_dir "/var/www/domain.ru/tmp/"
  php_admin_value sys_temp_dir "/var/www/domain.ru/tmp/"
  php_admin_value session.save_path "/var/www/domain.ru/session/"
</VirtualHost>

Ниже пояснения, если нужны... как сумел =)

Spoiler: Highlight to view

  • VirtualHost *:81 - Указываем, что тут начинается конфигурация отдельного виртуального хоста. Часть "*:81" должна совпадать с прослушивающимся портом в конфигурационном файле apache;
  • ServerAdmin admin@domain.ru - Почта администратора сайта;
  • ServerName domain.ru - Основное имя сайта;
  • ServerAlias www.domain.ru - Псевдонимы сайта (другие имена);
  • ErrorLog /var/log/httpd/error/domain.ru - Путь к логам ошибок;
  • CustomLog /var/log/httpd/access/domain.ru combined - Путь к логам обращений;
  • DocumentRoot /var/www/domain.ru/www - Корневая папка сайта;
  • Directory /var/www/domain.ru/www - Директива, в которой указываются параметры к данной папке и всем подпапкам в ней;
  • Options FollowSymLinks - Сервер будет проходить по ссылкам на файлы (ярлыкам);
  • AllowOverride All - Будет ли сервер искать файлы .htaccess и читать их. all - да, none - нет;
  • Order allow,deny - Параметр контролирует трёх-фазную систему контроля доступа;
  • Allow from All - Параметр "разрешить отовсюду";
  • /Directory - Окончание параметров директивы;
  • AssignUserID user group - Указывает от какого пользователя должен работать apache;
  • php_admin_value open_basedir - принудительно запрещаем веб-серверу обрабатывать код, который обращается за пределы корневой директории сайта (да, такого быть не должно!);
  • php_admin_value upload_tmp_dir - принудительно задаём путь к папке с временными файлами, который закачиваются на сайт. Обратите внимание, что директория находится во вне относительно корневой директории сайта
  • php_admin_value sys_temp_dir - принудительно задаём путь к папке с временными файлами. Принцип как и в предыдущем пункте.
  • php_admin_value session.save_path - принудительно задаём путь к папке, где хранятся сессии php (не для всех сайтов актуально, но хуже точно не будет). Опять же, пусть наши сессии будут отдельно от сессий других сайтов, если их несколько на сервер.
  • /VirtualHost # Окончание файла конфигурации виртуального хоста.

Теперь нам нужно "включить" наш хост.

cd /etc/httpd/sites-enabled/
ln -s ../sites-available/domain.ru.conf

Или, если вы скачали скрипт управления виртуальными хостами веб-сервера apache:
a2mng on domain.ru

Всё, apache готов. Если Вы не забыли создать корневую папку виртуального хоста и пользователя, которого указали в параметре AssignUserID, то всё должно быть хорошо.
Проверим apache:
apachectl configtest
Или, если вы поставили скрипт... ну, в общем, поняли =) :
a2mng cf
Результатом этой команды должно быть:
Syntax OK

Если ВДРУГ =) Вы получили ошибку:
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using localhost.localdomain. Set the 'ServerName' directive globally to suppress this message
Милости прошу под спойлер:

Spoiler: Highlight to view

Нужно зайти в файл /etc/hosts и добавить имя сервера напротив нашего внешнего адреса.
Поясню:
Чтобы узнать имя сервера, выполните:
hostname -a
Если будет что-то типа:
localhost.localdomain localhost4 localhost4.localdomain4 localhost.localdomain localhost6 localhost6.localdomain6
То лучше не обижать сервер и дать ему нормальное имя. Выполните:
hostname domain.ru
и ещё:
nmtui
И там выбираем: "Изменить имя узла сети" и вносим имя.
Можем проверить:
hostname
Вот это имя, которое мы внести надо прописать в файл /etc/hosts. Узнаем для начала наш внешний IP адрес:
ip a
Ищем строчку, которая начинается с inet и отличную от 127.0.0.1.
Например, как это выглядит у меня на тестовой машине:

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN 
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 08:00:27:c6:35:e5 brd ff:ff:ff:ff:ff:ff
    inet 192.168.0.251/24 brd 192.168.0.255 scope global enp0s3
       valid_lft forever preferred_lft forever
    inet6 fe80::a00:27ff:fec6:35e5/64 scope link 
       valid_lft forever preferred_lft forever

Т.е. мой внешний адрес: 192.168.0.251
Вставляем это значение в файл /etc/hosts
echo "192.168.0.251 domain.ru" >> /etc/hosts
Проверяем ещё раз apache:
apachectl configtest
Или, если вы поставили скрипт... :
a2mng cf
Результатом этой команды должно быть:
Syntax OK

Включаем apache, мы с ним закончили:
systemctl start httpd

Теперь varnish
Ничего пока с ним особого делать не будем и понадеемся на конфигурацию из коробки. Поверьте - это даст значительный прирост! Если кому интересно повозиться, тот парень, который написал конфиг для 3-ей версии, которым я пользуюсь до сих пор (с минимум изменений) сделал настройки и для 4-ой версии. Но проверить и потыкать я не успел ещё, поэтому на свой страх и риск, как говориться =)
Ссылочка вот:
https://github.com/mattiasgeniar/varnish-4.0-configuration-templates/blo...

А мы лишь изменим порт, на котором находится apache:
sed -i s#8080#81# /etc/varnish/default.vcl
Запускаем varnish:
systemctl start varnish

Теперь nginx

На самом деле nginx в общем-то готов к запуску. Нужно, разве что, создать конфигурацию виртуального хоста. Тем не менее, скину свой рабочий конфиг (файл /etc/nginx/nginx.conf):

Spoiler: Highlight to view

user  nginx;
worker_processes  12;
worker_rlimit_nofile 10000;
error_log /var/log/nginx/error.log;
pid /var/run/nginx.pid;
 
events {
  worker_connections  2048;
  use epoll;
}
 
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;
  tcp_nodelay     on;
  server_tokens   off;
  gzip            on;
  gzip_static     on;
  gzip_comp_level 5;
  gzip_min_length 1024;
  gzip_types	  text/plain application/x-javascript text/css application/json application/javascript text/javascript application/xml;
  keepalive_timeout  65;
  client_max_body_size 100m;
  proxy_read_timeout 300;
  proxy_connect_timeout 300;
  proxy_send_timeout 300;
 
  include /etc/nginx/conf.d/*.conf;
  server_names_hash_bucket_size 128;
}

Про значение параметров рассказывать не буду. Все они отлично описаны на официальном сайте на русском языке.
Нам остаётся лишь прописать виртуальный хост.

cd /etc/nginx/conf.d/
vi domain.ru.conf

Spoiler: Highlight to view

server {
  listen  80;
  server_name  www.domain.ru;
  return 301 http://domain.ru$request_uri;
}
 
server {
  listen 80;
  server_name domain.ru;
 
  error_log /var/log/nginx/error/domain.ru;
  access_log /var/log/nginx/access/domain.ru;
 
  location ~* \.(jpg|jpeg|gif|png|bmp|svg|swf|htm|js|ico|css|mp3|ogg|mpe?g|gz|tar|avi|zip|gz|bz2|rar)$ {
    try_files $uri $uri/ @drupal;
    expires 14d;
    root /var/www/domain.ru/www;
  }
 
  location ~ (^|/)\. {
    deny  all;
  }
 
  location / {
    proxy_pass http://127.0.0.1:6081;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Real-IP $remote_addr;
  }
 
  location @drupal {
    proxy_pass http://127.0.0.1:6081;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Real-IP $remote_addr;
  }
}

Что тут есть?...

  1. Значит сначала стоит редирект с www на без www.
  2. Директива location указывает на корневую папку виртуального хоста и ищет и отдаёт из неё файлы (статику) с указанными расширениями. Разумеется, их можно изменить/дополнить. Если nginx не находит файла по указанному пути, он передаёт запрос дальше (сначала на varnish, потом apache). И backend уже сам разбирается, что с ним делать.
  3. Файлы начинающиеся с точки (скрытые файлы linux) ".*" (обычно .htacces, .htpasswd, .git и пр.) не отдавать "не под каким предлогом" =)

Ну, в целом всё. Можно проверить правильность настроек и запускать nginx:

nginx -t
systemctl start nginx

На этом настройки web-серверов закончены!

Теперь быстренько mariadb - и всё =)
Для начала надо посмотреть, какой конфиг у нас там прописан. Найти его можно по адресу:
nano /etc/my.cnf
Вообще правильная настройка БД - это целое искусство.... которым я, к сожалению, толком не обладаю =)
Предлагаю Вам несколько вариантов, как это сделать:

  1. Оставить всё как есть ^_^;
  2. Посмотреть разные конфиг-файлы, предлагаемые по умолчанию:
    cat /usr/share/mysql/my-huge.cnf
    cat /usr/share/mysql/my-innodb-heavy-4G.cnf
    cat /usr/share/mysql/my-large.cnf
    cat /usr/share/mysql/my-medium.cnf
    cat /usr/share/mysql/my-small.cnf

    Внутри есть описания, но, по большому счёту, они отличаются количеством Вашей оперативной памяти;

  3. Зайти на сайт persona.com и создать там свой индивидуальный конфиг-файл.

Будем считать, что Вы справились с задачей выбора конфиг-файла и записали всё необходимое в файл настроек БД - /etc/my.cnf.
Далее, запускаем БД:
systemctl start mysql
И последний штрих - запустим настройку безопасности:
mysql_secure_installation
Здесь Вас попросят:

  • Ввести пароль для root пользователя СУБД;
  • Предложат удалить доступ для анонимных пользователей (обязательно соглашайтесь!);
  • Убрать доступ root пользователю удалённо;
  • Удалить тестовые БД и пользователя;
  • Перезагрузить таблицу привилегий.

Ну, вот и всё =)
Буду очень рад уточнениям и вопросам - потому как большой объём статьи и вполне возможны опечатки и "что-то забыл" =)
Всем удачи!

Комментарии

Спасибо за обновление толковой статьи!

Спасибо за статью!
Опечатка - Ну, а далее пуСть ваш лежит в поисковик =)

Благодарю, исправил. Хотя "пусть" - более эпично =)

При проверке состояния Apache у меня получилось:
AH00544: httpd: bad group name group

Решил так. Добавил группу:
groupadd users

и в файле domain.ru.conf заменил строку:
AssignUserID user group
на
AssignUserID user users

Всё верно, просто обычно имени пользователя есть соответствующая группа, если только специально не было указано что-то иное

Здравствуйте!
Спасибо! Очень помогло.
Нашёл неточность:
systemctl start mysql
возвращает:
Failed to start mysql.service: Unit mysql.service failed to load: No such file or directory.
Переписал -
systemctl start mariadb

Это странно =) А репу mariadb точно подключили?

cat /etc/yum.repos.d/MariaDB.repo
[mariadb]
name = MariaDB
baseurl = http://yum.mariadb.org/10.0/centos7-amd64

systemctl status mysql
● mysql.service - LSB: start and stop MySQL
Loaded: loaded (/etc/rc.d/init.d/mysql)
Active: active (exited)

Похоже, что нет... Пардон! ))

Добавить комментарий

CAPTCHA
Этот вопрос задается для того, чтобы выяснить, являетесь ли Вы человеком или представляете из себя автоматическую спам-рассылку.
Target Image