Установка 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]". Находим их и меняем. Для наглядности спойлер ниже:
[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! Что же мы вообще ставим?! На самом деле - только всё необходимое. Кому интересно можно посмотреть спойлер:
- 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
Далее переходим к настройкам виртуальных хостов.
Создадим и отредактируем наш виртуальный хост:
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>
Ниже пояснения, если нужны... как сумел =)
- 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
Милости прошу под спойлер:
Нужно зайти в файл /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):
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
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; } }
Что тут есть?...
- Значит сначала стоит редирект с www на без www.
- Директива location указывает на корневую папку виртуального хоста и ищет и отдаёт из неё файлы (статику) с указанными расширениями. Разумеется, их можно изменить/дополнить. Если nginx не находит файла по указанному пути, он передаёт запрос дальше (сначала на varnish, потом apache). И backend уже сам разбирается, что с ним делать.
- Файлы начинающиеся с точки (скрытые файлы linux) ".*" (обычно .htacces, .htpasswd, .git и пр.) не отдавать "не под каким предлогом" =)
Ну, в целом всё. Можно проверить правильность настроек и запускать nginx:
nginx -t
systemctl start nginx
На этом настройки web-серверов закончены!
Теперь быстренько mariadb - и всё =)
Для начала надо посмотреть, какой конфиг у нас там прописан. Найти его можно по адресу:
nano /etc/my.cnf
Вообще правильная настройка БД - это целое искусство.... которым я, к сожалению, толком не обладаю =)
Предлагаю Вам несколько вариантов, как это сделать:
- Оставить всё как есть ^_^;
- Посмотреть разные конфиг-файлы, предлагаемые по умолчанию:
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
Внутри есть описания, но, по большому счёту, они отличаются количеством Вашей оперативной памяти;
- Зайти на сайт persona.com и создать там свой индивидуальный конфиг-файл.
Будем считать, что Вы справились с задачей выбора конфиг-файла и записали всё необходимое в файл настроек БД - /etc/my.cnf.
Далее, запускаем БД:
systemctl start mysql
И последний штрих - запустим настройку безопасности:
mysql_secure_installation
Здесь Вас попросят:
- Ввести пароль для root пользователя СУБД;
- Предложат удалить доступ для анонимных пользователей (обязательно соглашайтесь!);
- Убрать доступ root пользователю удалённо;
- Удалить тестовые БД и пользователя;
- Перезагрузить таблицу привилегий.
Ну, вот и всё =)
Буду очень рад уточнениям и вопросам - потому как большой объём статьи и вполне возможны опечатки и "что-то забыл" =)
Всем удачи!
Комментарии
Александр
11/05/2015 - 19:55
Постоянная ссылка (Permalink)
Спасибо за обновление
Спасибо за обновление толковой статьи!
Михаил
03/25/2016 - 21:26
Постоянная ссылка (Permalink)
Спасибо за статью!
Спасибо за статью!
Опечатка - Ну, а далее пуСть ваш лежит в поисковик =)
erian
03/25/2016 - 21:47
Постоянная ссылка (Permalink)
Благодарю, исправил. Хотя
Благодарю, исправил. Хотя "пусть" - более эпично =)
Михаил
03/26/2016 - 09:32
Постоянная ссылка (Permalink)
При проверке состояния Apache
При проверке состояния Apache у меня получилось:
AH00544: httpd: bad group name group
Решил так. Добавил группу:
groupadd users
и в файле domain.ru.conf заменил строку:
AssignUserID user group
на
AssignUserID user users
erian
03/26/2016 - 09:41
Постоянная ссылка (Permalink)
Всё верно, просто обычно
Всё верно, просто обычно имени пользователя есть соответствующая группа, если только специально не было указано что-то иное
Александр
04/26/2016 - 13:36
Постоянная ссылка (Permalink)
Здравствуйте!
Здравствуйте!
Спасибо! Очень помогло.
Нашёл неточность:
systemctl start mysql
возвращает:
Failed to start mysql.service: Unit mysql.service failed to load: No such file or directory.
Переписал -
systemctl start mariadb
erian
04/26/2016 - 15:18
Постоянная ссылка (Permalink)
Это странно =) А репу 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)
Александр
04/27/2016 - 10:22
Постоянная ссылка (Permalink)
Похоже, что нет... Пардон! ))
Похоже, что нет... Пардон! ))
Добавить комментарий