Зачем нужен Nginx?
Это веб-сервер, предназначенный в основном для отдачи статики (для того чтобы разгрузить бекенд) и использования в качестве фронтендов. Apache при этом можно использовать в качестве бэкенда для генерации динамического контента.
Так же Nginx можно использовать в режиме FastCGI, при этом Apache вам не понадобится. Однако при этом режиме , поэтому на помощь приходит !
Более подробно о PHP-FPM в моей статье: Nginx. Использование PHP в режиме FastCGI с помощью php-fpm
Однако мы сегодня поговорим о совместной установке с Apache, а не в режиме FastCGI. Более того, по задаче у нас эти веб-сервера будут находится на одном сервере, поэтому выделим для Nginx — 80, а для Apache — 88 порт!

Установка Apache и Nginx
Ставим Apache:
make config
make install clean
Ставим Nginx:
make config
make install clean
Настройка Nginx
Отредактируем файл /usr/local/etc/nginx/nginx.conf
user www www;
# 3 рабочих процесса
worker_processes 3;
# Лог для ошибок
error_log logs/error.log;
events {
# максимум рабочих соединений
worker_connections 1024;
# Метод обработки соединений
# kqueue — эффективный метод, используемый во FreeBSD
# Подробнее http://sysoev.ru/nginx/docs/events.html
use kqueue;
}
http {
# Подключаем таблицу mime
include mime.types;
# mime-тип по умолчанию
default_type application/octet-stream;
# Формат лог файла
#log_format main '$remote_addr - $remote_user [$time_local] $request '
# '"$status" $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
# Лог доступа всего веб-сервера
#access_log logs/access.log main;
# Директива задаёт таймаут при чтении заголовка запроса клиента
client_header_timeout 3m;
# Директива задаёт таймаут при чтении тела запроса клиента
client_body_timeout 3m;
# Директива задаёт таймаут при передаче ответа клиенту
send_timeout 3m;
# Директива задаёт таймаут, в течение которого keep-alive соединение с клиентом не будет закрыто со стороны сервера
keepalive_timeout 2m;
# Директива разрешает или запрещает использовать sendfile()
sendfile on;
# Директива разрешает или запрещает использовать опции TCP_NOPUSH во FreeBSD
# Подробнее http://sysoev.ru/nginx/docs/http/ngx_http_core_module.html#keepalive_timeout
#tcp_nopush on;
# Директива задаёт размер буфера для чтения заголовка запроса клиента
#client_header_buffer_size 1k;
# Директива задаёт максимальное число и размер буферов для чтения большого заголовка запроса клиента
#large_client_header_buffers 4 4k;
# Модуль позволяет описывать группы серверов, которые могут использоваться
# в директивах proxy_pass и fastcgi_pass.
upstream backend {
# Директива задаёт имя и параметры сервера. Обратите внимание, мы будем
# использовать имя "backend" в директиве proxy_pass
server 127.0.0.1:88;
}
server {
# Слушать 80 порт
listen 80;
# Использовать следующие хосты
server_name pyha.ru www.pyha.ru;
# Кодировка
#charset koi8-r;
# Лог доступа для конкретного виртуального хоста
#access_log logs/host.access.log main;
# Максимальный размер тела запроса клиента
client_max_body_size 101M;
# Разруливаем статику и динамку, смотрите описание ниже в этой статье!
location ~* \.(jpg|jpeg|gif|png|ico|css|bmp|swf|js)$ {
root /home/pyha/pyha.ru;
}
location ~ /\.ht {
deny all;
}
location / {
proxy_pass http://backend/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_connect_timeout 120;
proxy_send_timeout 120;
proxy_read_timeout 180;
}
# Адрес страницы 404-ой ошибки, далее все ошибки по аналогии
#error_page 404 /404.html;
# Аналогично 404, только при этом назначается псевдоним 50x.html для всех
# 50x-тых ошибок и далее перенаправляется все на "root"
error_page 500 502 503 504 /50x.html;
location = /50x.html {
# корневая директория
root /usr/local/www/nginx-dist;
}
}
}
После конфигурации необходимо перезагрузить Nginx
Nginx: Отдаем статику

С помощью этих правил разруливаем запросы на отдачу статику и динамического контента
location ~* \.(jpg|jpeg|gif|png|ico|css|bmp|swf|js)$ {
root /home/pyha/pyha.ru;
}
# htaccess и htpasswd не отдаем
location ~ /\.ht {
deny all;
}
# Все остальное разруливает бекенд (Apache)
location / {
# Адрес бекенда. Параметры бекенда перечислили в директиве "upstream" (см. выше в статье)
proxy_pass http://backend/;
# Заголовок Host
proxy_set_header Host $host;
# Заголовок X-Real-IP
proxy_set_header X-Real-IP $remote_addr;
# Заголовок X-Forwarded-For
proxy_set_header X-Forwarded-For $remote_addr;
# Директива задаёт таймаут для соединения с проксированным сервером, сек
proxy_connect_timeout 120;
# Директива задаёт таймаут при передаче запроса проксированному серверу, сек
proxy_send_timeout 120;
# Директива задаёт таймаут при чтении ответа проксированного сервера, сек
proxy_read_timeout 180;
}
Настройка Apache
Редактируем файл /usr/local/etc/apache2/httpd.conf
Listen 88
Тоже самое делаем и в httpd-vhosts.conf для ваших хостов.
Если у вас появляется следующая ошибка:
> [warn] (2) No such file or directory:
> Failed to enable the ‘httpready’ Accept Filterто вам следует подгрузить модуль
# kldload accf_httpПодробнее тут
Установка и настройка RPAF или даешь верный REMOTE_ADDR!
Так как у нас появился в цепи дополнительный элемент в виде фронтенд-сервера, то теперь в REMOTE_ADDR у нас не пользовательский IP, а IP-адрес фронтенд-сервера (на котором расположен Nginx). Поэтому на помощь приходит RPAF, он берет тело заголовка X-Forwarded-For, присланного от фронтенда и формирует на бекенде из него REMOTE_ADDR.
Таким образом заголовок REMOTE_ADDR снова имеет пользовательский IP!
Устанавливаем модуль RPAF
make install clean
mod_rpaf2 — для apache2, а для первого индейца надо mod_rpaf
Настраиваем RPAF, редактируем httpd.conf, добавляем в конец файла:
RPAFenable On
# Доводит до ума X-Host
RPAFsethostname On
# Адрес фронтенда (nginx)
RPAFproxy_ips 82.146.61.55 127.0.0.1
# Имя отправляемого заголовка
RPAFheader X-Forwarded-For
После конфигурации необходимо перезагрузить Apache
Ну вот вроде и все, смотрите ниже дополнительную литературу и задавайте вопросы в камменты!
Полезные материалы по Nginx
Отличная статья с Хабра:
Полезная статья про балансировку нагрузки, оптимизацию и кеширование в Nginx:



[...] описание kqueue [...]
[...] nginx events [...]
[...] сервер Nginx используется совместно с Apache [...]
[...] настройка apache2 [...]
[...] nginx apache php 502-error [...]
руководство для Федоры (VPS):
Nginx рулит, пока обхожусь без апача вообще
а что насчет поддержки SSL ?
А какие именно вопросы по SSL?
Вот кусок из конфига:
#
#server {
# listen 443;
# server_name localhost;
# ssl on;
# ssl_certificate cert.pem;
# ssl_certificate_key cert.key;
# ssl_session_timeout 5m;
# ssl_protocols SSLv2 SSLv3 TLSv1;
# ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
# ssl_prefer_server_ciphers on;
# location / {
# root html;
# index index.html index.htm;
# }
#}
И сам ман по модулю:
Работает связка nginx+php-fpm.
Подскажите как сделать чтоб ошибки в php-скриптах выводились в браузер вместо сообщения «The page you are looking for is temporarily unavailable».
Никак не разберусь.
Спасибо.
bion, вот в Google-группе по PHP-FPM есть подобная тема:
Замечательная статья, спасибо!
Спасибо.
Vit, пожалуйста!
в логах апача 127.0.0.1 вместо верного REMOTE_ADDR
модуль RPAF2 установлен
Юрий, покажите конфиг RPAF
Если имеется ввиду то, что добавляется в httpd.conf, то отличие только в опущенных комментариях и IP сервера
Юрий, покажите ваш конфиг с RPAF (из конфиг апача, блок RPAF) пожалуйста. И конфиг Nginx.
httpd.conf
RPAFsethostname On
RPAFproxy_ips 1.2.3.4
RPAFheader X-Forwarded-For
nginx.conf
worker_processes 3;
error_log /var/log/nginx-error.log;
events {
worker_connections 1024;
use kqueue;
}
http {
include mime.types;
default_type application/octet-stream;
client_header_timeout 3m;
client_body_timeout 3m;
send_timeout 3m;
keepalive_timeout 2m;
sendfile on;
upstream bak {
server 127.0.0.1:8080;
}
server {
listen 213.179.227.214:80;
server_name localhost;
client_max_body_size 10M;
location ~* \.(jpg|jpeg|gif|png|ico|css|bmp|swf|js)$ {
root /home/www/test;
}
location ~ /\.ht {
deny all;
}
location / {
proxy_pass http://bak/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_connect_timeout 120;
proxy_send_timeout 120;
proxy_read_timeout 180;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/local/www/nginx-dist;
}
}
}
httpd-access.log
127.0.0.1 - - [19/Jun/2009:13:20:50 +0300] "GET /22.php?=PHPE9568F35-D428-11d2-A769-00AA001ACF42 HTTP/1.0" 200 2146 "http://1.2.3.4/22.php" "Opera/9.63 (Windows NT 5.1; U; ru) Presto/2.1.1"
127.0.0.1 - - [19/Jun/2009:13:44:37 +0300] "GET / HTTP/1.0" 304 - "-" "Opera/9.63 (Windows NT 5.1; U; ru) Presto/2.1.1"
Покажите
$_SERVER['HTTP_X_REAL_IP']
$_SERVER['HTTP_X_FORWARDED_FOR']
на несоответствие внешнего IP в nginx.conf и остальных конфигах не обращайте внимание — оторвали и забыл подправить перед отправкой :)
Юрий, сделай страничку с
$_SERVER['HTTP_HOST'],
$_SERVER['HTTP_X_REAL_IP'],
$_SERVER['HTTP_X_FORWARDED_FOR']
);
и дай на нее ссылку
Юрий, ну вроде все нормально... Покажи текущие логи, пару строк
127.0.0.1 - - [19/Jun/2009:14:37:36 +0300] "GET /21.php HTTP/1.0" 200 87 "-" "Opera/9.63 (Windows NT 5.1; U; ru) Presto/2.1.1"
127.0.0.1 - - [19/Jun/2009:14:40:57 +0300] "GET /21.php HTTP/1.0" 200 83 "http://adw0rd.ru/2009/nginx-and-apache-install/" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.1) Gecko/2008070206 Firefox/3.0.1"
127.0.0.1 - - [19/Jun/2009:14:42:30 +0300] "GET /21.php HTTP/1.0" 200 87 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/530.5 (KHTML, like Gecko) Chrome/2.0.172.31 Safari/530.5"
Как не работало так и не работает
Юрий, да, странно... может логи nginx тогда юзать?
я уже думал об этом, просто интересно почему
adw0rd, держи два спасибо. Одно за статью, второе за совет! :)
Юрий, кстати, а что у вас в REMOTE_ADDR?
Автор, а где указанная в топике статья «Nginx. Использование PHP в режиме FastCGI с помощью php-fpm» adw0rd.ru/2009/nginx-and-php-fpm/ ? У меня вылезает «Ничего не найдено... Попробуйте воспользоваться поиском по сайту.»
Она дописывается :)
Уважаемый. Написано хорошо. Можно уточнить кто у вас обрабатывает пхп. Апач или нгинкс. У меня был настроен нгинкс без апача с пхп на fastcgi. Сейчас когда я подключаю апач, у меня не пашет пхп.
Ivet, в статье описывается способ работы nginx+apache+mod_php, таким образом пхп работает из под апача. А вы пхп пересобирали с включенным модулем mod_php?
Нет, в том то и дело. Мне бы хотелось отстатся на fastcgi. Буду разбиратся как заставить нгикс не отправлять обрабатывать пхп на Апач. Огромное спасибо за быстрый ответ.
Как уже не мучался явным образом указываю ведь обрабатывать пхп
root /var/www/playlist;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /var/www/playlist$fastcgi_script_name;
include fastcgi_params;
}
И все равно обрабатыает пхп Апач.
Ivet, так у вас же и был настроен nginx+php:
теперь вы говорите
из этого делаю выводы, что у вас была связка nginx+php, и сейчас вы хотите nginx+php
Вопрос: Если не видно разницы, то что вы вообще хотите сделать? Оставайтесь на старой связке, или у вас сервак сгорел, а нету бекапов и вы не помните как настроить? :)
Все хорошо помню связка то осталась и меня она устраивает. Но когда я подключаю апач как бекенд-сервер. Нгинкс перестает понимать пхп, но у меня подозрение что он отправляет его обрабатывать Апачу.
Ivet, nginx никакое управление не передаст апачу, если вы явно это не укажете
listen 80;
server_name playlist.in.ua www.playlist.in.ua;
#charset koi8-r;
#access_log logs/host.access.log main;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
location ~* \.(jpg|jpeg|gif|png|ico|css|bmp|swf|js|php)$ {
root /var/www/playlist;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /var/www/playlist$fastcgi_script_name;
include fastcgi_params;
}
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 $remote_addr;
client_max_body_size 5m;
client_body_buffer_size 128k;
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 10m;
}
}
Вот такой у меня конфиг когда я подключаю Apache.
А в апаче настроена обработка php? Типа того:
Глянул в конфигах Апача. Не нашел. Добавил. Не помогло.
Хм, а вообще с чего вы взяли что обрабатывать стал апач?
Когда я ставил ФастЦГИ у меня отвалился пхп5, непомню по какой причине, но Апач совершенно отказался обрабатывать пхп. Вообщем сейчас я двигаюсь в направлении заставить апач обрабатывать пхп, не с помощью mod_php5, а с помощью mod_fcgid. Пока глухо но я рядом.
А, теперь понял. конечно не мое дело, но в чем смысл использовать апач в вашей связке? Вообще какую роль он должен играть у вас на сервере?
Да, дело в том что, nginx не умеет читать .htaccess, что мне есть очень важно.
Я как-то вроде читал в обсуждении, что хотели сделать патч, который позволяет использовать файлы типа htaccess, естественно с другим синтаксимом, но с той же идеей. Тут я видел
Все то что я писал я поднимал на Дебиане. Промучался еще пару дней и плюнул, поднял на мод_пхп5. Но по долгу службы пришлось всю эту связку поднять под FreeBSD. Вообщем вышла у меня связка Nginx + (FreeBSD + mod_fcgid).
Все достаточно просто:
1)устанавливаем:
2)далее в конфиге Апача выключаем модуль пхп5.
3) Добавляем поддержку модуля fcgid
(
)
4)в конец файла добавляем
AddHandler fcgid-script .fcgi
FCGIWrapper /usr/local/bin/php-cgi .php
</IfModule>
5) Добавляем:
AddType application/x-httpd-php-source .phps
6) И еще:
Options Indexes FollowSymLinks
AllowOverride None
Order allow,deny
SetHandler fcgid-script
FCGIWrapper /usr/local/bin/php-cgi .php
Options ExecCGI
Allow from all
</Directory>
7) Дальше перезапускаем Апач ну и он обрабатывает хпх посредством модуля fcgid, но пока это топорная настройка я думаю ее реально модифицировать.
А может nginx для определенного домена сделать запрос к Apache на другом сервере?
т.е. есть два сайта xxx.ru & yyy.ru
xxx.ru на apache 127.0.0.1
yyy.ru на apache 192.168.0.2
Да, может конечно
привет, adw0rd, подскажи, пожалуйста, я не совсем понимаю как будут работать виртуальные сайты(хосты) апача?
ну то есть — моя ситуация. на debian стоят apache2+mod_php.
у апача примерно20 сайтов, конфиги к этим сайтам лежат у меня в
/etc/apache2/conf.d
например:
/etc/apache2/conf.d/site1.com.conf
/etc/apache2/conf.d/site2.com.conf
/etc/apache2/conf.d/site3.com.conf
и в каждом файлике прописаны настойки к виртуальному хосту, типа:
php_admin_value doc_root ...
php_admin_value open_basedir ...
php_admin_value safe_mode_exec_dir ...
php_admin_value upload_tmp_dir ...
DocumentRoot ...
ServerName ...
ServerAlias ...
ErrorLog ...
CustomLog ...
<Directory ...>
Options -Indexes
AllowOverride All
</Directory>
</VirtualHost>
как по вашей схеме будет работать ngnix?
или не будет?
заранее огромное спасибо!
Работать будет. В чем вы видите проблему?
а зачем апач на все ip на 80 порт открываеть если на них буит nginx пахать?
sapun, вы обращаетесь к Иннокентий?
ага =)
Да думаю он либо все уже решил, либо забил :)
всё ещё пишеш ?
Ага, надо бы на днях закончить :/
welnax, adw0rd.ru/2010/nginx-and-php-fpm/ готово :)
Собственно для сайтов на DLE связка вообще бессмысленна, т.к. там большинство статики отдаётся через пхп и, соответственно, нгикс больше тормозит систему чем помогает ей. Конечно можно резать нгиксом коннекты, но намного лучше делать это на уровне фаервола.
Я не работал с DLE, но судя по отзывам о этой системе — никогда не буду с ней работать.
Забыли в конце статьи сказать о том, что после всего еще нужно прописать в /etc/rc.conf добавить nginx_enable="YES"!!!!
Сергей, судя по вашему каменту, вы потеряли на этой «мелочи» часа 2-4 )))
А как сделать чтобы RPAF принимал X-Forwarded-For и записывал в REMOTE_ADDR
с любого IP,
то есть что-то вроде этого:
RPAFproxy_ips *
нужно это для организации большого количества nginx web proxy, а править httpd.conf каждый раз при добавлении нового фронтэнда надоедает :( .
Да вроде там и надо было ставить «*». Либо попробуйте его закомментить вообще.
Иначе вам надо просто полезть в сорцы да посмотерть, думаю проблем нету, если вам действительно это необходимо...
Автор сайта молодец, статья хороша, понравилось что есть ссылки на CGI если не хочешь использовать апач. Респект;)