LEMP-стек (Linux, Nginx, MySQL, PHP) является одним из самых популярных и эффективных решений для разработки и развертывания современных веб-приложений. В отличие от классического LAMP-стека, использующего Apache, LEMP использует более легкий и производительный веб-сервер Nginx, что делает его идеальным выбором для высоконагруженных проектов.
В этой статье я поделюсь полным пошаговым руководством по настройке LEMP-стека от чистой установки Linux до полностью готовой к production среды. Мы уделим особое внимание безопасности, производительности и отказоустойчивости — ключевым аспектам любой production-системы.
Настройка production-сервера — это не просто установка компонентов по умолчанию, а тщательно спланированный процесс, учитывающий особенности проекта, ожидаемую нагрузку и требования к безопасности. Инвестиция времени в правильную настройку окупится многократно в будущем.
Данное руководство ориентировано на Ubuntu 22.04 LTS, но большинство команд и принципов применимы и к другим современным дистрибутивам Linux. Для максимальной эффективности рекомендую выполнять каждый шаг последовательно, так как многие настройки взаимосвязаны.
1. Подготовка сервера
Правильная подготовка сервера закладывает фундамент для стабильной и безопасной работы всего LEMP-стека. Начнем с базовой настройки свежеустановленной системы Ubuntu 22.04 LTS.
Обновление системы
Первым делом необходимо обновить все пакеты системы до последних версий:
# Обновление списка пакетов sudo apt update # Установка обновлений sudo apt upgrade -y # Перезагрузка сервера при необходимости sudo reboot
Настройка имени хоста и часового пояса
Установим правильное имя хоста и настроим часовой пояс:
# Установка имени хоста sudo hostnamectl set-hostname your-server-name # Настройка часового пояса sudo timedatectl set-timezone Europe/Moscow # Замените на ваш часовой пояс # Проверка настроек времени timedatectl
Создание непривилегированного пользователя
Для повышения безопасности создадим отдельного пользователя с правами sudo:
# Создание нового пользователя sudo adduser webadmin # Добавление пользователя в группу sudo sudo usermod -aG sudo webadmin # Проверка доступа su - webadmin sudo whoami # Должно вернуть "root"
Совет
Для дополнительной безопасности настройте аутентификацию по SSH-ключам вместо паролей. Это значительно снижает риск несанкционированного доступа к вашему серверу.
# На локальном компьютере (если ключа еще нет) ssh-keygen -t ed25519 -C "ваш_email@example.com" # Копирование публичного ключа на сервер ssh-copy-id webadmin@your_server_ip # На сервере - отключение парольной аутентификации sudo nano /etc/ssh/sshd_config # Установите следующие параметры: # PasswordAuthentication no # PubkeyAuthentication yes # PermitRootLogin no # Перезапуск SSH-сервера sudo systemctl restart sshd
Настройка брандмауэра
Установим и настроим UFW (Uncomplicated Firewall) для контроля сетевого доступа:
# Установка UFW, если он еще не установлен sudo apt install ufw # Настройка базовых правил sudo ufw default deny incoming sudo ufw default allow outgoing # Разрешение SSH для предотвращения потери доступа sudo ufw allow ssh # Разрешение веб-трафика sudo ufw allow 80/tcp sudo ufw allow 443/tcp # Включение брандмауэра sudo ufw enable # Проверка статуса sudo ufw status verbose
Настройка swap-файла
Для серверов с ограниченным объемом RAM полезно настроить swap-пространство:
# Проверка текущего swap sudo swapon --show # Создание swap-файла (2GB в данном примере) sudo fallocate -l 2G /swapfile sudo chmod 600 /swapfile sudo mkswap /swapfile sudo swapon /swapfile # Настройка автоматического монтирования при загрузке echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab # Настройка оптимальных параметров использования swap sudo sysctl vm.swappiness=10 sudo sysctl vm.vfs_cache_pressure=50 # Для сохранения настроек при перезагрузке echo 'vm.swappiness=10' | sudo tee -a /etc/sysctl.conf echo 'vm.vfs_cache_pressure=50' | sudo tee -a /etc/sysctl.conf
Важно!
На виртуальных серверах с SSD-дисками вместо fallocate рекомендуется использовать dd для создания swap-файла, чтобы избежать проблем с разреженными файлами:
sudo dd if=/dev/zero of=/swapfile bs=1M count=2048 status=progress
Установка базовых инструментов мониторинга
Установим необходимые утилиты для наблюдения за работой сервера:
# Установка базовых инструментов sudo apt install -y htop iotop iftop ncdu net-tools dnsutils curl wget unzip
2. Установка и настройка Nginx
Nginx — высокопроизводительный веб-сервер, обратный прокси-сервер и балансировщик нагрузки. Его асинхронная архитектура делает его более эффективным при обработке множества одновременных соединений по сравнению с Apache.
Установка Nginx из официального репозитория
Для получения наиболее свежих версий установим Nginx из официального репозитория:
# Добавление официального репозитория Nginx sudo apt install -y curl gnupg2 ca-certificates lsb-release ubuntu-keyring curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor | sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null # Добавление стабильного репозитория echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] http://nginx.org/packages/ubuntu `lsb_release -cs` nginx" | sudo tee /etc/apt/sources.list.d/nginx.list # Обновление списка пакетов и установка Nginx sudo apt update sudo apt install -y nginx # Запуск Nginx и включение автозапуска sudo systemctl start nginx sudo systemctl enable nginx # Проверка статуса sudo systemctl status nginx
Базовая конфигурация Nginx
Настроим основной конфигурационный файл Nginx с оптимальными параметрами для production:
# Создание резервной копии конфигурации sudo cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.backup # Редактирование основной конфигурации sudo nano /etc/nginx/nginx.conf
Заменим содержимое файла на следующую оптимизированную конфигурацию:
user nginx; worker_processes auto; pid /var/run/nginx.pid; # Оптимизация количества одновременных подключений на рабочий процесс events { worker_connections 1024; multi_accept on; use epoll; } http { # Основные настройки sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; types_hash_max_size 2048; server_tokens off; # Размер буфера и таймауты client_max_body_size 100M; client_body_timeout 12; client_header_timeout 12; send_timeout 10; # Буферизация client_body_buffer_size 10K; client_header_buffer_size 1k; large_client_header_buffers 4 4k; # Включаем сжатие для экономии трафика gzip on; gzip_vary on; gzip_proxied any; gzip_comp_level 6; gzip_buffers 16 8k; gzip_http_version 1.1; gzip_min_length 256; gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy; # Кеш открытых файловых дескрипторов open_file_cache max=1000 inactive=20s; open_file_cache_valid 30s; open_file_cache_min_uses 5; open_file_cache_errors on; # Логирование access_log /var/log/nginx/access.log; error_log /var/log/nginx/error.log; # MIME-типы include /etc/nginx/mime.types; default_type application/octet-stream; # Включение виртуальных хостов include /etc/nginx/conf.d/*.conf; include /etc/nginx/sites-enabled/*; }
Проверка конфигурации и перезапуск Nginx
После внесения изменений важно проверить конфигурацию на наличие ошибок перед перезапуском:
# Проверка синтаксиса конфигурации sudo nginx -t # Если ошибок нет, перезапускаем Nginx sudo systemctl restart nginx
Создание структуры каталогов для сайтов
Подготовим структуру каталогов для наших будущих сайтов:
# Создание основного каталога для веб-сайтов sudo mkdir -p /var/www/sites # Создание каталога для стандартного сайта sudo mkdir -p /var/www/sites/default/public # Установка корректных прав доступа sudo chown -R nginx:nginx /var/www/sites sudo chmod -R 755 /var/www/sites # Создание тестовой страницы echo '<!DOCTYPE html> <html> <head> <title>Welcome to LEMP Stack</title> <style> body { font-family: Arial, sans-serif; margin: 40px; line-height: 1.6; } h1 { color: #336699; } </style> </head> <body> <h1>Welcome to your LEMP Stack</h1> <p>If you see this page, Nginx is successfully installed and working.</p> <p>This is the default test page.</p> <p>Server time: <?php echo date("Y-m-d H:i:s"); ?></p> <p>PHP Version: <?php echo phpversion(); ?></p> </body> </html>' | sudo tee /var/www/sites/default/public/index.php
Настройка базового виртуального хоста
Создадим базовую конфигурацию виртуального хоста:
# Создание конфигурационного файла sudo nano /etc/nginx/conf.d/default.conf
Содержимое базового конфигурационного файла:
server { listen 80 default_server; listen [::]:80 default_server; server_name _; root /var/www/sites/default/public; index index.php index.html index.htm; # Логи для данного виртуального хоста access_log /var/log/nginx/default.access.log; error_log /var/log/nginx/default.error.log; # Настройка для статических файлов location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg)$ { expires 30d; add_header Cache-Control "public, no-transform"; } # Основная обработка PHP location ~ \.php$ { try_files $uri =404; fastcgi_pass unix:/run/php-fpm/php-fpm.sock; # Будет настроено позже fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; fastcgi_intercept_errors on; fastcgi_buffer_size 16k; fastcgi_buffers 4 16k; } # Защита от доступа к скрытым файлам location ~ /\. { deny all; access_log off; log_not_found off; } # Обработка основных запросов location / { try_files $uri $uri/ /index.php?$query_string; } }
Совет
Эта базовая конфигурация будет служить шаблоном для всех ваших сайтов. На данном этапе она не будет полностью работать, так как мы еще не настроили PHP-FPM. Но создание структуры конфигурации сейчас поможет нам избежать проблем в дальнейшем.
Проверим конфигурацию и перезапустим Nginx:
sudo nginx -t sudo systemctl restart nginx
3. Установка и защита MySQL
MySQL — одна из самых популярных реляционных систем управления базами данных. Она обеспечивает надежное хранение данных для ваших веб-приложений и отлично интегрируется с PHP.
Установка MySQL
Установим MySQL Server из стандартных репозиториев:
# Установка MySQL sudo apt install -y mysql-server # Проверка статуса сервиса sudo systemctl status mysql # Включение автозапуска sudo systemctl enable mysql
Безопасная настройка MySQL
Запустим скрипт безопасной настройки для удаления тестовых баз данных, анонимных пользователей и настройки безопасного доступа:
# Запуск мастера безопасной настройки sudo mysql_secure_installation
При запуске скрипта вам будет предложено выполнить следующие шаги:
- Настроить компонент проверки надежности паролей (рекомендуется выбрать политику STRONG)
- Установить надежный пароль для пользователя root
- Удалить анонимных пользователей (рекомендуется выбрать "Да")
- Запретить удаленный вход для пользователя root (рекомендуется выбрать "Да")
- Удалить тестовую базу данных (рекомендуется выбрать "Да")
- Перезагрузить таблицы привилегий (рекомендуется выбрать "Да")
Оптимизация конфигурации MySQL
Теперь настроим основные параметры производительности MySQL. Создадим конфигурационный файл:
# Создание конфигурационного файла sudo nano /etc/mysql/conf.d/mysql-optimization.cnf
Содержимое файла оптимизации (параметры подходят для сервера с 4 ГБ RAM):
[mysqld] # Оптимизация производительности innodb_buffer_pool_size = 1G innodb_log_file_size = 256M innodb_flush_method = O_DIRECT innodb_flush_log_at_trx_commit = 2 query_cache_type = 1 query_cache_size = 64M query_cache_limit = 2M max_connections = 150 table_open_cache = 2000 tmp_table_size = 64M max_heap_table_size = 64M join_buffer_size = 4M read_buffer_size = 3M read_rnd_buffer_size = 4M sort_buffer_size = 4M # Оптимизация для InnoDB innodb_file_per_table = 1 innodb_buffer_pool_instances = 4 innodb_read_io_threads = 4 innodb_write_io_threads = 4 innodb_io_capacity = 1000 # Настройки журнала slow_query_log = 1 slow_query_log_file = /var/log/mysql/mysql-slow.log long_query_time = 2 log_queries_not_using_indexes = 1 log_error = /var/log/mysql/error.log # Безопасность max_allowed_packet = 16M symbolic-links = 0 local_infile = 0
Важно!
Параметры MySQL сильно зависят от доступных ресурсов сервера и характера нагрузки. Указанные значения подойдут для стандартных веб-приложений на сервере с 4 ГБ RAM. Для высоконагруженных проектов или серверов с другими характеристиками необходима дополнительная настройка.
Применим настройки, перезапустив MySQL:
sudo systemctl restart mysql
Создание пользователя и базы данных для приложения
Вместо использования пользователя root, создадим отдельного пользователя для работы с базой данных:
# Подключение к MySQL sudo mysql # В командной строке MySQL выполним: CREATE DATABASE example_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; # Создание пользователя с доступом только с localhost CREATE USER 'example_user'@'localhost' IDENTIFIED BY 'StrongPassword123!'; # Предоставление привилегий пользователю только для созданной базы данных GRANT ALL PRIVILEGES ON example_db.* TO 'example_user'@'localhost'; # Применение изменений FLUSH PRIVILEGES; # Выход из MySQL EXIT;
Совет
Используйте уникальные, случайно генерируемые пароли для каждой базы данных. Для их генерации можете использовать команду:
openssl rand -base64 24
Настройка мониторинга производительности
Для отслеживания производительности MySQL установим инструмент MySQLTuner:
# Скачивание MySQLTuner sudo mkdir -p /opt/mysql-tools cd /opt/mysql-tools sudo wget https://raw.githubusercontent.com/major/MySQLTuner-perl/master/mysqltuner.pl sudo chmod +x mysqltuner.pl # Создание символической ссылки для удобства использования sudo ln -s /opt/mysql-tools/mysqltuner.pl /usr/local/bin/mysqltuner # Проверка и получение рекомендаций (запускать после нескольких дней работы) # sudo mysqltuner
4. Установка и оптимизация PHP-FPM
PHP-FPM (FastCGI Process Manager) — это альтернативная реализация PHP FastCGI с дополнительными возможностями, полезными для высоконагруженных сайтов. В отличие от mod_php для Apache, PHP-FPM работает как отдельный процесс и хорошо интегрируется с Nginx.
Установка PHP-FPM и необходимых модулей
Установим PHP 8.1 и основные модули, необходимые для большинства веб-приложений:
# Установка PHP-FPM и основных модулей sudo apt install -y php8.1-fpm php8.1-mysql php8.1-curl php8.1-gd php8.1-intl php8.1-mbstring php8.1-xml php8.1-zip php8.1-bcmath php8.1-cli # При необходимости можно установить дополнительные модули sudo apt install -y php8.1-soap php8.1-ldap php8.1-imagick php8.1-redis php8.1-memcached # Проверка статуса службы sudo systemctl status php8.1-fpm # Включение автозапуска sudo systemctl enable php8.1-fpm
Оптимизация PHP-FPM
Настроим конфигурацию PHP-FPM для оптимальной производительности:
# Создание резервной копии конфигурации sudo cp /etc/php/8.1/fpm/pool.d/www.conf /etc/php/8.1/fpm/pool.d/www.conf.backup # Редактирование конфигурации пула www sudo nano /etc/php/8.1/fpm/pool.d/www.conf
Отредактируйте следующие параметры в конфигурационном файле:
; Изменение пользователя и группы на nginx user = nginx group = nginx ; Использование Unix-сокета вместо TCP/IP для большей производительности listen = /run/php-fpm/php-fpm.sock listen.owner = nginx listen.group = nginx listen.mode = 0660 ; Настройка динамического управления процессами pm = dynamic pm.max_children = 50 pm.start_servers = 5 pm.min_spare_servers = 5 pm.max_spare_servers = 35 pm.max_requests = 500 ; Логирование slowlog = /var/log/php-fpm/www-slow.log request_slowlog_timeout = 10s php_admin_value[error_log] = /var/log/php-fpm/www-error.log php_admin_flag[log_errors] = on ; Ограничения ресурсов php_admin_value[memory_limit] = 256M php_admin_value[upload_max_filesize] = 50M php_admin_value[post_max_size] = 50M php_admin_value[max_execution_time] = 60 php_admin_value[max_input_time] = 60
Настройка PHP.ini
Оптимизируем основные настройки PHP для повышения безопасности и производительности:
# Создание резервной копии конфигурации sudo cp /etc/php/8.1/fpm/php.ini /etc/php/8.1/fpm/php.ini.backup # Редактирование конфигурационного файла sudo nano /etc/php/8.1/fpm/php.ini
Найдите и измените следующие параметры:
; Безопасность expose_php = Off display_errors = Off display_startup_errors = Off log_errors = On error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT error_log = /var/log/php/error.log ; Производительность realpath_cache_size = 4M realpath_cache_ttl = 600 opcache.enable = 1 opcache.memory_consumption = 128 opcache.interned_strings_buffer = 8 opcache.max_accelerated_files = 10000 opcache.revalidate_freq = 2 opcache.save_comments = 1 opcache.enable_file_override = 1 ; Сессии session.gc_maxlifetime = 1440 session.gc_probability = 1 session.gc_divisor = 1000 ; Дата и время date.timezone = Europe/Moscow
Создание необходимых директорий и настройка прав доступа
Создадим директории для сокета PHP-FPM и логов:
# Создание директорий sudo mkdir -p /run/php-fpm sudo mkdir -p /var/log/php-fpm sudo mkdir -p /var/log/php # Установка прав доступа sudo chown nginx:nginx /run/php-fpm sudo chown nginx:nginx /var/log/php-fpm sudo chown nginx:nginx /var/log/php
Перезапуск PHP-FPM и проверка работоспособности
Перезапустим службу PHP-FPM для применения всех настроек:
# Перезапуск PHP-FPM sudo systemctl restart php8.1-fpm # Проверка статуса sudo systemctl status php8.1-fpm # Проверка наличия сокета ls -la /run/php-fpm/
Совет
В production-среде рекомендуется создавать отдельные пулы PHP-FPM для каждого крупного веб-приложения. Это позволяет более гибко настраивать ресурсы и изолировать приложения друг от друга.
# Создание отдельного пула для приложения sudo cp /etc/php/8.1/fpm/pool.d/www.conf /etc/php/8.1/fpm/pool.d/example-app.conf # Редактирование нового пула sudo nano /etc/php/8.1/fpm/pool.d/example-app.conf # Измените следующие параметры: # [www] -> [example-app] # listen = /run/php-fpm/example-app.sock
5. Настройка SSL/TLS с Let's Encrypt
Шифрование соединений с помощью SSL/TLS сертификатов стало стандартом безопасности для современных веб-сайтов. Let's Encrypt предоставляет бесплатные сертификаты с автоматическим обновлением.
Установка Certbot
Certbot — это клиент Let's Encrypt, который значительно упрощает получение и обновление сертификатов:
# Установка Certbot и плагина для Nginx sudo apt install -y certbot python3-certbot-nginx
Получение SSL-сертификата
Перед получением сертификата необходимо настроить DNS для вашего домена и убедиться, что он указывает на ваш сервер:
# Получение сертификата с автоматической настройкой Nginx sudo certbot --nginx -d example.com -d www.example.com # Или для ручной настройки (только получение сертификата) sudo certbot certonly --nginx -d example.com -d www.example.com
Во время выполнения команды вам потребуется:
- Ввести адрес электронной почты для уведомлений об истечении срока действия сертификата
- Принять условия использования
- Решить, хотите ли вы делиться своим адресом электронной почты с EFF
- Выбрать, следует ли перенаправлять HTTP на HTTPS (рекомендуется)
Ручная настройка Nginx для использования SSL
Если вы выбрали режим "certonly", вам потребуется вручную настроить Nginx:
# Создание или редактирование виртуального хоста sudo nano /etc/nginx/conf.d/example.com.conf
Пример конфигурации с SSL и перенаправлением с HTTP на HTTPS:
server { listen 80; listen [::]:80; server_name example.com www.example.com; # Перенаправление на HTTPS return 301 https://$host$request_uri; } server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name example.com www.example.com; # SSL-сертификаты ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem; # Настройки SSL ssl_protocols TLSv1.2 TLSv1.3; ssl_prefer_server_ciphers on; ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384; ssl_session_timeout 1d; ssl_session_cache shared:SSL:10m; ssl_session_tickets off; # Настройки OCSP Stapling ssl_stapling on; ssl_stapling_verify on; resolver 8.8.8.8 8.8.4.4 valid=300s; resolver_timeout 5s; # Заголовки безопасности add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always; add_header X-Content-Type-Options nosniff; add_header X-Frame-Options SAMEORIGIN; add_header X-XSS-Protection "1; mode=block"; # Корневая директория сайта root /var/www/sites/example.com/public; index index.php index.html index.htm; # Логи access_log /var/log/nginx/example.com.access.log; error_log /var/log/nginx/example.com.error.log; # Настройка для статических файлов location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg)$ { expires 30d; add_header Cache-Control "public, no-transform"; } # Обработка PHP location ~ \.php$ { try_files $uri =404; fastcgi_pass unix:/run/php-fpm/php-fpm.sock; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; fastcgi_intercept_errors on; fastcgi_buffer_size 16k; fastcgi_buffers 4 16k; } # Защита от доступа к скрытым файлам location ~ /\. { deny all; access_log off; log_not_found off; } # Основная обработка запросов location / { try_files $uri $uri/ /index.php?$query_string; } }
Настройка автоматического обновления сертификатов
Certbot автоматически устанавливает задание cron для обновления сертификатов. Проверим его наличие и корректность:
# Проверка заданий cron для certbot systemctl list-timers | grep certbot # Ручная проверка процесса обновления (без фактического обновления) sudo certbot renew --dry-run
Важно!
Сертификаты Let's Encrypt действительны только 90 дней. Хотя Certbot настраивает автоматическое обновление, регулярно проверяйте его работоспособность, особенно после обновления операционной системы или Nginx.
Тестирование безопасности SSL-настроек
После настройки SSL рекомендуется проверить безопасность вашей конфигурации:
# Используйте онлайн-инструмент SSL Labs # https://www.ssllabs.com/ssltest/analyze.html?d=example.com # Или инструмент командной строки testssl.sh sudo apt install -y git git clone --depth 1 https://github.com/drwetter/testssl.sh.git cd testssl.sh ./testssl.sh https://example.com
6. Настройка виртуальных хостов
Виртуальные хосты позволяют размещать несколько сайтов на одном сервере. Правильная настройка виртуальных хостов — важный шаг для организации production-среды.
Организация файловой структуры
Для каждого сайта рекомендуется использовать следующую структуру каталогов:
# Создание структуры для нового сайта sudo mkdir -p /var/www/sites/example.com/{public,logs,backup,cache} # Настройка прав доступа sudo chown -R nginx:nginx /var/www/sites/example.com sudo chmod -R 755 /var/www/sites/example.com
Шаблон конфигурации виртуального хоста
Создадим шаблон для быстрого добавления новых сайтов:
# Создание шаблона sudo nano /etc/nginx/templates/vhost-template.conf
Содержимое шаблона:
server { listen 80; listen [::]:80; server_name DOMAIN_NAME www.DOMAIN_NAME; # Перенаправление на HTTPS return 301 https://$host$request_uri; } server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name DOMAIN_NAME www.DOMAIN_NAME; # SSL-сертификаты ssl_certificate /etc/letsencrypt/live/DOMAIN_NAME/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/DOMAIN_NAME/privkey.pem; ssl_trusted_certificate /etc/letsencrypt/live/DOMAIN_NAME/chain.pem; # Настройки SSL ssl_protocols TLSv1.2 TLSv1.3; ssl_prefer_server_ciphers on; ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384; ssl_session_timeout 1d; ssl_session_cache shared:SSL:10m; ssl_session_tickets off; # Настройки OCSP Stapling ssl_stapling on; ssl_stapling_verify on; resolver 8.8.8.8 8.8.4.4 valid=300s; resolver_timeout 5s; # Заголовки безопасности add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always; add_header X-Content-Type-Options nosniff; add_header X-Frame-Options SAMEORIGIN; add_header X-XSS-Protection "1; mode=block"; # Корневая директория сайта root /var/www/sites/DOMAIN_NAME/public; index index.php index.html index.htm; # Логи access_log /var/www/sites/DOMAIN_NAME/logs/access.log; error_log /var/www/sites/DOMAIN_NAME/logs/error.log; # Настройка для статических файлов location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg|woff|woff2|ttf|eot)$ { expires 30d; add_header Cache-Control "public, no-transform"; } # Обработка PHP location ~ \.php$ { try_files $uri =404; fastcgi_pass unix:/run/php-fpm/php-fpm.sock; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; fastcgi_intercept_errors on; fastcgi_buffer_size 16k; fastcgi_buffers 4 16k; } # Защита от доступа к скрытым файлам location ~ /\. { deny all; access_log off; log_not_found off; } # Отключение доступа к чувствительным файлам location ~* \.(env|log|git|htaccess|tpl|twig|ini|sql)$ { deny all; return 404; } # Основная обработка запросов location / { try_files $uri $uri/ /index.php?$query_string; } }
Скрипт для быстрого создания нового виртуального хоста
Создадим удобный скрипт для автоматизации процесса добавления новых сайтов:
# Создание скрипта sudo nano /usr/local/bin/create-vhost.sh
Содержимое скрипта:
#!/bin/bash # Проверка наличия доменного имени if [ -z "$1" ]; then echo "Не указано доменное имя!" echo "Использование: create-vhost.sh example.com" exit 1 fi DOMAIN=$1 TEMPLATE_FILE="/etc/nginx/templates/vhost-template.conf" CONFIG_FILE="/etc/nginx/conf.d/${DOMAIN}.conf" # Проверка существования шаблона if [ ! -f "$TEMPLATE_FILE" ]; then echo "Файл шаблона не найден: $TEMPLATE_FILE" exit 1 fi # Создание структуры каталогов echo "Создание структуры каталогов для $DOMAIN..." mkdir -p /var/www/sites/${DOMAIN}/{public,logs,backup,cache} chown -R nginx:nginx /var/www/sites/${DOMAIN} chmod -R 755 /var/www/sites/${DOMAIN} # Создание тестовой страницы echo "<!DOCTYPE html> <html> <head> <title>Welcome to ${DOMAIN}</title> <style> body { font-family: Arial, sans-serif; margin: 40px; line-height: 1.6; } h1 { color: #336699; } </style> </head> <body> <h1>Welcome to ${DOMAIN}</h1> <p>This is the default page for ${DOMAIN}.</p> <p>Server time: <?php echo date('Y-m-d H:i:s'); ?></p> <p>PHP Version: <?php echo phpversion(); ?></p> </body> </html>" > /var/www/sites/${DOMAIN}/public/index.php # Создание конфигурации виртуального хоста echo "Создание конфигурации виртуального хоста..." cp $TEMPLATE_FILE $CONFIG_FILE sed -i "s/DOMAIN_NAME/${DOMAIN}/g" $CONFIG_FILE # Проверка синтаксиса конфигурации echo "Проверка синтаксиса конфигурации Nginx..." nginx -t if [ $? -eq 0 ]; then echo "Конфигурация успешно проверена." echo "Перезапуск Nginx..." systemctl reload nginx echo "Получение SSL-сертификата..." certbot --nginx -d ${DOMAIN} -d www.${DOMAIN} echo "Виртуальный хост для ${DOMAIN} успешно создан!" echo "Теперь вы можете загрузить ваши файлы в /var/www/sites/${DOMAIN}/public/" else echo "Ошибка в конфигурации Nginx. Виртуальный хост не активирован." fi
Сделаем скрипт исполняемым:
sudo chmod +x /usr/local/bin/create-vhost.sh
Совет
Теперь добавление нового сайта выполняется простой командой:
sudo create-vhost.sh example.com
Скрипт создаст все необходимые каталоги, настроит виртуальный хост и запросит SSL-сертификат.
Настройка специализированных виртуальных хостов
Для различных CMS и фреймворков могут потребоваться дополнительные настройки:
Пример конфигурации для WordPress
# Дополнительные настройки для WordPress location / { try_files $uri $uri/ /index.php?$args; } # Защита файлов WordPress location ~* wp-config.php|wp-admin/includes { deny all; } # Кеширование статических файлов location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ { expires max; log_not_found off; }
Пример конфигурации для Laravel
# Laravel настройки location / { try_files $uri $uri/ /index.php?$query_string; } # Защита от доступа к .env и другим критичным файлам location ~ \.env { deny all; return 404; } # Кеширование для Laravel Mix (собранные ресурсы) location ~* \.(?:css|js|jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm|htc)$ { expires 1M; access_log off; add_header Cache-Control "public"; }
7. Оптимизация производительности
Оптимизация производительности LEMP-стека позволяет сайтам работать быстрее и обрабатывать больше запросов без необходимости в дополнительных ресурсах.
Настройка кеширования Nginx
Правильно настроенное кеширование может значительно снизить нагрузку на сервер:
# Создание директории для кеша sudo mkdir -p /var/cache/nginx # Настройка прав доступа sudo chown -R nginx:nginx /var/cache/nginx sudo chmod -R 755 /var/cache/nginx # Создание конфигурации кеширования sudo nano /etc/nginx/conf.d/cache.conf
Содержимое конфигурационного файла кеширования:
# Определение зон кеширования proxy_cache_path /var/cache/nginx/proxy_cache levels=1:2 keys_zone=proxy_cache:10m max_size=1g inactive=60m; fastcgi_cache_path /var/cache/nginx/fastcgi_cache levels=1:2 keys_zone=fastcgi_cache:10m max_size=1g inactive=60m; # Настройка параметров FASTCGI кеширования fastcgi_cache_key "$scheme$request_method$host$request_uri"; fastcgi_cache_use_stale error timeout invalid_header http_500; fastcgi_ignore_headers Cache-Control Expires Set-Cookie;
Добавление кеширования в конфигурацию виртуального хоста (пример для WordPress):
# Настройка FASTCGI-кеширования (добавить в server блок) set $skip_cache 0; # Пропуск кеша для админки, входа, авторизованных пользователей и т.д. if ($request_uri ~* "/wp-admin/|/xmlrpc.php|wp-.*.php|/feed/|index.php|sitemap(_index)?.xml") { set $skip_cache 1; } if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_no_cache|wordpress_logged_in") { set $skip_cache 1; } # В location блоке для PHP добавить: location ~ \.php$ { try_files $uri =404; fastcgi_pass unix:/run/php-fpm/php-fpm.sock; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; # Настройки кеширования fastcgi_cache fastcgi_cache; fastcgi_cache_valid 200 60m; fastcgi_cache_bypass $skip_cache; fastcgi_no_cache $skip_cache; fastcgi_cache_background_update on; # Добавление заголовка для отладки add_header X-Cache $upstream_cache_status; }
Установка и настройка Redis для кеширования сессий и данных
Redis — быстрое хранилище данных в памяти, которое можно использовать для кеширования и хранения сессий:
# Установка Redis sudo apt install -y redis-server php8.1-redis # Настройка Redis sudo nano /etc/redis/redis.conf
Основные настройки для Redis:
# Базовая настройка безопасности protected-mode yes port 6379 bind 127.0.0.1 ::1 # Производительность maxmemory 256mb maxmemory-policy allkeys-lru # Персистентность (если нужна) save 900 1 save 300 10 save 60 10000
Настройка PHP для использования Redis:
# Редактирование php.ini sudo nano /etc/php/8.1/fpm/php.ini # Добавить настройки для Redis session.save_handler = redis session.save_path = "tcp://127.0.0.1:6379"
Перезапуск сервисов:
sudo systemctl restart redis-server sudo systemctl restart php8.1-fpm
Оптимизация баз данных MySQL
Для оптимизации производительности баз данных:
# Создание скрипта для автоматической оптимизации sudo nano /usr/local/bin/optimize-mysql.sh
Содержимое скрипта:
#!/bin/bash # Файл для логов LOG_FILE="/var/log/mysql/optimization.log" # Дата выполнения DATE=$(date +"%Y-%m-%d %H:%M:%S") # Запись начала в лог echo "[$DATE] Starting MySQL optimization" >> $LOG_FILE # Получение списка баз данных DATABASES=$(mysql -B -N -e "SHOW DATABASES;" | grep -v "information_schema" | grep -v "performance_schema" | grep -v "mysql" | grep -v "sys") # Перебор баз данных for DB in $DATABASES; do echo "[$DATE] Optimizing database: $DB" >> $LOG_FILE # Получение списка таблиц TABLES=$(mysql -B -N -e "SHOW TABLES FROM \`$DB\`;") # Перебор таблиц for TABLE in $TABLES; do echo "[$DATE] Optimizing table: $DB.$TABLE" >> $LOG_FILE # Анализ таблицы mysql -e "ANALYZE TABLE \`$DB\`.\`$TABLE\`;" >> $LOG_FILE 2>&1 # Оптимизация таблицы mysql -e "OPTIMIZE TABLE \`$DB\`.\`$TABLE\`;" >> $LOG_FILE 2>&1 done done echo "[$DATE] MySQL optimization completed" >> $LOG_FILE
Сделаем скрипт исполняемым и добавим его в планировщик cron:
# Установка прав на исполнение sudo chmod +x /usr/local/bin/optimize-mysql.sh # Добавление задания в cron для выполнения каждое воскресенье в 3:00 echo "0 3 * * 0 root /usr/local/bin/optimize-mysql.sh" | sudo tee -a /etc/cron.d/mysql-optimization
Настройка мониторинга производительности
Установим простой инструмент для мониторинга производительности — Netdata:
# Установка зависимостей sudo apt install -y autoconf automake gcc make git python3 python3-pip # Установка Netdata bash <(curl -Ss https://my-netdata.io/kickstart.sh) # Проверка статуса sudo systemctl status netdata
После установки Netdata доступен через веб-интерфейс по адресу http://ваш_сервер:19999. Для повышения безопасности рекомендуется настроить базовую HTTP-аутентификацию или проксирование через Nginx с SSL.
Совет
Для максимальной производительности в production-среде также рассмотрите:
- Использование CDN (Content Delivery Network) для статического контента
- Настройку HTTP/2 для всех сайтов
- Применение WebP и оптимизацию изображений
- Минификацию и объединение CSS/JavaScript файлов
- Внедрение отложенной загрузки (lazy loading) для изображений
8. Повышение безопасности
Production-сервер требует особого внимания к безопасности. Рассмотрим дополнительные меры для защиты LEMP-стека от распространенных угроз.
Установка и настройка Fail2ban
Fail2ban помогает защититься от брутфорс-атак, блокируя IP-адреса после определенного количества неудачных попыток:
# Установка Fail2ban sudo apt install -y fail2ban # Создание конфигурационного файла sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local sudo nano /etc/fail2ban/jail.local
Основные настройки для Fail2ban:
[DEFAULT] # Время бана в секундах (24 часа) bantime = 86400 # Время в секундах, за которое отслеживаются попытки (10 минут) findtime = 600 # Количество попыток до бана maxretry = 5 # Игнорирование локальных IP ignoreip = 127.0.0.1/8 ::1 # Настройка для SSH [sshd] enabled = true port = ssh filter = sshd logpath = /var/log/auth.log maxretry = 3 # Настройка для Nginx (защита от сканирования сайта) [nginx-http-auth] enabled = true filter = nginx-http-auth port = http,https logpath = /var/log/nginx/*error.log # Настройка для защиты PHP-FPM от брутфорса [php-url-fopen] enabled = true port = http,https filter = php-url-fopen logpath = /var/log/nginx/*error.log
Создание дополнительного фильтра для обнаружения атак на веб-приложения:
# Создание фильтра для обнаружения сканирования уязвимостей sudo nano /etc/fail2ban/filter.d/nginx-scanners.conf
Содержимое фильтра:
[Definition] failregex = ^<HOST> .* "(?:GET|POST|HEAD) (?:/\.env|/wp-login\.php|/administrator|/admin/|/wp-content/|/phpMyAdmin|/phpmyadmin|/myadmin|/mysql|/mysqladmin|/sqladmin|/MyAdmin|/pma/|/PMA/|/joomla/|/wordpress/) .*$ ignoreregex =
Добавление нового фильтра в конфигурацию:
# Добавить в /etc/fail2ban/jail.local [nginx-scanners] enabled = true port = http,https filter = nginx-scanners logpath = /var/log/nginx/access.log maxretry = 2 bantime = 86400
Запуск и включение автозапуска Fail2ban:
sudo systemctl start fail2ban sudo systemctl enable fail2ban # Проверка статуса sudo fail2ban-client status
Настройка ModSecurity WAF
ModSecurity — это межсетевой экран веб-приложений (WAF), который обеспечивает защиту от распространенных атак на веб-приложения:
# Установка зависимостей sudo apt install -y git build-essential libpcre3-dev libxml2-dev libyajl-dev liblmdb-dev libgeoip-dev libcurl4-openssl-dev libmaxminddb-dev # Клонирование репозитория ModSecurity cd /opt sudo git clone --depth 1 -b v3/master --single-branch https://github.com/SpiderLabs/ModSecurity # Компиляция ModSecurity cd ModSecurity sudo git submodule init sudo git submodule update sudo ./build.sh sudo ./configure sudo make sudo make install # Клонирование коннектора для Nginx cd /opt sudo git clone --depth 1 https://github.com/SpiderLabs/ModSecurity-nginx.git # Определение версии Nginx NGINX_VERSION=$(nginx -v 2>&1 | sed 's/^nginx version: nginx\///g') # Загрузка исходников Nginx той же версии cd /opt sudo wget http://nginx.org/download/nginx-$NGINX_VERSION.tar.gz sudo tar zxvf nginx-$NGINX_VERSION.tar.gz # Компиляция и установка модуля cd /opt/nginx-$NGINX_VERSION sudo ./configure --with-compat --add-dynamic-module=/opt/ModSecurity-nginx sudo make modules sudo cp objs/ngx_http_modsecurity_module.so /etc/nginx/modules/ # Создание директории для правил ModSecurity sudo mkdir -p /etc/nginx/modsecurity cd /etc/nginx/modsecurity # Клонирование OWASP Core Rule Set sudo git clone https://github.com/coreruleset/coreruleset.git sudo cp coreruleset/crs-setup.conf.example coreruleset/crs-setup.conf # Настройка базовой конфигурации ModSecurity sudo cp /opt/ModSecurity/modsecurity.conf-recommended /etc/nginx/modsecurity/modsecurity.conf # Редактирование конфигурации sudo sed -i 's/SecRuleEngine DetectionOnly/SecRuleEngine On/' /etc/nginx/modsecurity/modsecurity.conf # Создание основного конфигурационного файла включения sudo nano /etc/nginx/modsecurity/main.conf
Содержимое файла main.conf:
Include /etc/nginx/modsecurity/modsecurity.conf Include /etc/nginx/modsecurity/coreruleset/crs-setup.conf Include /etc/nginx/modsecurity/coreruleset/rules/*.conf
Настройка Nginx для использования ModSecurity:
# Редактирование nginx.conf sudo nano /etc/nginx/nginx.conf
Добавьте в начало блока http следующие строки:
load_module modules/ngx_http_modsecurity_module.so; http { # Настройки ModSecurity modsecurity on; modsecurity_rules_file /etc/nginx/modsecurity/main.conf;
Перезапуск Nginx:
sudo nginx -t sudo systemctl restart nginx
Важно!
ModSecurity может вызывать ложные срабатывания и блокировать легитимный трафик. Рекомендуется сначала запустить его в режиме обнаружения (SecRuleEngine DetectionOnly) и тщательно проанализировать логи перед включением в производственной среде.
Защита важных файлов и каталогов
Настройка защиты для критически важных файлов системы:
# Настройка защиты критических файлов sudo chattr +i /etc/passwd sudo chattr +i /etc/shadow sudo chattr +i /etc/group sudo chattr +i /etc/gshadow # Для временного редактирования этих файлов используйте: # sudo chattr -i /etc/passwd # ... внесите изменения ... # sudo chattr +i /etc/passwd
Установка и настройка Maldet (Linux Malware Detect)
Maldet — это инструмент для обнаружения вредоносного ПО в Linux:
# Загрузка и установка Maldet cd /opt sudo wget http://www.rfxn.com/downloads/maldetect-current.tar.gz sudo tar -xzf maldetect-current.tar.gz cd maldetect-* sudo ./install.sh # Настройка Maldet sudo nano /usr/local/maldetect/conf.maldet
Основные параметры для настройки:
# Включение e-mail уведомлений email_alert="1" email_addr="your-email@example.com" # Автоматическое сканирование каталогов autoupdate_signatures="1" autoupdate_version="1" # Карантин для зараженных файлов quarantine_hits="1" # Сканирование оперативной памяти scan_user_access="1"
Создание задания для регулярного сканирования:
# Создание скрипта для еженедельного сканирования echo '#!/bin/bash /usr/local/maldetect/maldet -b -r /var/www /home /tmp /var/tmp /var/log' | sudo tee /etc/cron.weekly/maldet-scan sudo chmod +x /etc/cron.weekly/maldet-scan
Аудит безопасности с помощью Lynis
Lynis — инструмент для аудита безопасности и проверки соответствия стандартам:
# Установка Lynis sudo apt install -y lynis # Запуск аудита безопасности sudo lynis audit system # Создание еженедельного отчета echo '#!/bin/bash REPORT_FILE="/var/log/security-audit-$(date +%Y%m%d).log" echo "Security Audit Report - $(date)" > $REPORT_FILE echo "===================================" >> $REPORT_FILE echo "" >> $REPORT_FILE lynis audit system --quiet >> $REPORT_FILE echo "" >> $REPORT_FILE echo "Recommendations:" >> $REPORT_FILE echo "===================================" >> $REPORT_FILE lynis show suggestions >> $REPORT_FILE echo "" >> $REPORT_FILE echo "Warnings:" >> $REPORT_FILE echo "===================================" >> $REPORT_FILE lynis show warnings >> $REPORT_FILE # Отправка отчета на email mail -s "Security Audit Report for $(hostname) - $(date +%Y-%m-%d)" your-email@example.com < $REPORT_FILE' | sudo tee /etc/cron.weekly/security-audit sudo chmod +x /etc/cron.weekly/security-audit
Совет
Регулярно проверяйте отчеты аудита безопасности и внедряйте рекомендуемые меры. Безопасность — это непрерывный процесс, а не одноразовое мероприятие.
9. Мониторинг и логирование
Комплексный мониторинг и логирование — ключевые компоненты для надежной работы production-сервера. Они позволяют своевременно обнаруживать проблемы и принимать меры до того, как они повлияют на пользователей.
Настройка централизованного логирования
Объединение логов в одном месте упрощает их анализ и поиск проблем:
# Установка rsyslog sudo apt install -y rsyslog # Настройка централизованного хранения логов sudo mkdir -p /var/log/centralized sudo chown syslog:adm /var/log/centralized # Конфигурация rsyslog sudo nano /etc/rsyslog.d/30-centralized.conf
Содержимое конфигурационного файла:
# Nginx логи $InputFileName /var/log/nginx/access.log $InputFileTag nginx-access: $InputFileStateFile stat-nginx-access $InputFileSeverity info $InputFileFacility local6 $InputRunFileMonitor $InputFileName /var/log/nginx/error.log $InputFileTag nginx-error: $InputFileStateFile stat-nginx-error $InputFileSeverity error $InputFileFacility local6 $InputRunFileMonitor # PHP-FPM логи $InputFileName /var/log/php-fpm/www-error.log $InputFileTag php-error: $InputFileStateFile stat-php-error $InputFileSeverity error $InputFileFacility local5 $InputRunFileMonitor # MySQL логи $InputFileName /var/log/mysql/error.log $InputFileTag mysql-error: $InputFileStateFile stat-mysql-error $InputFileSeverity error $InputFileFacility local4 $InputRunFileMonitor # Шаблон для сохранения логов $template CentralizedLogs,"/var/log/centralized/%$YEAR%/%$MONTH%/%$DAY%/%syslogfacility-text%-%syslogseverity-text%.log" # Правила для записи логов local4.* -?CentralizedLogs local5.* -?CentralizedLogs local6.* -?CentralizedLogs
Перезапуск rsyslog:
sudo systemctl restart rsyslog
Настройка ротации логов
Правильная ротация логов предотвращает заполнение диска старыми логами:
# Настройка logrotate для всех компонентов LEMP sudo nano /etc/logrotate.d/lemp
Содержимое файла конфигурации ротации:
# Nginx логи /var/log/nginx/*.log { daily missingok rotate 14 compress delaycompress notifempty create 0640 nginx adm sharedscripts postrotate [ -s /run/nginx.pid ] && kill -USR1 `cat /run/nginx.pid` endscript } # PHP-FPM логи /var/log/php-fpm/*.log { daily missingok rotate 14 compress delaycompress notifempty create 0640 nginx adm sharedscripts postrotate [ -s /run/php-fpm/php-fpm.pid ] && kill -USR1 `cat /run/php-fpm/php-fpm.pid` endscript } # MySQL логи /var/log/mysql/*.log { daily missingok rotate 14 compress delaycompress notifempty create 0640 mysql adm sharedscripts postrotate [ -s /run/mysqld/mysqld.pid ] && kill -USR1 `cat /run/mysqld/mysqld.pid` endscript }
Установка и настройка Prometheus и Grafana
Для комплексного мониторинга всего стека настроим Prometheus (сбор метрик) и Grafana (визуализация):
# Создание пользователя для Prometheus sudo useradd --no-create-home --shell /bin/false prometheus # Создание директорий sudo mkdir -p /etc/prometheus sudo mkdir -p /var/lib/prometheus sudo chown prometheus:prometheus /var/lib/prometheus # Загрузка и установка Prometheus cd /tmp wget https://github.com/prometheus/prometheus/releases/download/v2.40.0/prometheus-2.40.0.linux-amd64.tar.gz tar -xvf prometheus-2.40.0.linux-amd64.tar.gz cd prometheus-2.40.0.linux-amd64 sudo cp prometheus /usr/local/bin/ sudo cp promtool /usr/local/bin/ sudo chown prometheus:prometheus /usr/local/bin/prometheus sudo chown prometheus:prometheus /usr/local/bin/promtool sudo cp -r consoles/ /etc/prometheus sudo cp -r console_libraries/ /etc/prometheus sudo chown -R prometheus:prometheus /etc/prometheus/consoles sudo chown -R prometheus:prometheus /etc/prometheus/console_libraries # Настройка конфигурации Prometheus sudo nano /etc/prometheus/prometheus.yml
Базовая конфигурация Prometheus:
global: scrape_interval: 15s scrape_configs: - job_name: 'prometheus' scrape_interval: 5s static_configs: - targets: ['localhost:9090'] - job_name: 'node_exporter' scrape_interval: 5s static_configs: - targets: ['localhost:9100'] - job_name: 'mysql_exporter' scrape_interval: 5s static_configs: - targets: ['localhost:9104'] - job_name: 'nginx_exporter' scrape_interval: 5s static_configs: - targets: ['localhost:9113']
Создание systemd-сервиса для Prometheus:
sudo nano /etc/systemd/system/prometheus.service
Содержимое файла сервиса:
[Unit] Description=Prometheus Wants=network-online.target After=network-online.target [Service] User=prometheus Group=prometheus Type=simple ExecStart=/usr/local/bin/prometheus \ --config.file /etc/prometheus/prometheus.yml \ --storage.tsdb.path /var/lib/prometheus/ \ --web.console.templates=/etc/prometheus/consoles \ --web.console.libraries=/etc/prometheus/console_libraries [Install] WantedBy=multi-user.target
Установка экспортеров для сбора метрик:
# Node Exporter для системных метрик cd /tmp wget https://github.com/prometheus/node_exporter/releases/download/v1.4.0/node_exporter-1.4.0.linux-amd64.tar.gz tar -xvf node_exporter-1.4.0.linux-amd64.tar.gz cd node_exporter-1.4.0.linux-amd64 sudo cp node_exporter /usr/local/bin/ sudo useradd --no-create-home --shell /bin/false node_exporter sudo chown node_exporter:node_exporter /usr/local/bin/node_exporter # Сервис для Node Exporter sudo nano /etc/systemd/system/node_exporter.service
Содержимое файла сервиса Node Exporter:
[Unit] Description=Node Exporter Wants=network-online.target After=network-online.target [Service] User=node_exporter Group=node_exporter Type=simple ExecStart=/usr/local/bin/node_exporter [Install] WantedBy=multi-user.target
Установка и настройка Grafana:
# Установка зависимостей sudo apt install -y apt-transport-https software-properties-common # Добавление GPG ключа Grafana wget -q -O - https://packages.grafana.com/gpg.key | sudo apt-key add - # Добавление репозитория Grafana echo "deb https://packages.grafana.com/oss/deb stable main" | sudo tee -a /etc/apt/sources.list.d/grafana.list # Установка Grafana sudo apt update sudo apt install -y grafana # Запуск и включение автозапуска sudo systemctl start grafana-server sudo systemctl enable grafana-server
Запуск всех служб мониторинга:
sudo systemctl daemon-reload sudo systemctl start prometheus sudo systemctl enable prometheus sudo systemctl start node_exporter sudo systemctl enable node_exporter
Совет
После настройки откройте Grafana (http://ваш_сервер:3000) и импортируйте готовые дашборды для мониторинга. Рекомендуемые ID дашбордов:
- 1860 — Node Exporter Full
- 7362 — MySQL Overview
- 9614 — NGINX Exporter Dashboard
Настройка оповещений
Создание системы оповещений о критических событиях:
# Установка Alertmanager cd /tmp wget https://github.com/prometheus/alertmanager/releases/download/v0.24.0/alertmanager-0.24.0.linux-amd64.tar.gz tar -xvf alertmanager-0.24.0.linux-amd64.tar.gz cd alertmanager-0.24.0.linux-amd64 sudo cp alertmanager /usr/local/bin/ sudo cp amtool /usr/local/bin/ sudo useradd --no-create-home --shell /bin/false alertmanager sudo chown alertmanager:alertmanager /usr/local/bin/alertmanager sudo chown alertmanager:alertmanager /usr/local/bin/amtool sudo mkdir -p /etc/alertmanager sudo chown alertmanager:alertmanager /etc/alertmanager # Конфигурация Alertmanager sudo nano /etc/alertmanager/alertmanager.yml
Базовая конфигурация Alertmanager:
global: resolve_timeout: 5m smtp_from: 'alerts@example.com' smtp_smarthost: 'smtp.example.com:587' smtp_auth_username: 'alerts@example.com' smtp_auth_password: 'your-password' smtp_require_tls: true route: group_by: ['alertname', 'instance', 'severity'] group_wait: 30s group_interval: 5m repeat_interval: 4h receiver: 'email-notifications' receivers: - name: 'email-notifications' email_configs: - to: 'admin@example.com' send_resolved: true
Создание systemd-сервиса для Alertmanager:
sudo nano /etc/systemd/system/alertmanager.service
Содержимое файла сервиса:
[Unit] Description=Alertmanager Wants=network-online.target After=network-online.target [Service] User=alertmanager Group=alertmanager Type=simple ExecStart=/usr/local/bin/alertmanager \ --config.file=/etc/alertmanager/alertmanager.yml \ --storage.path=/var/lib/alertmanager [Install] WantedBy=multi-user.target
Запуск Alertmanager:
sudo systemctl daemon-reload sudo systemctl start alertmanager sudo systemctl enable alertmanager
10. Автоматизация обслуживания
Автоматизация рутинных задач позволяет экономить время и снижает риск человеческих ошибок. Рассмотрим автоматизацию основных процессов обслуживания LEMP-стека.
Автоматизация резервного копирования
Создадим скрипт для полного резервного копирования всех компонентов LEMP-стека:
# Создание скрипта для резервного копирования sudo nano /usr/local/bin/lemp-backup.sh
Содержимое скрипта:
#!/bin/bash # Настройки BACKUP_DIR="/var/backups/lemp" MYSQL_USER="root" MYSQL_PASSWORD="" # Если используется аутентификация через socket DATE=$(date +"%Y-%m-%d_%H-%M-%S") LOG_FILE="/var/log/lemp-backup.log" KEEP_DAYS=7 # Количество дней хранения резервных копий # Создание директории для резервных копий mkdir -p $BACKUP_DIR mkdir -p $BACKUP_DIR/databases mkdir -p $BACKUP_DIR/websites mkdir -p $BACKUP_DIR/config # Логирование начала процесса echo "$(date): Начало процесса резервного копирования" >> $LOG_FILE # Резервное копирование MySQL базы данных echo "$(date): Резервное копирование баз данных MySQL" >> $LOG_FILE databases=$(mysql -u $MYSQL_USER --skip-column-names -e "SHOW DATABASES;" | grep -v "information_schema" | grep -v "performance_schema" | grep -v "mysql" | grep -v "sys") for db in $databases; do echo "$(date): Копирование базы данных $db" >> $LOG_FILE mysqldump -u $MYSQL_USER --single-transaction --quick --lock-tables=false $db | gzip > $BACKUP_DIR/databases/$db-$DATE.sql.gz if [ $? -eq 0 ]; then echo "$(date): База данных $db успешно скопирована" >> $LOG_FILE else echo "$(date): Ошибка при копировании базы данных $db" >> $LOG_FILE fi done # Резервное копирование веб-сайтов echo "$(date): Резервное копирование веб-сайтов" >> $LOG_FILE for website_dir in /var/www/sites/*; do if [ -d "$website_dir" ]; then website_name=$(basename $website_dir) echo "$(date): Копирование сайта $website_name" >> $LOG_FILE tar -czf $BACKUP_DIR/websites/$website_name-$DATE.tar.gz -C /var/www/sites $website_name if [ $? -eq 0 ]; then echo "$(date): Сайт $website_name успешно скопирован" >> $LOG_FILE else echo "$(date): Ошибка при копировании сайта $website_name" >> $LOG_FILE fi fi done # Резервное копирование конфигурации echo "$(date): Резервное копирование конфигурационных файлов" >> $LOG_FILE tar -czf $BACKUP_DIR/config/nginx-config-$DATE.tar.gz /etc/nginx tar -czf $BACKUP_DIR/config/php-config-$DATE.tar.gz /etc/php tar -czf $BACKUP_DIR/config/mysql-config-$DATE.tar.gz /etc/mysql # Удаление старых резервных копий echo "$(date): Удаление устаревших резервных копий (старше $KEEP_DAYS дней)" >> $LOG_FILE find $BACKUP_DIR -type f -name "*.gz" -mtime +$KEEP_DAYS -delete # Установка прав доступа chown -R root:root $BACKUP_DIR chmod -R 600 $BACKUP_DIR echo "$(date): Процесс резервного копирования завершен" >> $LOG_FILE # Опционально: отправка уведомления о завершении # mail -s "LEMP Backup Completed on $(hostname)" your-email@example.com < $LOG_FILE
Настройка прав доступа и добавление задания в cron:
# Установка прав на исполнение sudo chmod +x /usr/local/bin/lemp-backup.sh # Добавление задания в cron для ежедневного резервного копирования в 2:00 echo "0 2 * * * root /usr/local/bin/lemp-backup.sh" | sudo tee -a /etc/cron.d/lemp-backup
Автоматизация обновлений безопасности
Настроим автоматические обновления безопасности для системы:
# Установка пакета unattended-upgrades sudo apt install -y unattended-upgrades apt-listchanges # Настройка автоматических обновлений sudo nano /etc/apt/apt.conf.d/50unattended-upgrades
Основные настройки для автоматических обновлений:
Unattended-Upgrade::Allowed-Origins { "${distro_id}:${distro_codename}"; "${distro_id}:${distro_codename}-security"; "${distro_id}ESMApps:${distro_codename}-apps-security"; "${distro_id}ESM:${distro_codename}-infra-security"; }; Unattended-Upgrade::Package-Blacklist { }; Unattended-Upgrade::Automatic-Reboot "true"; Unattended-Upgrade::Automatic-Reboot-Time "02:00";
Включение автоматических обновлений:
sudo nano /etc/apt/apt.conf.d/20auto-upgrades
Содержимое конфигурационного файла:
APT::Periodic::Update-Package-Lists "1"; APT::Periodic::Download-Upgradeable-Packages "1"; APT::Periodic::AutocleanInterval "7"; APT::Periodic::Unattended-Upgrade "1";
Скрипт для проверки состояния LEMP-стека
Создадим скрипт для комплексной проверки работоспособности всего стека:
# Создание скрипта sudo nano /usr/local/bin/check-lemp-stack.sh
Содержимое скрипта:
#!/bin/bash # Файл для логов LOG_FILE="/var/log/lemp-health-check.log" # Очистка лог-файла echo "LEMP Stack Health Check - $(date)" > $LOG_FILE echo "=====================================" >> $LOG_FILE echo "" >> $LOG_FILE # Проверка состояния Nginx echo "Проверка состояния Nginx:" >> $LOG_FILE if systemctl is-active --quiet nginx; then echo "✅ Nginx работает" >> $LOG_FILE nginx -v >> $LOG_FILE 2>&1 else echo "❌ Nginx не запущен!" >> $LOG_FILE fi # Проверка синтаксиса конфигурации Nginx echo "" >> $LOG_FILE echo "Проверка конфигурации Nginx:" >> $LOG_FILE nginx -t >> $LOG_FILE 2>&1 # Проверка состояния MySQL echo "" >> $LOG_FILE echo "Проверка состояния MySQL:" >> $LOG_FILE if systemctl is-active --quiet mysql; then echo "✅ MySQL работает" >> $LOG_FILE mysql --version >> $LOG_FILE 2>&1 else echo "❌ MySQL не запущен!" >> $LOG_FILE fi # Проверка подключения к MySQL echo "" >> $LOG_FILE echo "Проверка соединения с MySQL:" >> $LOG_FILE if mysql -e "SELECT 1;" &>/dev/null; then echo "✅ Соединение с MySQL успешно" >> $LOG_FILE else echo "❌ Ошибка соединения с MySQL!" >> $LOG_FILE fi # Проверка состояния PHP-FPM echo "" >> $LOG_FILE echo "Проверка состояния PHP-FPM:" >> $LOG_FILE if systemctl is-active --quiet php8.1-fpm; then echo "✅ PHP-FPM работает" >> $LOG_FILE php-fpm8.1 -v >> $LOG_FILE 2>&1 else echo "❌ PHP-FPM не запущен!" >> $LOG_FILE fi # Проверка доступности сокета PHP-FPM echo "" >> $LOG_FILE echo "Проверка сокета PHP-FPM:" >> $LOG_FILE if [ -S /run/php-fpm/php-fpm.sock ]; then echo "✅ Сокет PHP-FPM доступен" >> $LOG_FILE else echo "❌ Сокет PHP-FPM отсутствует!" >> $LOG_FILE fi # Проверка использования диска echo "" >> $LOG_FILE echo "Проверка использования диска:" >> $LOG_FILE df -h / >> $LOG_FILE DISK_USAGE=$(df -h / | awk 'NR==2 {print $5}' | sed 's/%//g') if [ "$DISK_USAGE" -gt 90 ]; then echo "❌ Предупреждение! Использование диска превышает 90%" >> $LOG_FILE else echo "✅ Использование диска в норме ($DISK_USAGE%)" >> $LOG_FILE fi # Проверка использования памяти echo "" >> $LOG_FILE echo "Проверка использования памяти:" >> $LOG_FILE free -h >> $LOG_FILE MEM_USAGE=$(free | awk 'NR==2 {print int($3*100/$2)}') if [ "$MEM_USAGE" -gt 90 ]; then echo "❌ Предупреждение! Использование памяти превышает 90%" >> $LOG_FILE else echo "✅ Использование памяти в норме ($MEM_USAGE%)" >> $LOG_FILE fi # Проверка загрузки системы echo "" >> $LOG_FILE echo "Проверка загрузки системы:" >> $LOG_FILE uptime >> $LOG_FILE LOAD=$(uptime | awk -F'[a-z]:' '{ print $2}' | awk -F',' '{print $1}' | tr -d ' ') CORES=$(nproc) LOAD_PER_CORE=$(echo "$LOAD / $CORES" | bc -l) if (( $(echo "$LOAD_PER_CORE > 1.5" | bc -l) )); then echo "❌ Предупреждение! Высокая загрузка системы" >> $LOG_FILE else echo "✅ Загрузка системы в норме" >> $LOG_FILE fi # Проверка виртуальных хостов Nginx echo "" >> $LOG_FILE echo "Проверка виртуальных хостов Nginx:" >> $LOG_FILE for config in /etc/nginx/conf.d/*.conf; do if [ -f "$config" ]; then SERVER_NAME=$(grep -E '^\s*server_name' "$config" | head -1 | sed 's/server_name//g' | sed 's/;//g' | tr -d ' ' | cut -d' ' -f1) if [ ! -z "$SERVER_NAME" ]; then echo " - $SERVER_NAME ($(basename $config))" >> $LOG_FILE fi fi done # Проверка SSL-сертификатов echo "" >> $LOG_FILE echo "Проверка SSL-сертификатов:" >> $LOG_FILE for cert in /etc/letsencrypt/live/*/cert.pem; do if [ -f "$cert" ]; then DOMAIN=$(echo "$cert" | sed -E 's/.*live\/([^/]+)\/cert.pem/\1/') EXPIRY_DATE=$(openssl x509 -enddate -noout -in "$cert" | cut -d= -f2) EXPIRY_EPOCH=$(date -d "$EXPIRY_DATE" +%s) CURRENT_EPOCH=$(date +%s) DAYS_LEFT=$(( ($EXPIRY_EPOCH - $CURRENT_EPOCH) / 86400 )) if [ "$DAYS_LEFT" -lt 10 ]; then echo "❌ $DOMAIN: Сертификат истекает через $DAYS_LEFT дней ($EXPIRY_DATE)" >> $LOG_FILE else echo "✅ $DOMAIN: Сертификат действителен ($DAYS_LEFT дней до истечения)" >> $LOG_FILE fi fi done # Проверка сетевых соединений echo "" >> $LOG_FILE echo "Активные сетевые соединения:" >> $LOG_FILE netstat -tulpn | grep -E '(nginx|mysql|php)' >> $LOG_FILE # Сбор метрик производительности echo "" >> $LOG_FILE echo "Метрики производительности:" >> $LOG_FILE echo " - Nginx Active Connections: $(curl -s http://localhost/nginx_status 2>/dev/null | grep "Active connections" | awk '{print $3}' || echo "N/A")" >> $LOG_FILE echo " - PHP-FPM Active Processes: $(ps aux | grep php-fpm | grep -v master | grep -v grep | wc -l)" >> $LOG_FILE echo " - MySQL Active Connections: $(mysql -e "SHOW STATUS LIKE 'Threads_connected';" 2>/dev/null | tail -1 | awk '{print $2}' || echo "N/A")" >> $LOG_FILE # Отправка отчета на email (опционально) #mail -s "LEMP Health Check Report - $(hostname) - $(date +"%Y-%m-%d")" your-email@example.com < $LOG_FILE # Вывод пути к файлу отчета echo "" >> $LOG_FILE echo "Отчет сохранен в $LOG_FILE" echo "Отчет сохранен в $LOG_FILE"
Настройка прав доступа и добавление в cron:
# Установка прав на исполнение sudo chmod +x /usr/local/bin/check-lemp-stack.sh # Добавление задания в cron для ежедневной проверки в 8:00 echo "0 8 * * * root /usr/local/bin/check-lemp-stack.sh" | sudo tee -a /etc/cron.d/lemp-health-check
Скрипт для быстрого развертывания проектов
Создадим скрипт для автоматического развертывания проектов на базе LEMP-стека:
# Создание скрипта sudo nano /usr/local/bin/deploy-project.sh
Содержимое скрипта:
#!/bin/bash # Проверка аргументов if [ "$#" -lt 3 ]; then echo "Использование: $0" echo "Поддерживаемые типы проектов: wordpress, laravel, php-static" exit 1 fi DOMAIN=$1 PROJECT_TYPE=$2 GIT_REPO=$3 WWW_DIR="/var/www/sites/$DOMAIN" WWW_PUBLIC="$WWW_DIR/public" LOG_FILE="/var/log/project-deploy-$DOMAIN.log" # Запись начала процесса echo "Начало развертывания проекта $DOMAIN ($(date))" > $LOG_FILE # Создание директории для проекта echo "Создание директории проекта..." >> $LOG_FILE sudo mkdir -p $WWW_DIR sudo mkdir -p $WWW_PUBLIC sudo mkdir -p $WWW_DIR/logs sudo mkdir -p $WWW_DIR/backup # Клонирование репозитория echo "Клонирование репозитория $GIT_REPO..." >> $LOG_FILE git clone $GIT_REPO $WWW_PUBLIC 2>> $LOG_FILE # Настройка прав доступа echo "Настройка прав доступа..." >> $LOG_FILE sudo chown -R nginx:nginx $WWW_DIR sudo chmod -R 755 $WWW_DIR # Создание виртуального хоста echo "Создание виртуального хоста..." >> $LOG_FILE sudo create-vhost.sh $DOMAIN # Настройка в зависимости от типа проекта case $PROJECT_TYPE in wordpress) echo "Настройка WordPress..." >> $LOG_FILE # Создание базы данных и пользователя DB_NAME=$(echo ${DOMAIN/./_} | sed 's/-/_/g') DB_USER=$(echo ${DOMAIN/./_} | sed 's/-/_/g' | cut -c 1-12) DB_PASS=$(openssl rand -base64 12 | tr -d "=+/") echo "Создание базы данных $DB_NAME и пользователя $DB_USER..." >> $LOG_FILE mysql -e "CREATE DATABASE IF NOT EXISTS $DB_NAME CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;" mysql -e "CREATE USER IF NOT EXISTS '$DB_USER'@'localhost' IDENTIFIED BY '$DB_PASS';" mysql -e "GRANT ALL PRIVILEGES ON $DB_NAME.* TO '$DB_USER'@'localhost';" mysql -e "FLUSH PRIVILEGES;" # Создание wp-config.php cd $WWW_PUBLIC if [ -f wp-config-sample.php ]; then cp wp-config-sample.php wp-config.php sed -i "s/database_name_here/$DB_NAME/" wp-config.php sed -i "s/username_here/$DB_USER/" wp-config.php sed -i "s/password_here/$DB_PASS/" wp-config.php # Генерация ключей безопасности for i in $(seq 1 8); do key=$(openssl rand -base64 48 | tr -d "=+/" | cut -c 1-64) sed -i "/AUTH_KEY/,/NONCE_SALT/ s/'put your unique phrase here'/'$key'/1" wp-config.php done # Настройка дополнительных параметров echo "/** Настройки для повышения безопасности */" >> wp-config.php echo "define('DISALLOW_FILE_EDIT', true);" >> wp-config.php echo "define('WP_AUTO_UPDATE_CORE', true);" >> wp-config.php echo "define('WP_POST_REVISIONS', 5);" >> wp-config.php else echo "ОШИБКА: Файл wp-config-sample.php не найден. Возможно, это не проект WordPress." >> $LOG_FILE fi ;; laravel) echo "Настройка Laravel..." >> $LOG_FILE # Создание базы данных и пользователя DB_NAME=$(echo ${DOMAIN/./_} | sed 's/-/_/g') DB_USER=$(echo ${DOMAIN/./_} | sed 's/-/_/g' | cut -c 1-12) DB_PASS=$(openssl rand -base64 12 | tr -d "=+/") echo "Создание базы данных $DB_NAME и пользователя $DB_USER..." >> $LOG_FILE mysql -e "CREATE DATABASE IF NOT EXISTS $DB_NAME CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;" mysql -e "CREATE USER IF NOT EXISTS '$DB_USER'@'localhost' IDENTIFIED BY '$DB_PASS';" mysql -e "GRANT ALL PRIVILEGES ON $DB_NAME.* TO '$DB_USER'@'localhost';" mysql -e "FLUSH PRIVILEGES;" # Настройка Laravel cd $WWW_PUBLIC cp .env.example .env sed -i "s/DB_DATABASE=laravel/DB_DATABASE=$DB_NAME/" .env sed -i "s/DB_USERNAME=root/DB_USERNAME=$DB_USER/" .env sed -i "s/DB_PASSWORD=/DB_PASSWORD=$DB_PASS/" .env # Установка зависимостей и настройка приложения composer install --no-interaction --no-dev --optimize-autoloader php artisan key:generate php artisan storage:link php artisan config:cache php artisan route:cache php artisan view:cache # Миграция базы данных php artisan migrate --force # Настройка прав доступа для Laravel sudo chown -R nginx:nginx $WWW_DIR/storage sudo chown -R nginx:nginx $WWW_DIR/bootstrap/cache ;; php-static) echo "Настройка статического PHP проекта..." >> $LOG_FILE # Для статических сайтов дополнительная настройка не требуется ;; *) echo "ОШИБКА: Неизвестный тип проекта: $PROJECT_TYPE" >> $LOG_FILE exit 1 ;; esac # Запись информации о проекте echo "Сохранение информации о проекте..." >> $LOG_FILE cat > $WWW_DIR/project-info.txt << EOF Домен: $DOMAIN Тип проекта: $PROJECT_TYPE Репозиторий: $GIT_REPO Дата развертывания: $(date) EOF if [ $PROJECT_TYPE == "wordpress" ] || [ $PROJECT_TYPE == "laravel" ]; then cat >> $WWW_DIR/project-info.txt << EOF База данных: $DB_NAME Пользователь БД: $DB_USER Пароль БД: $DB_PASS EOF fi # Защита файла с информацией sudo chmod 600 $WWW_DIR/project-info.txt sudo chown root:root $WWW_DIR/project-info.txt echo "Проект успешно развернут!" >> $LOG_FILE echo "" echo "Проект $DOMAIN успешно развернут!" echo "Тип проекта: $PROJECT_TYPE" echo "Информация о проекте сохранена в $WWW_DIR/project-info.txt" echo "Лог установки: $LOG_FILE"
Установка прав на исполнение:
sudo chmod +x /usr/local/bin/deploy-project.sh
Совет
Использование скрипта очень простое:
sudo deploy-project.sh example.com wordpress https://github.com/username/wordpress-project.git
Скрипт автоматически создаст виртуальный хост, базу данных, настроит права доступа и выполнит базовую настройку проекта в зависимости от его типа.
Заключение
Настройка и оптимизация LEMP-стека для production-среды — это многогранный процесс, который требует внимания ко множеству аспектов от безопасности до производительности. В этой статье мы прошли полный путь от чистой установки Linux до полностью настроенного стека, готового для размещения высоконагруженных веб-приложений.
Мы рассмотрели:
- Подготовку сервера — базовую настройку безопасности системы
- Установку и оптимизацию Nginx — настройку веб-сервера для максимальной производительности
- Настройку MySQL — оптимизацию базы данных и обеспечение ее безопасности
- Установку PHP-FPM — настройку интерпретатора PHP для эффективной работы с Nginx
- Настройку SSL/TLS — защиту передаваемых данных с помощью шифрования
- Настройку виртуальных хостов — организацию размещения нескольких сайтов на одном сервере
- Оптимизацию производительности — повышение скорости работы всех компонентов стека
- Повышение безопасности — защиту от распространенных угроз и атак
- Мониторинг и логирование — отслеживание работы системы и выявление проблем
- Автоматизацию обслуживания — минимизацию рутинных операций с помощью скриптов
Важно понимать, что настройка production-сервера — это не одноразовое событие, а непрерывный процесс. Регулярное обновление всех компонентов, мониторинг, аудит безопасности и оптимизация производительности должны стать частью вашей повседневной работы.
Основные принципы работы с production-средой
С правильно настроенным LEMP-стеком вы получаете надежную, производительную и защищенную платформу для размещения практически любых веб-приложений — от простых сайтов до сложных высоконагруженных систем.
Заключительный совет
Сохраните все скрипты и команды из этого руководства в личном репозитории. Это позволит вам быстро восстановить настроенную среду в случае необходимости или развернуть аналогичную конфигурацию на новых серверах. В идеале перейдите к полностью автоматизированному развертыванию инфраструктуры с помощью таких инструментов, как Ansible, Chef или Terraform.
Максим Орлов
27 января 2025Потрясающая статья! Я уже давно занимаюсь администрированием веб-серверов, но нашел здесь множество полезных советов, о которых раньше не задумывался. Особенно понравился раздел по автоматизации - скрипты очень удобные и практичные.