NGINX + Apache (httpd) + MariaDB (MySQL) + PHP + PHP-FPM (fastCGI) + FTP + PHPMyAdmin + Memcached + xCache + Postfix на CentOS 7
Веб-сервер, настроенный по данной инструкции можно будет использовать для размещения собственных сайтов в локальной сети или сети Интернет. Данная инструкция проверена для CentOS 7.
Тематические термины: Linux, CentOS, NGINX, Apache, MySQL, MariaDB, PHP-FPM, FTP, phpMyAdmin, Memcached, xCache, Postfix.
Содержание:
Общая настройка системы
Установка NGINX
Установка PHP и PHP-FPM
Установка MariaDB или MySQL
Установка phpMyAdmin
Установка Memcached
Установка xCache
Установка и настройка FTP-сервера
Apache (httpd)
Postfix
Тюнинг веб-сервера
Создание первого сайта
Общая настройка системы
Установка пакетов
1. Обновляем CentOS:
yum update
2. Устанавливаем репозиторий EPEL и пакет для загрузки:
yum install epel-release wget
Время
1. Устанавливаем часовой пояс:
timedatectl set-timezone Europe/Moscow
* данной командой мы установим часовой пояс по московскому времени.
2. Устанавливаем и запускаем службу для автоматической синхронизации времени:
yum install chrony
systemctl enable chronyd --now
Настройка безопасности
1. Отключаем SELinux:
sed -i "s/SELINUX=enforcing/SELINUX=disabled/" /etc/selinux/config
setenforce 0
* первая команда редактирует конфигурационный файл, чтобы SELinux не запускался автоматически, вторая — отключает его разово. Подробнее читайте статью Как отключить SELinux.
2. Открываем необходимые порты в брандмауэре:
firewall-cmd --permanent --add-port={80,443}/tcp
firewall-cmd --permanent --add-port={20,21,60000-65535}/tcp
firewall-cmd --reload
* 80, 443 порты для веб-сервера; 20, 21 порты нужны для работы FTP; 60000-65535 также необходимы для работы FTP (динамические порты для пассивного режима); последняя команда перезапускает firewalld, чтобы применить новые правила. Подробнее про настройку firewalld.
Установка NGINX
Устанавливаем NGINX:
yum install nginx
Внесем небольшую корректировку в файл nginx.conf:
vi /etc/nginx/nginx.conf
http {
...
server_names_hash_bucket_size 64;
....
}
* на практике, может встретиться ошибка could not build server_names_hash, you should increase server_names_hash_bucket_size: 32. Она возникает при большом количестве виртуальных серверов или если один из них будет иметь длинное название. Данная строка в конфиге исправит ситуацию.
Разрешаем автозапуск сервиса и запустим его:
systemctl enable nginx --now
Проверим, что веб-сервер работает. Для этого открываем браузер на другом компьютере, который находится в одной сети и вводим в адресной строке IP-адрес сервера. В итоге мы должны увидеть заголовок «Welcome to nginx!»:
* обратите внимание, что данное приветствие может иметь и другой вид.
Для настройки http/2 читайте соответствующую статью.
Установка PHP и PHP-FPM
Устанавливаем PHP и php-fpm следующей командой:
yum install php php-fpm
* В CentOS 7 будет установлена php версии 5.4. Если необходимо установить PHP 7 или 8, читайте статью Как установить PHP 7 / 8 на CentOS 7.
Запускаем php-fpm и разрешаем его автозапуск:
systemctl enable php-fpm --now
Настройка связки NGINX + PHP
Открываем файл для настройки виртуального домена по умолчанию. В зависимости от версии CentOS 7 пути могут различаться:
а) вариант 1:
vi /etc/nginx/conf.d/default.conf
б) вариант 2:
vi /etc/nginx/nginx.conf
в) вариант 3:
vi /etc/nginx/nginx.conf.default
В секции location редактируем параметр index на следующее значение:
location / {
index index.php index.html index.htm;
}
* добавляем index.php в начало списка. Если параметра index нет, создаем его.
А внутри секции server добавим следующее:
location ~ \.php$ {
set $root_path /usr/share/nginx/html;
fastcgi_pass unix:/run/php-fpm/www.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $root_path$fastcgi_script_name;
include fastcgi_params;
fastcgi_param DOCUMENT_ROOT $root_path;
}
* где /usr/share/nginx/html — корневой путь хранения скриптов; unix:/run/php-fpm/www.sock — файл для взаимодействия с php-fpm.
Открываем настройки php-fpm:
vi /etc/php-fpm.d/www.conf
Проверяем, настройки параметров:
listen = /run/php-fpm/www.sock
...
listen.group = nginx
* listen должен иметь значение /run/php-fpm/www.sock (путь до сокетного файла, который мы указали в конфигурационном файле nginx); listen.group указывает, какую группу назначить сокетному файлу.
... иначе, меняем значение. После перезагружаем php-fpm:
systemctl restart php-fpm
* в данном примере мы указываем, что php-fpm будет использовать сокетный файл /run/php-fpm/www.sock для взаимодействия. Этот файл мы указали выше в настройке NGINX.
Проверяем правильность настроек nginx:
nginx -t
И перезагружаем его:
systemctl restart nginx
Создаем index.php в каталоге сайта по умолчанию со следующим содержимым:
vi /usr/share/nginx/html/index.php
<?php phpinfo(); ?>
Открываем в браузере IP-адрес нашего сервера. Теперь мы должны увидеть сводную информацию по PHP и его настройкам, например:
Установка MariaDB или MySQL
В данной статье мы установим MariaDB, но процедура установки и настройки MySQL аналогичная. Все расхождения будут отмечены явно в инструкции.
Устанавливаем MariaDB следующей командой:
yum install mariadb-server
* будет установлена mariadb версии 5.5. Если нужна другая, то читаем подробнее в инструкции Установка MariaDB на CentOS или Ubuntu.
** для установки mysql выполняем команду yum install mysql
Разрешаем автозапуск и запускаем СУБД:
systemctl enable mariadb --now
* для работы с mysql меняем mariadb на mysql.
Сразу создаем пароль для учетной записи root:
mysqladmin -u root password
PHP + MariaDB (MySQL)
Для возможности подключаться к базе данных скриптами PHP необходимо установить следующие модули:
yum install php-mysqli
Если мы установили php5, также ставим php-mysql:
yum install php-mysql
После перезагружаем php-fpm:
systemctl restart php-fpm
И открываем наш сайт в браузере. В phpinfo появится новая секция MySQL:
* нас не должно смущать, что установили мы mariadb, а заголовок mysql. Если посмотреть в таблицу, можно увидеть ячейку Client API version, в которой указано, что используется именно mariadb.
Установка phpMyAdmin
Для установки phpMyAdmin вводим следующую команду:
yum install phpmyadmin
Однако, если мы устанавливали php версии 7 и выше, необходимо указать репозиторий, который мы использовали для этого, например:
yum --enablerepo=remi-php74 install phpmyadmin
* в данном примере предполагается, что мы использовали репозиторий remi-php74.
Это необходимо для корректной установки расширений PHP.
Теперь создадим для него отдельный виртуальный домен в NGINX:
vi /etc/nginx/conf.d/phpMyAdmin.conf
И добавим в него следующее содержимое:
server {
listen 80;
server_name phpmyadmin.dmosk.local;
set $root_path /usr/share/phpMyAdmin;
location / {
root $root_path;
index index.php;
}
location ~ \.php$ {
fastcgi_pass unix:/run/php-fpm/www.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $root_path$fastcgi_script_name;
include fastcgi_params;
fastcgi_param DOCUMENT_ROOT $root_path;
fastcgi_read_timeout 300;
}
}
* где phpmyadmin.dmosk.local — адрес для виртуального домена, именно этот адрес должен быть введен в адресную строку браузера, чтобы открылся нужный сайт. Поэтому есть нет возможность зарегистрировать домен и имя узла в DNS, можно воспользоваться локальным файлом hosts. /usr/share/phpMyAdmin — это каталог, в который по умолчанию устанавливается phpMyAdmin.
После перезапускаем NGINX:
systemctl reload nginx
Также нужно перезапустить php-fpm, так как в процессе установки был добавлен модуль mbstring:
systemctl restart php-fpm
И открываем в браузере наш домен, в данном примере, http://phpmyadmin.dmosk.local. Откроется форма для авторизации — вводим логин root и пароль, который мы указали после установки и запуска mariadb.
Установка Memcached
Первым этапом мы установим и настроим сервис memcached. Вторым — модуль php-memcached.
Сервис memcached
Выполняем установку пакетов:
yum install memcached
После разрешаем автозапуск и запускаем сервис кэширования:
systemctl enable memcached --now
Модуль для php
Установить компонент из репозитория:
yum install php-pecl-memcached
После устаноки модуля перезапускаем php-fpm:
systemctl restart php-fpm
Чтобы проверить, что модуль memcached работаем, открываем наш сайт в браузере — в phpinfo должна появиться новая секция:
... или вводим команду:
php -m | grep memcached
Мы должны получить:
memcached
Установка xCache
xCache не поддерживается в php7. Если мы установили именно эту версию, пропускаем установку данного пакета.
Запускаем установку xCache следующей командой:
yum install php-xcache
Перезапускаем php-fpm:
systemctl restart php-fpm
В phpinfo должно появиться следующее:
Установка и настройка FTP-сервера
В качестве FTP-сервера будем использовать ProFTPd, так как он позволяет авторизовываться под uid системных учетных записей. Для его установки вводим следующую команду:
yum install proftpd proftpd-utils
Создаем каталог для хранения настроек:
mkdir /etc/proftpd.d
Создаем виртуального пользователя:
ftpasswd --passwd --file=/etc/proftpd.d/ftpd.passwd --name=ftpwww --uid=48 --gid=48 --home=/var/www --shell=/sbin/nologin
* где /etc/proftpd/ftpd.passwd — путь до файла, в котором хранятся пользователи; ftpwww — имя пользователя (логин); uid и gid — идентификаторы пользователя и группы системной учетной записи (apache); /var/www — домашний каталог пользователя; /sbin/nologin — оболочка, запрещающая локальный вход пользователя в систему.
Открываем на редактирование конфигурационный файл proftpd:
vi /etc/proftpd.conf
И редактируем следующее (комментируем):
#AuthOrder ...
В конце файла добавим следующее:
UseIPv6 off
IdentLookups off
PassivePorts 60000 65535
RequireValidShell off
AuthUserFile /etc/proftpd.d/ftpd.passwd
AuthPAM off
LoadModule mod_auth_file.c
AuthOrder mod_auth_file.c
* где 60000 - 65535 — диапазон динамических портов для пассивного режима.
Разрешаем автозапуск FTP-серверу и запускаем его:
systemctl enable proftpd --now
Пробуем подключиться к серверу, использую любые FTP-клиенты, например, FileZilla, Total Commander или тот же браузер.
Это базовая и самая простая настройка ProFTPd, но если необходимо настроить TLS или хранить виртуальных пользователей в базе MySQL, читайте подробнее инструкцию по настройке ProFTPd на CentOS 7.
Apache (httpd)
Несмотря на то, что мы установили и настроили PHP-FPM, Apache нам понадобится, как минимум, по двум причинам. Во-первых, многие сайты используют файл .htaccess, который читает только Apache. Во-вторых, последний включает большое число модулей, которые может использовать портал.
В некоторых случаях, можно обойтись без Apache, но в данной инструкции мы опишем процедуру его установки и настройки.
И так, устанавливаем httpd:
yum install httpd
Заходим в настройки:
vi /etc/httpd/conf/httpd.conf
И редактируем следующее:
Listen 8080
* наш веб-сервер будет слушать на порту 8080, так как на 80 уже работает NGINX.
<IfModule dir_module>
DirectoryIndex index.php index.html
</IfModule>
* если не указан конкретный скрипт, сначала веб-сервер пытается найти и запустить index.php, затем index.html
Добавляем:
<Directory /var/www/*/www>
AllowOverride All
Options Indexes ExecCGI FollowSymLinks
Require all granted
</Directory>
* где Directory — разрешенные каталоги для запуска из apache; Options — разрешенные опции; Require — с каких IP-адресов можно открывать сайты, определенные в данном каталоге. Итого, мы разрешаем все каталоги в /var/www, но только если следующий каталог будет www; разрешаем опции Indexes (возвращает список файлов, если нет индексного файла, например, index.php), ExecCGI (разрешены сценарии CGI), FollowSymLinks (включены символические ссылки в этом каталоге); доступ для данных каталого разрешен со всех адресов (all granted).
Проверяем синтаксис конфигурационного файла httpd:
apachectl configtest
Разрешаем автозапуск и запускаем службу:
systemctl enable httpd --now
Создаем php-файл со следующим содержимым:
vi /var/www/html/index.php
<?php phpinfo(); ?>
Открываем браузер и вводим в адресную строку IP-адрес нашего сервера и добавляем :8080. Мы должны увидеть привычную страницу:
NGINX + Apache
Ранее нами была настроена связка nginx + php-fpm. Теперь проверяем совместную работу первого с apache.
Открываем конфигурационный файл nginx:
vi /etc/nginx/conf.d/default.conf
* если при настройке nginx мы редактировали файл /etc/nginx/nginx.conf, то необходимо открыть его.
Находим наш настроенный location для php-fpm:
...
location ~ \.php$ {
fastcgi_pass unix:/run/php-fpm/www.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $root_path$fastcgi_script_name;
include fastcgi_params;
fastcgi_param DOCUMENT_ROOT $root_path;
}
...
и меняем на:
...
location ~ \.php$ {
proxy_pass http://127.0.0.1:8080;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
...
Проверяем и перезапускаем nginx:
nginx -t
systemctl restart nginx
Пробуем открыть в браузере IP-адрес нашего сервера — должна открыться та же страница, что при проверке Apache (с добавлением 8080):
Apache Real IP
Так как все запросы на httpd приходят от NGINX, они воспринимаются как от IP-адреса 127.0.0.1. На практике, это может привести к проблемам, так как некоторым сайтам необходимы реальные адреса посетителей.
Для решения проблемы будем использовать модуль mod_rpaf. Устанавливаем набор разработчика для apache:
yum install httpd-devel gcc unzip
Переходим в каталог /usr/local/src:
cd /usr/local/src
Скачиваем модуль:
wget https://github.com/gnif/mod_rpaf/archive/stable.zip
Распаковываем его:
unzip stable.zip
Переходим в распакованный каталог:
cd mod_rpaf-stable/
Собираем модуль и устанавливаем его:
make
make install
* при возникновении ошибки ./apxs.sh: line 15: -c: command not found, необходимо поставить which командой yum install which.
Создаем конфигурационный файл со следующим содержимым:
vi /etc/httpd/conf.d/mod_rpaf.conf
LoadModule rpaf_module modules/mod_rpaf.so
RPAF_Enable On
RPAF_ProxyIPs 127.0.0.1
RPAF_SetHostName On
RPAF_SetHTTPS On
RPAF_SetPort On
RPAF_ForbidIfNotProxy Off
Перезапускаем httpd:
systemctl restart httpd
Для проверки настройки открываем на редактирование созданный index-файл для httpd:
vi /var/www/html/index.php
И редактируем содержимое на:
<?php echo $_SERVER['REMOTE_ADDR'] ?>
Открываем браузер и вводим в адресную строку IP-адрес нашего сервера. Мы должны увидеть внешний адрес компьютера, с которого обращаемся к серверу.
Postfix
В CentOS postfix уже установлен и запущен. Нам необходимо сделать несколько простых настроек:
vi /etc/postfix/main.cf
myorigin = $mydomain
smtp_generic_maps = hash:/etc/postfix/generic_map
* где myhostname — имя узла для почтового сервера (его он будет использовать в представлениях другим почтовым серверам); mydomain — домен сервера; myorigin — имя домена, которое будет подставляться всем отправляемым сообщениям без явного указания оного; smtp_generic_maps указывает на карту с общими правилами пересылки.
Открываем карту пересылки:
vi /etc/postfix/generic_map
И добавляем:
@dmosk.local no-reply@dmosk.local
* данной настройкой мы будем подставлять всем отправляемым письмам без поля FROM адрес no-reply@dmosk.local.
Создаем карту:
postmap /etc/postfix/generic_map
Для применения настроек перезагружаем почтовый сервер:
systemctl restart postfix
Тюнинг веб-сервера
PHP
Открываем на редактирование следующий файл:
vi /etc/php.ini
И правим следующее:
upload_max_filesize = 256M
post_max_size = 256M
short_open_tag = On
date.timezone = "Europe/Moscow"
Перезапускаем php-fpm и httpd:
systemctl restart php-fpm
systemctl restart httpd
NGINX
Открываем на редактирование следующий файл:
vi /etc/nginx/nginx.conf
И правим следующее:
worker_processes auto;
И внутри секции http добавляем:
client_max_body_size 256M;
После перезапускаем nginx:
systemctl restart nginx
Подробнее про тюнинг NGINX в статье Практические советы по тюнингу веб-сервера NGINX.
Postfix
Чтобы отправляемая почта меньше попадала в СПАМ, необходимо выполнить следующие шаги:
- Прописать PTR-запись.
- Создать запись SPF.
- Настроить DKIM.
Создание первого сайта
Задаем переменную, значение которой будет домен сайта:
TMP_SITE=site1
* где site1 — имя домена. Нам будет намного удобнее копировать и вставлять команды с переменной (не придется править после копипасты).
Создаем новый файл виртуального домена NGINX:
vi /etc/nginx/conf.d/$TMP_SITE.conf
* обязательно на конце должен быть .conf, так как только такие файлы веб-сервер подгружает в конфигурацию.
И добавляем следующее содержимое.
Для HTTP:
server {
listen 80;
server_name site1.local www.site1.local;
set $root_path /var/www/site1/www;
access_log /var/www/site1/log/nginx/access_log;
error_log /var/www/site1/log/nginx/error_log;
gzip on;
gzip_disable "msie6";
gzip_min_length 1000;
gzip_vary on;
gzip_proxied expired no-cache no-store private auth;
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript;
root $root_path;
location / {
proxy_pass http://127.0.0.1:8080/;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location ~* ^.+\.(jpg|jpeg|gif|png|css|zip|tgz|gz|rar|bz2|doc|docx|xls|xlsx|exe|pdf|ppt|tar|wav|bmp|rtf|js)$ {
expires modified +1w;
}
}
* где site1.local — домен, для которого создается виртуальный домен; /var/www/site1 — каталог, в котором будет размещаться сайт.
** все запросы будут переводиться на локальный сервер, порт 8080, на котором работает apache, кроме обращений к статическим файла (jpg, png, css и так далее).
*** обратите внимание на выделения полужирным — здесь нужно подставить свои данные.
Для HTTPS:
server {
listen 80;
server_name site1.local www.site1.local;
location ~ /.well-known {
root /usr/share/nginx/html;
allow all;
}
if ($uri !~ /.well-known){
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl;
ssl on;
ssl_certificate /etc/nginx/ssl/cert.pem;
ssl_certificate_key /etc/nginx/ssl/cert.key;
server_name site1.local www.site1.local;
set $root_path /var/www/site1/www;
access_log /var/www/site1/log/nginx/access_log;
error_log /var/www/site1/log/nginx/error_log;
gzip on;
gzip_disable "msie6";
gzip_min_length 1000;
gzip_vary on;
gzip_proxied expired no-cache no-store private auth;
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript;
root $root_path;
location ~ /.well-known {
root /usr/share/nginx/html;
allow all;
}
location / {
proxy_pass http://127.0.0.1:8080/;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location ~* ^.+\.(jpg|jpeg|gif|png|css|zip|tgz|gz|rar|bz2|doc|docx|xls|xlsx|exe|pdf|ppt|tar|wav|bmp|rtf|js)$ {
expires modified +1w;
}
}
* в первой секции server мы перенаправляем все запросы по незащищенному http на https.
** ssl_certificate и ssl_certificate_key — пути к публичному и приватному ключам соответственно.
*** для получения бесплатного сертификата читайте статью Получение бесплатного SSL сертификата Let's Encrypt.
Теперь создаем виртуальный домен в Apache:
vi /etc/httpd/conf.d/$TMP_SITE.conf
<VirtualHost *:8080>
Define root_domain site1.local
Define root_path /var/www/site1
ServerName ${root_domain}
ServerAlias www.${root_domain}
DocumentRoot ${root_path}/www
ErrorLog ${root_path}/log/apache/error_log
TransferLog ${root_path}/log/apache/access_log
php_admin_value upload_tmp_dir ${root_path}/tmp
php_admin_value doc_root ${root_path}
php_admin_value open_basedir ${root_path}:/usr/local/share/smarty:/usr/local/share/pear
php_admin_value session.save_path 0;0660;${root_path}/tmp
</VirtualHost>
Создаем каталоги для сайта:
mkdir -p /var/www/$TMP_SITE/{www,tmp}
mkdir -p /var/www/$TMP_SITE/log/{nginx,apache}
Создаем индексный файл со следующим содержимым:
vi /var/www/$TMP_SITE/www/index.php
<?php echo "<h1>Hello from site1</h1>"; ?>
Задаем права на папки:
chown -R apache:apache /var/www/$TMP_SITE
chmod -R 775 /var/www/$TMP_SITE
Проверяем корректность настроек конфигурационных файлов:
nginx -t
apachectl configtest
Перезапускаем веб-сервер:
systemctl reload nginx
systemctl reload httpd
Открываем сайт в браузере.
При необходимости, создаем базу данных.
mysql -uroot -p
> CREATE DATABASE site1 DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;
> CREATE USER 'dbuser'@'localhost' IDENTIFIED BY 'password';
> GRANT ALL PRIVILEGES ON site1.* TO dbuser@localhost;
* данными sql-командами мы создаем базу данных site1 и предоставляем к ней доступ для учетной записи dbuser с паролем password.