Настройка LEMP сервера для простых проектов. Инструкция для самых маленьких. Часть вторая

от автора

Данная статья является продолжением предыдущей статьи https://habr.com/ru/company/nixys/blog/645451/. Статья является обучающим материалом для начинающих администраторов, а также для разработчиков, которые хотели бы познакомиться с миром администрирования проектов. Если вы являетесь опытным администратором, можете смело пропускать данный материал.

Целью серии статей является описание подготовки работы сервера со стеком LEMP (Linux, Nginx, MySQL, PHP), отмечу, что в качестве PHP интерпретатора здесь используется Apache2, а не PHP-FPM, так как показывает практика многим разработчикам по прежнему необходим файл.htaccess, работу с которыми PHP-FPM из коробки не поддерживает.

Со своей стороны мы переносим правила из файла .htaccess в Nginx при необходимости установки PHP-FPM, однако это также занимает определенное время, зачастую разработчикам проще и быстрее внести нужные правила для текущих площадок именно в .htaccess файл. Также статьи описывают развертывание стэка и поднятие на нем работающих площадок. Инструкция подойдет для небольших Bitrix проектов, а тажке для проектов развернутых под любой популярной CMS.

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

Целью статей не является показать как развернуть идеальное окружение, а лишь указать на нюансы в работе и защитить начинающих специалистов от базовых ошибок при настройке.

Во второй частье статьи будут отражены такие темы как:

Базовая настройка Nginx
Базовая настройка Apache2
Базовая настройка MySQL

Базовая настройка Nginx  

После базовой настройки основных компонентов сервера, пора начинать настраивать веб-сервера, начнем с Nginx. Пакет уже находится в стандартных репозиториях Debian, поэтому выполняем простую установку:

apt update apt install nginx

Nginx в нашей конфигурации будет являться точкой входа http/https трафика и обрабатывать статичные данные. После установки начинаем конфигурировать веб-сервер, для этого переходим к файлу /etc/nginx/nginx.conf  и приводим его к следующему виду:

user www-data; worker_processes auto; worker_priority -15; include /etc/nginx/modules-enabled/*.conf;   error_log  /var/log/nginx/error.log; pid        /var/run/nginx.pid;   events {         worker_connections  1024; }   http {         include       /etc/nginx/mime.types;         default_type  application/octet-stream;           log_format nixys '$remote_addr\t"$host"\t[$time_local]\t$status\t"$request"\t$request_time ($upstream_response_time)\t$bytes_sent\t"$http_referer"\t"$http_user_agent"';         log_format nixys-debug '$remote_addr\t"$host"\t[$time_local]\t$status\t"$request"\t"req_time: $request_time"\t"bytes_sent: $bytes_sent"\n'                             '\t\t\t\t\t\t\t\t"req_file: $request_filename"\t"$http_user_agent"\t"$http_referer"\n'                                 '\t\t\t\t\t\t\t\t"Request completed: $request_completion"\n'                                 '\t\t\t\t\t\t\t\t"Body request: $request_body"\n';       access_log  /var/log/nginx/access.log nixys;           sendfileon;         tcp_nodelay on;       gzip on;         gzip_proxied any;         gzip_comp_level 4;         gzip_vary on;         gzip_types text/css text/plain application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript;       server_tokens off;       server_names_hash_bucket_size 33;         reset_timedout_connection on;           client_header_timeout 15;         client_body_timeout   15;         send_timeout       5;         keepalive_timeout  30 15;     include /etc/nginx/conf.d/*.conf;     include /etc/nginx/sites-enabled/*; } 

Пробегусь по основным изменениям, которые мы добавляем относительно стандартной конфигурации:

worker_priority -15;

Данная строка повышает приоритет процессов Nginx в системе. Это нужно для того, чтобы при высокой нагрузке приоритет обработки отдавался процессам Nginx, что позволит отображать статичные данные площадки

worker_connections  1024;

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

Обязательно включаем сжатие передаваемых данных:

gzip on; gzip_proxied any; gzip_comp_level 4; gzip_vary on; gzip_types text/css text/plain application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript;

Также хочется отметить следующий формат логов:

    log_format nixys '$remote_addr\t"$host"\t[$time_local]\t$status\t"$request"\t$request_time ($upstream_response_time)\t$bytes_sent\t"$http_referer"\t"$http_user_agent"';     log_format nixys-debug '$remote_addr\t"$host"\t[$time_local]\t$status\t"$request"\t"req_time: $request_time"\t"bytes_sent: $bytes_sent"\n'                            '\t\t\t\t\t\t\t\t"req_file: $request_filename"\t"$http_user_agent"\t"$http_referer"\n'                                 '\t\t\t\t\t\t\t\t"Request completed: $request_completion"\n'                                 '\t\t\t\t\t\t\t\t"Body request: $request_body"\n';

Здесь мы задаем два формата логов для Nginx. Формат логов Nixys будет являться основным, и использоваться для всех виртуальных хостов по умолчанию. Подключенные с ним логи выглядят следующим образом:

31.31.192.22 "site.ru"   [18/Dec/2021:06:26:50 +0500]200 "GET / HTTP/1.1"    0.028 (0.028)   13069   "-" "Mozilla/5.0 (compatible; InterfaxBot/1.0; email:swabuse@interfax.ru)" 

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

31.31.192.22 – IP адрес клиента

site.ru  — название виртуального хоста

18/Dec/2021:06:26:50 +0500 – время поступления запроса

200 – код ответа, полученный в результате выполнения запроса

0.028 – время обработки запроса Nginx

(0.028)   — время обработки запроса со стороны, которой Nginx передал запрос (при необходимости). В нашем случае здесь будет отражено время, за которое Apache2 обработал соединение.

13069   — это размер переданных данных в байтах

«Mozilla/5.0 (compatible; InterfaxBot/1.0; email:swabuse@interfax.ru)» – user-agent, переданные клиентом.

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

После внесения этих изменений необходимо перечитать файлы веб-сервера. При любой операции reload или restart сервиса Nginx необходимо обязательно протестировать конфигурацию на наличие ошибок с помощью команды nginx -t, многие администраторы вначале работы забывают об этом, что может привести к простоям в работе проекта:

nginx -t nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful

Если все ок, то перечитываем конфигурацию веб-сервера:

service nginx reload

И обязательно проверяем статус:

service nginx status ● nginx.service - A high performance web server and a reverse proxy server     Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled    Active: active (running) since Sun 2021-12-19 19:55:16 MSK; 36min ago  Docs: man:nginx(8)   Process: 2913 ExecReload=/usr/sbin/nginx -g daemon on; master_process on; -s reload (code=exited, status=0/SUCCESS)  Main PID: 2246 (nginx) Tasks: 3 (limit: 1171)    Memory: 9.3M    CGroup: /system.slice/nginx.service             ├─2246 nginx: master process /usr/sbin/nginx -g daemon on; master_process on;             ├─2914 nginx: worker process             └─2915 nginx: worker process

Обратите внимание, что после перезапуска любой службы необходимо обязательно проверить статус ее работы!

На этом базовую настройку Nginx можно считать завершенной.

Базовая настройка Apache2

Переходим к настройке Apache2. Устанавливаем необходимые пакеты:

apt install apache2 libapache2-mpm-itk

Если вы все делали по статье, то Apache2 сразу после установки не запустится и выдаст ошибку:

Action 'start' failed. The Apache error log may have more information. apache2.service: Control process exited, code=exited, status=1/FAILURE Failed with result 'exit-code'. Failed to start The Apache HTTP Server.

Дело в том, что веб-сервер по умолчанию работает на том же порту, что и запущенный Nginx. Поэтому нам потребуется изменить стандартный 80 порт веб сервера на 81. Для этого редактируем файл /etc/apache2/ports.conf и меняем порт: 

-Listen 80 +Listen 81

В нашем случае Apache2 работает с модулем mpm_prefork, поэтому включаем модуль командой:

a2enmod mpm_prefork

После нам потребуется задать параметры работы воркеров, данные параметры вы можете конфигурировать как угодно, в зависимости от нагрузки проекта; они расположены в файле /etc/apache2/mods-enabled/mpm_prefork.conf, базовая настройка выглядит следующим образом:

<IfModule mpm_prefork_module>         StartServers        5         MinSpareServers     3         MaxSpareServers     10         MaxRequestWorkers   50         MaxConnectionsPerChild  2000         LimitUIDRange       0 65535       LimitGIDRange       0 65535 </IfModule>

Для того, чтобы каждый раз при проверке синтаксиса Apache2 не всплывало сообщение о том, что имя сервера не объявлено, объявляем его в файле apache2.conf

ServerName MAIN_DOMAIN_NAME

Где MAIN_DOMAIN_NAME это имя основной площадки сервера.

Вам также потребуется привести default виртуальный хост веб-сервера к виду:

<VirtualHost *:81>     ServerName default     ServerAdmin webmaster@localhost     DocumentRoot /usr/share/apache2/default-site       ErrorLog ${APACHE_LOG_DIR}/error.log     CustomLog ${APACHE_LOG_DIR}/access.log combined </VirtualHost>

Изменять порт, на котором работает default виртуальный хост необходимо в соответствии с /etc/apache2/ports.conf. В дальнейшем вы увидите, что логи каждой площадки будут расположены в отдельной директории, однако логи стандартного виртульного хоста будут расположены согласно этим настройкам в /var/log/apache2.

Также очень важно настроить корректное отображение внешнего IP адреса клиентов в логах apache2, для этого потребуется активировать следующие модули с помощью команд:

a2enmod remoteip a2enmod rewrite

 Если после этого в логах apache2 площадки фигурирует 127.0.0.1, то необходимо также внести следующие изменения в формат логов:

--- apache2.conf_old2016-07-06 18:30:37.423038360 +0500  +++ apache2.conf    2016-07-06 18:27:32.874586631 +0500  @@ -204,8 +204,8 @@   # Use mod_remoteip instead.   LogFormat "%v:%p %h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" vhost_combined -LogFormat "%h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined -LogFormat "%h %l %u %t \"%r\" %>s %O" common +LogFormat "%a %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined +LogFormat "%a %l %u %t \"%r\" %>s %O" common  LogFormat "%{Referer}i -> %U" referer  LogFormat "%{User-agent}i" agent

Указываем кодировку СУБД по умолчанию, в нашем случае это UTF8, для этого вносим изменения в файл /etc/mysql/my.cnf:

diff --git a/mysql/my.cnf b/mysql/my.cnf  [mysqld] +character-set-server = utf8 +collation-server = utf8_unicode_ci

По умолчанию MySQL слушает только локальный IP адрес 127.0.0.1. В случае если необходимы подключения к СУБД извне, потребуется открыть порт 3306 на уровне фаервола сервера, а также указать MySQL слушать все интерфейсы сервера Для этого параметру bind-address указываем следующее значение:

bind-address = 0.0.0.0

Здесь же в файле my.cnf указываем базовые параметры для работы СУБД:

max_allowed_packet  = 32M thread_stack        = 512K thread_cache_size   = 64 open_files_limit    = 8192 max_connections     = 100 query_cache_limit   = 4M query_cache_size    = 16M

Данные параметры могут быть скорректированы под нужды проекта.

Для таблиц innodb задаем хранение в отдельных файлах, чтобы избежать возможных проблем, связанных с ростом файла ibdata1:

innodb_file_per_table

И задаем буфер для innodb обычно он равен 60-80% оперативной памяти сервера. Например, для сервера с количеством оперативной памяти 4GB можем выделить на буфер 3GB оперативной памяти:

innodb_buffer_pool_size = 3GB

Значение также можно скорректировать по мере необходимости.

В качестве безопасности, ограничиваем доступ к MySQL для пользователей системы:

chmod 750 /etc/mysql chown root:mysql /etc/mysql

Перезапускаем СУБД и проверяем статус работы:

service mysql restart service mysql status

Для того, чтобы каждый раз при входе в консоль MySQL не указывать пароль от root пользователя, создаем файл в домашней директории root и задаем ему права безопасности:

touch /root/.my.cnf chmod 600 /root/.my.cnf

Созданный файл должен иметь следующее содержание:

[client] password = MYSQL_ROOT_PASSWORD

Где MYSQL_ROOT_PASSWORD, это пароль от пользователя root.

Теперь для подключения к консоли MySQL от root достаточно просто ввести команду mysql:

mysql  Welcome to the MySQL monitor.  Commands end with ; or \g. Your MySQL connection id is 40559777 Server version: 5.7.31-34 Percona Server (GPL), Release '34', Revision '2e68637'  Copyright (c) 2009-2020 Percona LLC and/or its affiliates Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.  Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners.  Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.  mysql>

На этом базовую настройку MySQL можно считать завершенной.

Для оптимизации mysql вы можете использовать утилиту mysqltuner. Она есть в стандартных репозиториях. Суть ее в том, что с помощью скриптов анализируются параметры и текущие показатели mysql. В случае, если наблюдаются неоптимизированные параметры, утилита предложит изменить их. Ниже пример вывода анализа mysqltuner:

-------- Recommendations -----------------------------------------------------  General recommendations:      Run OPTIMIZE TABLE to defragment tables for better performance     Reduce your overall MySQL memory footprint for system stability     Adjust your join queries to always utilize indexes     When making adjustments, make tmp_table_size/max_heap_table_size equal     Reduce your SELECT DISTINCT queries without LIMIT clauses  Variables to adjust:    *** MySQL's maximum memory usage is dangerously high ***   *** Add RAM before increasing MySQL buffer variables ***      query_cache_size (> 16M)     join_buffer_size (> 16.0M, or always use indexes with joins)     tmp_table_size (> 128M)     max_heap_table_size (> 128M)     innodb_buffer_pool_size (>= 11G)

Заключение:

В последней третьей статье будут описаны:

  • Установка и настройка PHP

  • Процесс создания и настройки виртуальных хостов для веб-серверов.

  • Выдача SSH и FTP доступов для площадки

  • Настройка почтовых записей таким образом, чтобы почта отправляемая с сервера не попадала в СПАМ.

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

Спасибо за внимание!

 


ссылка на оригинал статьи https://habr.com/ru/company/nixys/blog/646023/