Если у тебя на одном VPS или выделенном сервере должны сосуществовать два веб-сервера — Nginx и Apache — это вполне рабочая и часто используемая схема. Обычно Nginx ставят «перед» Apache: он принимает входящие соединения, раздаёт статику, выполняет SSL-терминацию и проксирует динамические запросы в Apache; Apache, в свою очередь, остаётся за Nginx и обрабатывает сложную динамику, модульные приложения и .htaccess-логику.
Такой подход позволяет совмещать сильные стороны обоих проектов: лёгкую, масштабируемую обработку соединений у Nginx и богатую модульную функциональность у Apache. Именно об этом и пойдёт речь — разберём все нюансы, примеры конфигураций, типичные ошибки и приёмы отладки, чтобы ты смог настроить связку безопасно и надёжно.
Кратко о ролях: Nginx — это HTTP-сервер и reverse proxy; Apache — полнофункциональный HTTP-сервер с обширной экосистемой модулей.
Почему использовать связку Nginx + Apache (когда это оправдано)
Есть несколько ситуаций, когда имеет смысл держать оба сервера на одном хосте. Например, у тебя есть старое приложение, которое сильно зависит от .htaccess и модулей Apache, но при этом хочется улучшить отдачу статических файлов, сжать трафик и разгрузить сервер — тогда Nginx как фронтенд — логичный выбор.
Ещё одна причина — SSL/TLS: часто удобнее закрывать TLS в Nginx (он проще в автоматизации получения сертификатов, имеет гибкие директивы для кеширования и gzip) и проксировать уже расшифрованные запросы в Apache; это упрощает конфигурации PHP и модулей, которые не знают о шифровании.
Практические гайды по такой настройке есть у ведущих провайдеров и сообществ (примеры и детальные пошаговые инструкции — у DigitalOcean).
Короткие определения (важные термины)
Reverse proxy — это посредник между клиентом и внутренним сервером: он принимает запросы от клиентов и пересылает их на один или несколько бэкендов; при этом может менять заголовки, кешировать ответы и защищать бэкенд от прямого доступа.
Server block (в Nginx) / VirtualHost (в Apache) — это конфигурационный блок, который описывает поведение веб-сервера для конкретного домена или IP-адреса; там указывают root, логирование, SSL и прочее.
mod_remoteip (Apache) — модуль, позволяющий заменить IP клиента в логах и правилах на реальный IP, который передал reverse proxy (через X-Forwarded-For или PROXY протокол). Без него в логах будет IP Nginx, а не посетителя.
Варианты развёртывания и их преимущества / недостатки
Ниже — самые распространённые схемы, которые реально встретишь в продакшене. Я опишу плюсы и минусы, чтобы ты понимал, за что платишь гибкостью.
| Схема | Плюсы | Минусы |
|---|---|---|
| Nginx (front) → Apache (backend) | Быстрая отдача статических файлов; удобная TLS-терминация; Nginx держит много соединений; | Нужно корректно передавать заголовки (X-Forwarded-For) и настраивать mod_remoteip в Apache; |
| Apache (front) → Nginx (backend) | Редко; полезно при специфичных модулях Apache, которые должны управлять входящими соединениями; | Менее распространено; утрачиваются преимущества event-driven Nginx при большом количестве соединений; |
| Оба слушают разные IP/порты (раздельно) | Чёткое разделение сайтов и ответственности; можно назначать сервисы на отдельные IP; | Потребность в дополнительных IP; больше работы по маршрутизации и firewall; |
Общая идея: Nginx как reverse proxy поверх Apache
Самая распространённая и рекомендованная схема — Nginx принимает трафик на 80/443, отдаёт статику сам, а динамику (например, обработку PHP через модуль Apache или другую backend-логику) проксирует в Apache на локальный порт (например, 127.0.0.1:8080) или unix-сокет.
Почему так делают: Nginx эффективнее масштабируется по количеству одновременных соединений благодаря событийной архитектуре (event-driven), а Apache остаётся удобным для приложений, требующих функционала модулей и .htaccess. По части производительности и архитектурных преимуществ Nginx подробно описан в официальных материалах NGINX.
Типичная цепочка заголовков при проксировании
Важно передавать заголовки, чтобы бэкенд видел корректную информацию о клиенте и протоколе. Обычно отправляют:
- X-Forwarded-For: список IP через запятую; последним — IP клиента;
- X-Real-IP: реальный IP клиента;
- X-Forwarded-Proto: http или https — чтобы бэкенд понимал, по какому протоколу пришёл клиент.
Пошаговая настройка (практическая часть)
Далее — конкретные шаги, которые ты можешь применить на типичной Ubuntu/Debian-системе. Если у тебя другой дистрибутив — команды установки пакетов могут отличаться, но идея остаётся той же.
1) Установка Nginx и Apache
На Debian/Ubuntu обычно достаточно установить оба пакета из репозитория:
sudo apt update; sudo apt install nginx apache2;
После установки убедись, что службы запущены и что только Nginx слушает порты 80/443 (Apache мы перенастроим на другой порт или локальный адрес).
2) Перенести Apache на локальный порт (например, 8080)
По умолчанию Apache слушает 0.0.0.0:80 — это конфликт. В конфигурации Apache надо изменить директиву Listen на локальный интерфейс или другой порт:
Listen 127.0.0.1:8080
Или в VirtualHost указывать <VirtualHost 127.0.0.1:8080>. Это гарантирует, что Apache не будет доступен извне напрямую и все внешние запросы пойдут через Nginx.
3) Настройка Nginx — серверный блок (server block)
Пример простого server-блока, который отдаёт статику и проксирует остальное к Apache:
server {
listen 80;
server_name example.com www.example.com;
```
root /var/www/example.com/html;
index index.php index.html index.htm;
# Отдаём статику напрямую:
location ~* \.(jpg|jpeg|png|css|js|ico|svg|gif)$ {
try_files $uri =404;
expires 30d;
access_log off;
}
# Всё остальное - проксируем в Apache:
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 90;
}
```
} Обрати внимание на директивы proxy_set_header — они обеспечивают передачу нужных заголовков в Apache.
4) Настройка Apache: VirtualHost на 127.0.0.1:8080
Пример Apache-конфигурации для сайта:
<VirtualHost 127.0.0.1:8080>
ServerName example.com
ServerAlias www.example.com
DocumentRoot /var/www/example.com/html
```
AllowOverride All
Require all granted
ErrorLog ${APACHE_LOG_DIR}/example.com_error.log
CustomLog ${APACHE_LOG_DIR}/example.com_access.log combined
```
\ Если твои приложения используют .htaccess — именно Apache будет их читать, потому что Nginx .htaccess не поддерживает.
5) Корректные IP в логах: модуль mod_remoteip
Когда Nginx проксирует запросы, в логах Apache обычно появится IP Nginx (127.0.0.1). Чтобы в логах и для правил авторизации видеть реальный IP клиента, включи модуль mod_remoteip и настрой его:
RemoteIPHeader X-Forwarded-For RemoteIPInternalProxy 127.0.0.1
Это заменит текущий IP на последний из X-Forwarded-For и позволит использовать этот IP в логах и проверках. Подробно про модуль можно прочитать в документации Apache.
SSL/TLS: где завершать шифрование?
Обычно TLS завершают в Nginx: он прост в автоматизации Let’s Encrypt, лучше управляет цепочками сертификатов и имеет гибкие директивы для настройки ciphers, HSTS и OCSP stapling. Nginx принимает https, расшифровывает трафик и проксирует в Apache по HTTP (локально).
Это уменьшает сложность и нагрузку на Apache и упрощает централизованное управление SSL. Многие руководства рекомендуют такой подход; примеры конфигураций можно найти в сообществе DigitalOcean.
Пример TLS-конфигурации в Nginx (фрагмент)
server {
listen 443 ssl http2;
server_name example.com;
```
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
```
} PHP: какие есть варианты и что лучше
Если у тебя PHP-приложение, есть два основных подхода:
- Оставить Apache с модулем mod_php и проксировать запросы через Nginx в Apache (простой путь, если приложение зависит от .htaccess);
- Перейти на Nginx + PHP-FPM: Nginx напрямую общается с PHP-FPM, а Apache можно вовсе убрать или оставить для других сайтов.
Первый вариант удобен для миграции старых проектов; второй — обычно даёт более низкую задержку и лучшую управляемость пулами PHP-процессов. Если приложение активно использует .htaccess, миграция потребует переработки правил в конфиг Nginx или сохранения части логики в Apache.
Особые случаи: WebSocket, большие файлы, timeouts
WebSocket и long-polling требуют прокидывания заголовков Upgrade и Connection, например:
proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade";
Для больших загрузок файлов увеличь client_max_body_size в Nginx и соответствующие timeout/buffer-директивы.
Типичные ошибки и как их исправить
Ниже — подборка наиболее частых проблем и быстрые рецепты их исправления.
- Проблема: Apache и Nginx конфликтуют на порту 80; решение: изменить Listen в Apache на 127.0.0.1:8080;
- Проблема: в логах Apache виден только 127.0.0.1; решение: включить mod_remoteip и настроить RemoteIPHeader и RemoteIPInternalProxy;
- Проблема: 502 Bad Gateway в Nginx; решение: проверить, слушает ли Apache указанный порт/unix-сокет и нет ли SELinux/AppArmor, блокирующих соединение;
- Проблема: загрузка больших файлов прерывается; решение: увеличить client_max_body_size и proxy_read_timeout;
- Проблема: некорректная логика редиректов (http → https или www); решение: правильно настроить X-Forwarded-Proto и правило редиректа в Nginx, а не в Apache, чтобы избежать циклов.
Команды для отладки
Пара полезных команд при отладке:
- systemctl status nginx apache2 — проверить статус служб;
- ss -ltnp | grep -E ’80|443|8080′ — увидеть, какие процессы слушают порты;
- curl -I -H «Host: example.com» http://127.0.0.1:80 — проверить ответ Nginx локально;
- tail -f /var/log/nginx/error.log /var/log/apache2/error.log — смотреть ошибки в реальном времени.
Резюме практических рекомендаций (коротко)
Если у тебя много статики и современные клиенты — ставь Nginx внешним, делай TLS-терминацию там, отдавай статику из Nginx и проксируй динамику в Apache на локальном порту. Не забывай про передачу X-Forwarded-For и настройку mod_remoteip в Apache, чтобы логи и правила работали корректно. Тестируй WebSocket-сценарии и большие загрузки заранее, настраивая буферы и таймауты.
Примеры конфигураций — сводная вкладка
Ниже — краткая сводка с примерами, чтобы ты мог быстро скопировать и адаптировать их под свой проект.
- Nginx server block для проксирования (см. выше);
- Apache VirtualHost на 127.0.0.1:8080 (см. выше);
- mod_remoteip: RemoteIPHeader X-Forwarded-For; RemoteIPInternalProxy 127.0.0.1.
Подведём итоги
Настроить Nginx и Apache на одном сервере — реально и часто разумно. Nginx выдаёт статику, делает TLS и разгружает соединения, а Apache остаётся «мозгом» для тех приложений, которые завязаны на .htaccess и модулях. Самые важные моменты — правильно распределить порты/адреса, передавать заголовки (X-Forwarded-For, X-Real-IP, X-Forwarded-Proto) и настроить в Apache модуль для корректного получения реального IP (mod_remoteip). Также не забудь про буферы, таймауты, поддержку WebSocket и проверку SELinux/AppArmor, если они активны.
—
Источники: https://nginx.org/, https://www.digitalocean.com/community/tutorials/how-to-configure-nginx-as-a-web-server-and-reverse-proxy-for-apache-on-one-ubuntu-18-04-server, https://httpd.apache.org/docs/2.4/mod/mod_remoteip.html