Настройка Apache: оптимизация, безопасность и кэширование
Представьте: интернет-магазин на WordPress с 1000 уникальных посетителей в час отдаёт 503 ошибку. Типичная картина — Apache исчерпал MaxClients, а PHP-FPM не настроен. Без кэширования каждый запрос к статике (CSS, JS, изображения) грузит сервер заново — LCP улетает за 5 секунд. В 90% случаев это решается переходом на PHP-FPM через Unix-сокет и включением mod_expires. За 10 лет мы настроили Apache для 500+ проектов: от простых лендингов до высоконагруженных SaaS. Ниже — проверенная схема, которая уменьшает TTFB на 30% и снижает потребление памяти на 40%.
Неочевидная проблема — .htaccess. На каждый запрос Apache проверяет директории от корня до DocumentRoot на наличие .htaccess. Для глубоких структур это до 10 дисковых операций. Мы используем AllowOverride None и переносим правила в конфиг VirtualHost. Это ускоряет отдачу на 15–20%.
Типичные проблемы, с которыми мы работаем
- Медленная отдача статики — без mod_expires и mod_deflate браузер каждый раз запрашивает файлы заново, LCP вырастает на 30%.
- Небезопасные VirtualHost — открытые директории, устаревшие протоколы, отсутствие HSTS.
- Некорректный .htaccess — Laravel не работает из-за отсутствия RewriteRule, .env доступен извне.
- PHP-FPM через TCP, а не Unix-сокет — лишние 20% задержки на localhost.
- Отсутствие rate limiting — один клиент может выкачать весь контент за секунды.
Как мы настраиваем Apache под ключ
Наш стек: Apache 2.4+, PHP 8.3 (FPM через socket), Laravel, WordPress, любая CMS. Для каждого проекта создаём Production-ready конфиг с учётом нагрузки. Вот пример для Laravel:
<VirtualHost *:443>
ServerName example.com
DocumentRoot /var/www/myapp/current/public
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
Protocols h2 http/1.1
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
Header always set X-Frame-Options "DENY"
<Directory /var/www/myapp/current/public>
AllowOverride All
Require all granted
Options -Indexes
</Directory>
<FilesMatch \.php$>
SetHandler "proxy:unix:/var/run/php/php8.3-fpm.sock|fcgi://localhost"
</FilesMatch>
<FilesMatch "\.(css|js|jpg|png|gif|ico|svg|woff2)$">
Header set Cache-Control "public, max-age=31536000, immutable"
</FilesMatch>
ErrorLog ${APACHE_LOG_DIR}/myapp-error.log
CustomLog ${APACHE_LOG_DIR}/myapp-access.log combined
</VirtualHost>
Пример конфигурации для WordPress с дополнительной оптимизацией
<VirtualHost *:443>
ServerName blog.example.com
DocumentRoot /var/www/wp/current
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/blog.example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/blog.example.com/privkey.pem
Protocols h2 http/1.1
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
Header always set X-Content-Type-Options "nosniff"
<Directory /var/www/wp/current>
AllowOverride None
Require all granted
Options -Indexes +FollowSymLinks
# WordPress rewrite rules
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</Directory>
<FilesMatch \.php$>
SetHandler "proxy:unix:/var/run/php/php8.3-fpm.sock|fcgi://localhost"
</FilesMatch>
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType image/jpg "access plus 1 year"
ExpiresByType image/jpeg "access plus 1 year"
ExpiresByType image/gif "access plus 1 year"
ExpiresByType image/png "access plus 1 year"
ExpiresByType text/css "access plus 1 month"
ExpiresByType application/javascript "access plus 1 month"
</IfModule>
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/html text/css application/json application/javascript
DeflateCompressionLevel 6
</IfModule>
ErrorLog ${APACHE_LOG_DIR}/wp-error.log
CustomLog ${APACHE_LOG_DIR}/wp-access.log combined
</VirtualHost>
Что входит в работу
- Аудит текущей конфигурации Apache.
- Настройка VirtualHost, SSL (Let's Encrypt), HSTS.
- Оптимизация MPM event, gzip, кэширования.
- .htaccess под вашу CMS (Laravel, WordPress, Drupal).
- Внедрение rate limiting и заголовков безопасности.
- Тестирование нагрузки (ab, siege) и передача документации.
- Обучение команды работе с конфигами и поддержка после деплоя.
Оптимизация MPM и кэширования для высоконагруженных проектов
Первый шаг — выбор MPM. Для динамических сайтов с PHP используйте mpm_event. Пример оптимизации:
<IfModule mpm_event_module>
StartServers 2
MinSpareThreads 25
MaxSpareThreads 75
ThreadLimit 64
ThreadsPerChild 25
MaxRequestWorkers 150
MaxConnectionsPerChild 0
</IfModule>
Затем включите сжатие и кэширование:
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/html text/css application/json application/javascript
DeflateCompressionLevel 6
</IfModule>
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType text/css "access plus 1 year"
ExpiresByType application/javascript "access plus 1 year"
ExpiresByType image/jpeg "access plus 1 year"
ExpiresByType image/png "access plus 1 year"
</IfModule>
Типичная ошибка — использование mod_php вместо PHP-FPM. Первый потребляет на 40% больше памяти при пиковых нагрузках. Переход на PHP-FPM снижает TTFB на 15% и увеличивает пропускную способность в 2 раза.
Почему стоит использовать PHP-FPM с Apache?
PHP-FPM через Unix-сокет снижает задержку на localhost на 20% по сравнению с TCP-соединением. Кроме того, mod_php потребляет на 40% больше памяти при пиковых нагрузках, так как каждый процесс Apache таскает интерпретатор. PHP-FPM позволяет гибко управлять пулом воркеров и отдельно настраивать php.ini.
Чем Apache отличается от Nginx и когда его выбирать?
| Критерий | Apache | Nginx |
|---|---|---|
| Обработка динамики | mod_php (встроенный) | PHP-FPM (внешний) |
| .htaccess | Поддерживается per-directory | Не поддерживает |
| Память на соединение | Выше (процесс на запрос) | Ниже (event-driven) |
| Статика | Хорошо с mod_cache | Отлично из коробки |
| Гибкость конфигурации | Модульная, много директив | Проще, меньше опций |
Apache лучше Nginx в 2 случаях: когда критичен .htaccess (shared-хостинг) или используются модули вроде mod_ldap, mod_authnz_ldap. В остальном Nginx даёт на 30% больше RPS на статике.
Сравнение MPM-модулей Apache
| Параметр | mpm_prefork | mpm_worker | mpm_event |
|---|---|---|---|
| Тип процессов | Один поток на запрос | Несколько потоков на процесс | Потоки + событийный цикл |
| Память | Высокая (1 процесс = 1 запрос) | Средняя | Низкая |
| Совместимость | mod_php, старые приложения | PHP-FPM, Python | PHP-FPM, Python, Node |
| Под нагрузкой | Быстро истощает память | Лучше prefork | Оптимален для высоких нагрузок |
Процесс работы по настройке Apache
- Аналитика: изучаем текущий конфиг, нагрузку, CMS.
- Проектирование: подбираем MPM, модули, параметры кэша.
- Реализация: настраиваем VirtualHost, SSL, .htaccess, rate limiting.
- Тестирование: проверяем LCP, CLS, TTFB через Lighthouse, нагрузочное тестирование.
- Деплой: применяем конфиг, мониторим логи, передаём документацию.
Типичные ошибки, которых мы избегаем:
- Отсутствие Header always set X-Content-Type-Options "nosniff".
- Неправильные права на DocumentRoot (должен быть 755, не 777).
- Использование mod_php вместо PHP-FPM — на 40% больше потребление памяти.
Сроки ориентировочно
Базовая настройка Apache с PHP-FPM занимает от 1 дня. Полный цикл с оптимизацией, безопасностью и нагрузочным тестированием — до 3 дней. Стоимость рассчитывается индивидуально. Закажите аудит конфигурации — оценим проект и предложим решение под ключ.
Получите конфигурацию Apache, соответствующую лучшим практикам, с гарантией стабильной работы под пиковой нагрузкой. Свяжитесь с нами для консультации по вашему проекту.







