LEMP - это...
LEMP - представляет собой стек веб-технологий, который позволяет создать среду для работы, как слабо так и высоко нагруженных веб-приложений. LEMP является акронимом, каждая буква которого представляет следующие веб-технологии: L - Linux, E - Nginx, M - MySQL/MariaDB, P - PHP.
В данной статье рассмотрен пример установки LEMP-стека на VPS/VDS сервере под управлением операционной системы CentOS 7.
Перед началом установки стека LEMP рекомендуется обновить все ранее установленные пакеты приложений.
sudo yum update -y
Шаг #1: Настройка файервола
По умолчанию в CentOS 7 80-порт, на котором работает http-сервер, фильтруется файерволом. Доступ к 80-порту можно получить с локального хоста, но никак не с внешнего. Для того, чтобы другие компьютеры могли подключаться к нашему серверу по 80-порту (т.е могли просматривать сайты) нам необходимо его открыть, добавив новое правило работы межсетевого экрана, с помощью утилиты firewall-cmd
.
Для начала убедимся, что файервол у нас запущен и включен в автозапуск при перезагрузке сервера:
systemctl status firewalld;
systemctl is-enabled firewalld;
Если в результате выполнения команд вы видите такие слова как inactive
и disabled
соответственно, то это означает, что файевол у вас не работает и ваш сервер не защищен. Запустить файервол можно так:
sudo systemctl start firewalld;
sudo systemctl enable firewalld;
Убедившись, что файервол работает, создадим для него новое правило, которое добавляет сервисы http
и https
для работы на 80
и 443
портах соответственно в публичную зону (группа портов/сервисов, которые доступны для всех компьютеров).
sudo firewall-cmd --permanent --zone=public --add-service=http;
sudo firewall-cmd --permanent --zone=public --add-service=https;
Перезапустим службу firewalld
для того, чтобы изменения вступили в силу.
sudo systemctl restart firewalld
Убедимся в том, что службы http
и https
добавлены в публичную зону.
sudo firewall-cmd --zone=public --list-services
В появившейся строке результата, должны быть указаны слова http
и https
.
[meliorem@centos7 ~]$ sudo firewall-cmd --zone=public --list-services
ssh dhcpv6-client http https
Теперь, при удачно выполненных предыдущих действиях, ваши будущие сайты будут доступны для всех.
Шаг #2: Установка веб-сервера Nginx
Nginx (энджин экс) можно установить как минимум двумя способами.
Способ #1: Из репозитория EPEL-release
Так как Nginx не входит в набор пакетов доступных из базового репозитория, то скачать и установить его вы сможете его из репозитория EPEL-release.
EPEL-release, в некоторых дистрибутивах, может быть не установлен по-умолчанию, поэтому для начала нужно убедится, что он у вас есть.
yum list installed | grep epel-release
или
ls /etc/yum.repos.d | grep epel.repo

Если вы не видите никаких результатов для вышеуказанных команд, тогда EPEL репозитория у вас нет и его нужно установить.
sudo yum install epel-release -y
Далее устанавливаем сам веб-сервер nginx
sudo yum install nginx -y
Минус данного способа в том, что часто в EPEL репозитории хранится устаревшая версия пакета Nginx. Установленную версию можно проверить следующей командой:
nginx -v
Способ #2: Из собственного репозитория Nginx
Данный способ позволит установить последнюю стабильную версию Nginx прямо с сайта http://nginx.org, который мы укажем в репозитории как источник пакета.
Для этого необходимо создать новый файл nginx.repo
в каталоге /etc/yum.repos.d
.
sudo vi /etc/yum.repos.d/nginx.repo
Файл нужно наполнить следующим содержимым:
1 2 3 4 5 |
[nginx] name=nginx repo baseurl=http://nginx.org/packages/centos/$releasever/$basearch/ gpgcheck=0 enabled=1 |
Теперь установим Nginx, однако в качестве источника пакета автоматически будет выбран наш, только что созданный, репозиторий.
sudo yum install nginx -y
Включим Nginx и добавим его в автозапуск при перезагрузке системы.
sudo systemctl start nginx;
sudo systemctl enable nginx;
Уже сейчас можно проверить работоспособность сервера. Наберите ip-адрес вашей машины в адресной строке браузера и вам будет выдана проверочная страница /usr/share/nginx/html/index.html
.

Шаг #3: Настройка файла конфигурации Nginx
Настроим параметры в главном конфигурационном файле Nginx.
Перед любым начальным изменением конфигов, рекомендую создавать их копии.
sudo cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf_backup
Вы можете скачать представленный ниже Nginx конфиг следующей командой - sudo wget https://raw.githubusercontent.com/CharmingProjects/Conf-files/master/nginx.conf -O /etc/nginx/nginx.conf
Приступим к редактированию главного конфига Nginx.
sudo vi /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 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
user nginx; # Имя пользователя worker_processes auto; # Количество рабочих процессов worker_cpu_affinity auto; # Количество рабочих процессов на ядро pcre_jit on; # Компилятор регулярных выражений (снижает нагрузку на CPU) error_log /var/log/nginx/error.log crit; # Путь к логам критических ошибок error_log /var/log/nginx/warn.log warn; # Путь к логам предупреждений (не обязательно) pid /var/run/nginx.pid; # Путь для запуска главного процесса events { worker_connections 1024; # Количество соединений (1024-4096) multi_accept on; # Максимум параллельных соединений } http { include /etc/nginx/mime.types; default_type application/octet-stream; # Кэширование SSL сессий ssl_session_cache shared:SSL:50m; ssl_session_timeout 1h; # Определение формата логов 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 off; # Выключение логов о подключении (экономия памяти) access_log /var/log/nginx/access.log main; # Путь к логам о подключении # Заголовки и начало файла в одном пакете sendfile on; tcp_nopush on; tcp_nodelay on; # Соединения keepalive_timeout 30; # Время ожидания ответа от веб-сервера keepalive_requests 400; # Максимум запросов от одного соединения reset_timedout_connection on; # Сброс соединения если клиент отвалился client_body_timeout 30; # Время ожидания тела запроса от клиента client_header_timeout 20; # Время ожидания заголовка запроса от клиента send_timeout 20; # Сброс соединения если клиент перестал считывать ответ client_max_body_size 2m; # Ограничение размера тела запроса # client_body_buffer_size 128k; # client_body_temp_path /var/nginx/client_body_temp # types_hash_max_size 1000; # Размер таблицы служебных данных # server_names_hash_max_size 2048; # Размер таблицы хранения имен сайтов server_names_hash_bucket_size 64; server_tokens off; # Убираем инфу (версию) о сервере из заголовка server # Настройки проксирования # proxy_connect_timeout 5; # Время задержки проксирования # proxy_send_timeout 10; # Время задержки отправки # proxy_read_timeout 10; # Время задержки чтения # proxy_buffer_size 4k; # proxy_buffers 8 16k; # proxy_busy_buffers_size 64k; # proxy_temp_file_write_size 64k; # Сжатие трафика gzip on; # Включаем сжатие (ускоряет загрузку страниц) gzip_static on; gzip_disable "msie6"; # Отключаем сжатие для MS Explorer gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript application/msword application/rtf application/pdf application/x-font-ttf image/svg+xml image/x-icon; gzip_comp_level 7; # Уровень сжатия gzip_proxied any; # Использовать сжатие при проксировании gzip_min_length 1000; # Мин размер сжимаемого файла gzip_vary on; # etag off; # Кеширование open_file_cache max=200000 inactive=20s; # Макс кол-во кэшируемых файлов open_file_cache_valid 120s; # Время удаления кэша open_file_cache_min_uses 2; # Число обращения к файлу для кэширования # open_file_check_errors on; # Кэширование инфы об отсутствующих файлах # proxy_cache_valid 1m; # proxy_cache_key $scheme$proxy_host$reques_url$cookie_US # proxy_cache_path /usr/local/nginx/cache levels=1:2 keyz_zone=one:400M; # limit_conn_zone $binary_remote_addr zone=lone:10M; # limit_req_zone $binary_remote_addr zone=ltwo:10M rate=5r/s; # limit_req_zone $binary_remote_addr zone=lstrict:10M rate=1r/s; # limit_req_zone $binary_remote_addr zone=highload:10M rate=10r/s; include /etc/nginx/conf.d/*.conf; include /etc/nginx/sites-enabled/*.conf; # Подключаем файлы сервер-блоков сайтов } |
После сохранения изменений, рекомендую всегда проверять конфиг на ошибки в синтаксисе.
sudo nginx -t

Шаг #4: Создание и настройка сервер-блоков Nginx
Для создания возможности обработки нескольких доменов на одном ip-адресе, веб-сервер Apache использует виртуальные хосты - это специальные файлы конфигурации веб-сервера, которые настраиваются отдельно для каждого домена. В веб-сервере Nginx также присутствует такая возможность, однако в терминологии Nginx виртуальные хосты называются сервер-блоками.
Создание директорий для сайта
По умолчанию, Nginx создает один сервер-блок настроенный для обработки файлов из директории /usr/share/nginx/html
, однако для создания самостоятельных сервер-блоков для каждого отдельного домена рекомендуется использовать директорию /var/www
. Внутри каталога /var/www
создадим новый каталог с именем вашего домена, внутри которого также добавим нужные подкаталоги - www
, где будут хранится файлы сайта и log
, где будут хранится логи работы веб-сервера.
sudo mkdir -p /var/www/example.ru/{www,log}
Созданным директориям нужно присвоить владельца. Владельцем чаще всего назначается сам веб-сервер т.к. именно он проводит большинство операций с файлами.
Установка веб-сервера в качестве владельца особенно важна при установки каких-либо CMS-систем, например WordPress.
Так как нашим веб сервером будет Nginx, то и установим его в качестве владельца и группы. При необходимости группу можно будет заменить на любую удобную вам.
sudo chown -R nginx:nginx /var/www/example.ru/www
Также настроим права доступа для /var/www
sudo chmod -R 755 /var/www
Создание тестовой страницы.
Для проверки работоспособности будущего сервер-блока создадим главную страницу сайта - index.html
. При желании, вы можете создать полноценную html-разметку, однако я ограничусь простым текстом, которым заполню файл с помощью команды - echo.
touch /var/www/example.ru/www/index.html;
echo 'example.ru is working!' > /var/www/example.ru/www/index.html;
Создание сервер-блока
Изначально Nginx содержит только один сервер-блок с именем - default
, его мы будет использовать в качестве шаблона для наших собственных сервер-блоков.
Создадим необходимые для работы каталоги и файл для настроек сервер-блока:
sudo mkdir /etc/nginx/{sites-available,sites-enabled};
sudo vi /etc/nginx/sites-available/example.ru.conf;
Файл /etc/nginx/sites-available/example.ru.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 |
server { listen 80; server_name example.ru www.example.ru; set $root_path '/var/www/example.ru/www'; root $root_path; index index.php index.html; location / { try_files $uri $uri/ $uri.html $uri.php$is_args$query_string; } error_page 500 502 503 504 /50x.html; error_page 404 /404.php; location = /50x.html {root /usr/share/nginx/html;} #location = /404.php {root $root_path;} location ~ \.php$ { fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $request_filename; include fastcgi_params; fastcgi_intercept_errors on; } error_log /var/www/example.ru/log/nginx-error.log error; } |
Включение сервер-блоков
Теперь когда созданы сервер-блоки их нужно активировать, чтобы Nginx мог начать с ними работать.
Сделать это можно путем создания символической ссылки:
sudo ln -s /etc/nginx/sites-available/example.ru.conf /etc/nginx/sites-enabled/example.ru.conf
Убедитесь, что все конфигурационные файлы, для каждого домена, подключены в главном конфиге Nginx. Для этого в файле /etc/nginx/main.conf
должна присутствовать следующая строка.
include /etc/nginx/sites-enabled/*.conf;
Теперь, если все предыдущие этапы выполнены без ошибок, то вы можете зайти на страницу сайта, введя имя домена в адресную строку, в моем случае это example.ru.

Шаг #5: Установка и настройка MariaDB
MariaDB - это популярный форк MySQL, отличающийся большей производительностью и функциональностью по сравнению с обычным MySQL.
Установим основной пакет MariaDB, который подтянет все необходимые зависимости.
sudo yum install mariadb-server -y
Запустим MariaDB для дальнейшей работы.
systemctl start mariadb;
systemctl enable mariadb;
Далее необходимо настроить безопасность управления базами данных, с помощью небольшого скрипта, который скачался вместе MariaDB.
sudo mysql_secure_installation
В режиме диалога, Вам будут предложены следующие вопросы:
Если вам не предложили создать пароль во время загрузки сервера, то жмем enter и создаем сейчас.
Enter current password for root (enter for none):
Далее запрещаем анонимный доступ:
Remove anonymous users? [Y/n] y
Запрещаем удаленный доступ:
Disallow root login remotely? [Y/n] y
Удаляем ненужные тестовые базы данных:
Remove test database and access to it? [Y/n] y
Применяем только что выставленные настройки:
Reload privilege tables now? [Y/n] y
Настройка файла конфигурации MariaDB
В файле /etc/my.cnf хранятся все главные настройки для сервера баз данных.
Грамотно настроенная СУБД MariaDB будет производительнее работать и потреблять меньше оперативной памяти, что, например, для VPS/VDS серверов с памятью в 512мб является очень важным. Так как для своих проектов я арендую виртуальный выделенный сервер именно с 512мб памяти, то предлагаю вашему вниманию соответствующий файл конфига для MariaDB (/etc/my.cnf).
В реальности тюнинг MariaDB должен происходить согласно требованиям проектов, которые с ней работают. Отсюда следует сказать, что не существует универсального файла конфигурации, который бы работал у всех одинаково хорошо.
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 |
[mysqld] datadir=/var/lib/mysql socket=/var/lib/mysql/mysql.sock # Disabling symbolic-links is recommended to prevent assorted security risks symbolic-links=0 # Settings user and group are ignored when systemd is used. # If you need to run mysqld under a different user or group, # customize your systemd unit file for mariadb according to the # instructions in http://fedoraproject.org/wiki/Systemd low-priority-updates # Приоритет для чтения в ущерб записи skip-name-resolve # Не определяем домены клиентов, только IP (ускоряет соединение) max_allowed_packet=8M # Максималный размер данных передаваемых в одном запросе max_connections=128 # Максимальное количество параллельных соединений к серверу thread_cache_size=16 # Указывает число кэшируемых потоков query_cache_limit=1M # Максимальный размер кэшируемого запроса query_cache_size=10M # Размер кэша query_cache_min_res_unit=2M # Минимальный размер хранимого в кэше блока key_buffer_size=100M # Размер буфера, выделяемого под индексы и доступного всем потокам innodb_buffer_pool_size=150M # Размер памяти, выделяемый InnoDB для хранения и индексов и данных innodb_flush_method=O_DIRECT # Позволяет избежать двойного кеширования innodb_flush_log_at_trx_commit=2 # (2) Уменьшает вероятность потери данных в ущерб производительности [mysqld_safe] log-error=/var/log/mariadb/mariadb.log pid-file=/var/run/mariadb/mariadb.pid # # include all files from the config directory # !includedir /etc/my.cnf.d |
Теперь MariaDB готова к работе и созданию баз данных.
Шаг #6: Установка и настройка php-fpm
В отличии, например от Apache, Nginx самостоятельно работает только со статикой, если в запросе к нему попадается php код, то Nginx сам его не обрабатывает, а проксирует (передает) на специальный php-обработчик, в роли которого выступает один из php модулей - php-fpm (fastCGI process manager).
На момент написания статьи php-fpm последней версии 7.1 нельзя установить из стандартных репозиториев, поэтому в наш список репозиториев (/etc/yum.repos.d
) нужно добавить два дополнительных репозитория: EPEL-release и remirepo, а затем уже установить пакет php71w-fpm
, а также несколько других нужных модулей. Так установка EPEL-release описана ранее в шаге по установке Nginx, то сейчас коснемся только установки remirepo.
Установим репозиторий от remirepo.com:
sudo rpm -Uvh http://rpms.remirepo.net/enterprise/remi-release-7.rpm
Установим дополнительные инструменты для активации дополнительного репозитория remi-php71:
sudo yum install yum-utils;
sudo yum-config-manager --enable remi-php71;
Теперь, из уже подключенного репозитория установим необходимые php-пакеты:
- php-fpm - обработчик php кода для Nginx
- php-mysqlnd - содержит функции для работы с БД
- php-mbstring - содержит функции для работы со строками
- php-cli - позволяет запускать php код прямо в консоли
sudo yum install php-mysqlnd php-fpm php-mbstring php-cli -y
Запустим php-fpm.
systemctl start php-fpm;
systemctl enable php-fpm;
Настройка файла конфигурации php-fpm
Откроем главный конфиг php - /etc/php.ini
:
sudo vi /etc/php.ini
На данный момент нас интересует одна директива - cgi.fix_path_info
, которая "говорит" php, чтобы он выполнил любой ближайший файл, если изначально запрашиваемый файл не был найден.
Существует опасность в том, что пользователь может создавать вредоносные запросы на сервер, которые будут беспрепятственно выполнены, чего допустить никак нельзя. Чтобы этого не случилось, найдем директиву cgi.fix_path_info
, раскоментируем и отключим, установив ее параметр в значение - 0.
cgi.fix_path_info = 0
Также откройте для редактирования файл конфигурации php-fpm - /etc/php-fpm.d/www.conf
и измените в нем имя пользователя и группы (по умолчанию установлен пользователь apache). Это позволит избежать проблем с правами на запись файлов сайта.
user = nginx
group = nginx
Если вы используете тестовый сервер и вам необходимо выводить ошибки PHP когда они случаются, то также укажите следующие директивы.
php_admin_value[error_log] = /var/log/php-fpm/www-error.log
php_admin_flag[log_errors] = on
php_flag[display_errors] = on
php_flag[display_startup_errors] = on
После правки всех конфигов, перезапустим php-fpm.
systemctl restart php-fpm
Проверка работы php-скриптов
Создайте тестовый файл для сайта, например /var/www/example.ru/www/test.php
, и вставьте в него следующий код:
<?php phpinfo(); ?>
Далее в браузере перейдите по адресу example.ru/test.php, если на полученной странице отобразится результат выполнения функции phpinfo()
, то это значит, что php-код успешно обрабатывается и на этом установка LEMP-стека завершена.

Теперь файл /var/www/example.ru/www/test.php
нужно удалить.
Заключение
Выполнив все шаги установки LEMP-стека вы получаете полноценную рабочую среду для ваших проектов.