Nginx - свободный высокопроизводительный веб-сервер и обратный прокси-сервер с открытым исходным кодом, а также IMAP/POP3 прокси-сервер. Игорь Сысоев начал разработку Nginx в 2002 году, первый публичный релиз был выпущен в 2004 году. Nginx в настоящее время используют около 7,65% всех доменов по всему миру по рейтингу Netcraft.

Nginx известен своей высокой производительностью, стабильностью, богатым набором функций, простой конфигурацией, и низким потреблением ресурсов. В отличие от традиционных серверов, Nginx не зависит от потоков для обработки запросов. Вместо этого он использует гораздо более масштабируемую управляемую событиями (асинхронную) архитектуру. Эта архитектура использует небольшие, но что более важно, предсказуемые объемы памяти под нагрузкой.

Установка Nginx

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

Установка Nginx в CentOS

Из-под привелегированного пользователя вам нужно отдать сл. команду:

yum install nginx

После установки вам нужно его запустить

/etc/init.d/nginx start

или

service nginx start

Так же рекомендуется включить этот сервис в автозагрузку

chkconfig nginx on

Установка Nginx в Ubuntu

От привелегированного пользователяч вам нужно отдать сл. команду:

apt-get install nginx

Как только сервис будет установлен в вашу систему, его можно включить

/etc/init.d/nginx start

Установка Nginx в FreeBSD

Установка из портов:

1
2
cd /usr/ports/www/nginx
make install clean

После этого возникнет окно с выбором модулей, среди которых вам нужно будет выбрать необходимые

Установка Nginx в Solaris из исходников

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
./configure \
--with-libatomic \
--with-md5-asm \
--with-pcre \
--with-http_ssl_module \
--with-http_realip_module \
--with-http_addition_module \
--with-http_xslt_module \
--with-http_image_filter_module \
--with-http_geoip_module \
--with-http_sub_module \
--with-http_dav_module \
--with-http_flv_module \
--with-http_gzip_static_module \
--with-http_random_index_module \
--with-http_secure_link_module \
--with-http_degradation_module \
--with-http_stub_status_module \

gmake
gmake install

Установка Nginx в Windows

Необходимо скачать zip-архив. Он доступен на этой странице. Далее в командной строке нужно перейти в место его сохранения, например, в корень диска C:

cd c:\

Разархивировать полученный файл

unzip nginx.zip

Перейти внутрь каталога

cd nginx

Запустить сервер

start nginx

Если nginx не запустился, нужно смотреть причины в error_log. Если же error_log не создался, то об этом сообщается в Event Log. В настоящее время данное ПО не работает в Windows как сервис.

Настройка Nginx

Настройка Nginx для работы с Apache

Для того, чтобы Nginx мог работать с другими веб-сервисами, достаточно прописать одну строку в конфигурацию.

proxy_pass IP сервера:PORT

Например, у нас есть сайт wikiadmin.net, на нем apache, отдающий контент на порт 8080. Надо, чтобы nginx отдавал контент wikiadmin.net на 80 порту:

1
2
3
4
5
6
server {
 listen 127.0.0.1:80;
 location / {
   proxy_pass http://127.0.0.1:8080);
 }
}

В apache можно отключить keep alive, так как nginx с ним общается через http/1.0 и keepalive не поддерживается. При отключении может сильно уменьшиться кол-во процессов и снизиться нагрузка на сервер.

Отдаём статику без участия Apache

Зачем просить Apache отдавать статику, если Nginx с этим справится быстрее? Добавляем в конфиг, например, это:

1
2
3
4
5
6
location ~* \.(jpg|jpeg|gif|png|ico|css|bmp|swf)$ {
       root /var/www/html/site;
       expires 31536000s;
       add_header Pragma "public";
       add_header Cache-Control "public, must-revalidate, proxy-revalidate";
       }

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

Ошибка 504 и ругань про timeout

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

1
2
proxy_read_timeout 120;
proxy_connect_timeout 120;

Если взять верхний пример, получится так:

1
2
3
4
5
6
7
8
server {
 listen 127.0.0.1:80;
 location / {
   proxy_pass http://127.0.0.1:8080;
   proxy_read_timeout 120;
   proxy_connect_timeout 120;
 }
}

Проблема, когда в логах apache только адрес сервера nginx

Значит просто не установлен модуль apache mod_rpaf и (или) не настроен Nginx для передачи IP. Итак, порядок действий в CentOS5:

  • Установка хранилища, откуда можно установить модуль mod_rpaf

rpm -ihv http://centos.alt.ru/repository/centos/5/x86_64/centalt-release-5-3.noarch.rpm

  • Отключение этого хранилища, редактируя файл /etc/yum.repos.d/centalt.repo и заменив 1 на 0 в строке

enabled=0

  • Установка mod_rpaf

yum -y --enablerepo=CentALT install mod_rpaf

  • добавляем в /etc/httpd/conf/httpd.conf следующее:
1
2
3
4
5
6
LoadModule rpaf_module /usr/lib/httpd/modules/mod_rpaf-2.0.so # для 32 битной ОС
LoadModule rpaf_module /usr/lib64/httpd/modules/mod_rpaf-2.0.so # для 64 битной ОС
RPAFenable On
RPAFsethostname Off
RPAFproxy_ips 127.0.0.1
RPAFheader X-Real-IP

Учтите, что может потребоваться заменить 127.0.0.1 на тот IP, который использует Nginx. В логах, по сути, только он и есть.

  • Перезгрузите apache

/etc/init.d/httpd restart

  • В конфигурации nginx должны быть строки:
1
2
3
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;

Например:

1
2
3
4
5
6
7
location / {
           proxy_pass http://127.0.0.1:8080;
           proxy_redirect http://127.0.0.1:8080;
           proxy_set_header Host $host;
           proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
           proxy_set_header X-Real-IP $remote_addr;
       }

Настройка Nginx для phpBB

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
server {
       listen   IP:80;
       server_name forum.wikiadmin.net;
       access_log /ПУТЬ/access.log;
       error_log /ПУТЬ/error.log warn;
   location = / {
       root            /ПУТЬ/forum/;
       index           index.php;
   }
   location / {
       root           /ПУТЬ/forum/;
       index           index.php index.html;
       if (!-e $request_filename) {
       rewrite  ^/(.*)$  /index.php?q=$1  last;
       break;
       }
}
error_page  404                 /index.php;
error_page  403                 /index.php;
error_page  500 502 503 504     /index.php;
# статические картинки
location ~* ^.+\.(jpg|jpeg|gif|css|png|js|ico)$ {
       access_log        off; #стоит ли засорять этим логи - решайте сами
       expires           30d;
       `[`root`](/root)` /ПУТЬ/forum/;
   break;
}
# прячем нужное
location ~* \.(engine|inc|info|install|module|profile|po|sh|.*sql|theme|tpl(\.php)?|xtmpl)$|^(code-style\.pl|Entries.*|Repository|root|Tag|Template)$ {
       deny all;
}
location ~ \.php$ {
       fastcgi_pass   127.0.0.1:9000;
       fastcgi_index  index.php;
       fastcgi_param  SCRIPT_NAME      $fastcgi_script_name;
       fastcgi_param  SCRIPT_FILENAME  /ПУТЬ/forum/$fastcgi_script_name;
       fastcgi_param  QUERY_STRING     $query_string;
       fastcgi_param  REQUEST_METHOD   $request_method;
       fastcgi_param  CONTENT_TYPE     $content_type;
       fastcgi_param  CONTENT_LENGTH   $content_length;
       fastcgi_param  REMOTE_ADDR        $remote_addr;
       fastcgi_param  REMOTE_PORT        $remote_port;
  }
}

Настройка Nginx для Mediawiki

Конфигурация нгинкс для вики ресурсов. Эта конфигурация проверена и в данный момент работает для wikiadmin.net

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
   server {
       listen       IP:80; #IP сервера
       server_name wikiadmin.net www.wikiadmin.net; #имя домена без www и с www
       root /var/www/html; #корень сайта
       charset utf-8;
       client_max_body_size 5m;
       client_body_timeout 60;
       index index.php index.html index.htm default.html default.htm; #обязательная строка, иначе nginx будет искать index.html
       location / { rewrite ^/(.*)$ /index.php?title=$1 last; } #строка убирает index.php в url
       location ~ .*.php$ {
       include /etc/nginx/fastcgi.conf;
       fastcgi_pass  127.0.0.1:9000;
           fastcgi_index index.php;
           }
       location = /robots.txt { break; } #эти данные статичны и могут сразу отдаваться клиенту
       location /skins/ { break; } #эти данные статичны и могут сразу отдаваться клиенту
       location /images/ { break; } #эти данные статичны и могут сразу отдаваться клиенту
       location /images/deleted/ { return 404; } 
       location ~ ^/extensions/.*\.css$ { break; }     #эти данные статичны и могут сразу отдаваться клиенту
       gzip             on; #включаем сжатие gzip для ускорения отдачи страниц
       gzip_min_length  1000;
       gzip_proxied     expired no-cache no-store private auth;
       gzip_types       text/plain application/xml;
       }

Настройка Nginx для Wordpress

Это рабочая конфигурация для вордпресс, проверено на нескольких серверах

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
   server {
       listen       IP:80; #IP сервер
       server_name wikiadmin.net www.wikiadmin.net; #имя домена без www и с www
       `[`root`](/root)` /var/www/html; #корень сайта
       access_log /var/www/logs/access_log; #логи вашего сайта
       error_log /var/www/logs/error_log; #логи вашего сайта
       charset utf-8;
       client_max_body_size 5m;
       client_body_timeout 60;
       index index.php index.html; #обязательная строка, иначе nginx будет искать index.html
       if (!-e $request_filename) {rewrite ^/(.*)$ /index.php?q=$1 last;  #строка убирает index.php в url
       }
       try_files $uri $uri/ /index.php;
       location ~ \.php$ {
       include        fastcgi_params;
       fastcgi_pass   127.0.0.1:9000;
       fastcgi_index index.php;
       fastcgi_param  SCRIPT_FILENAME  $document_`[`root`](/root)`$fastcgi_script_name;
                       }
       location ~ (/wp-content/cache/(wp-cache-.*\.html|meta)|\.htaccess) {
             deny all;
                 }

включаем сжатие GZIP

Для этого достаточно добавить в конфиг сайта следующее:

1
2
3
4
5
6
7
8
9
       gzip  on;
       gzip_static on;
       gzip_http_version 1.1;
       gzip_vary on;
       gzip_comp_level 6;
       gzip_proxied any;
       gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
       gzip_buffers 16 8k;
       gzip_disable “MSIE [1-6].(?!.*SV1)”;

gzip_static on подразумевает, что у вас могут быть сжатые копии некоторых файлов. Например, CSS, JS, GIF и так далее. Сделать их можно следующим образом:

for i in `find`  /var/www/site* -type f -name '*.css'; do echo $i; gzip -c -9 $i > $i.gz; done; `

for i in `find`  /var/www/site* -type f -name '*.js'; do echo $i; gzip -c -9 $i > $i.gz; done; `

for i in `find /var/www/site* -type f -name '*.gif'`; do echo $i; gzip -c -9 $i > $i.gz; done;

То есть меняется только расширение. GIF, PNG тоже можно сжать, если это элементы верстки страницы и редко изменяются.

Включаем кеширование

Вставляем что-то типа нижеприведённого в nginx.conf до каких-либо include в секцию http:

`proxy_cache_path /var/lib/nginx/cache levels=1:2 keys_zone=cache:30m max_size=1G;

`proxy_temp_path /var/lib/nginx/proxy 1 2;

`proxy_ignore_headers Expires Cache-Control;

`proxy_cache_use_stale error timeout invalid_header http_502;

`proxy_cache_bypass $cookie_session;

proxy_no_cache $cookie_session;

Создаём каталоги:

`mkdir -p  /var/lib/nginx/cache

`chown -R www-data /var/lib/nginx/cache

chmod 700 /var/lib/nginx/cache

Секция server в конфиге будет выглядеть примерно так (для wordpress):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
server {
        listen 192.168.61.1:80;
        server_name wikiadmin.net;
        location / {
        if ($http_cookie ~* "comment_author_|wordpress_(?!test_cookie)|wp-postpass_|wp-admin_" ) {
                set $do_not_cache 1;
                }
        proxy_cache_bypass $do_not_cache;
        proxy_cache_valid 10m;
        proxy_cache_valid 404 1m;
        proxy_cache_key "$request_method|$http_if_modified_since|$http_if_none_match|$host|$request_uri";
        proxy_hide_header "Set-Cookie";
        proxy_ignore_headers "Cache-Control" "Expires";
        proxy_pass http://127.0.0.1:8080;
        }
}

Показать содержимое директории (или папки)

1
2
3
location  /  {
  autoindex  on;
}

Настройка мультисабдомена в Nginx

1
2
3
4
5
6
7
8
9
10
11
12
13
server {
    listen   IP:80;
      server_name wikiadmin.net *.wikiadmin.net;
      access_log  /var/log/nginx/access.log;
      root /var/www/$subexample;
      set $subexample "";
           if ($host ~* ^([a-z0-9-\.]+)\.wikiadmin.net$) {
               set $subexample $1;
               }
           if ($host ~* ^www.wikiadmin.net$) {
           set $subexample "";
       }`
}

Где:

  • IP - ваш ip адрес сервера;
  • wikiadmin.net - ваш домен;
  • /var/www - путь к каталогу с сайтами.

То есть получаем:

Блокировка использования контента сторонним сервисом (хотлинк)

Как заблокировать контент (картинки и так далее), чтобы их не использовали на другом сайте.

1
2
3
4
5
6
location /images/ {
  valid_referers none blocked www.domain.com domain.com;
  if ($invalid_referer) {
  return 403;
  }
  }

www.wikiadmin.net wikiadmin.net - это ваши домены, для которых медиаконтент доступен.

Вместо return 403; вы можете использовать любой свой баннер:

rewrite ^/images/uploads.*\.(gif|jpg|jpeg|png)$ http://www.wikiadmin.net/banned.jpg last

Ошибка 413 Request Entity Too Large

Эта ошибка возникает, когда вы загружаете слишком большой файл. Добавьте в секцию http (в файл конфигурации nginx.conf) параметр и желаемый размер. Например, разрешим отправлять файлы до 100МБ:

client_max_body_size 100m;

И перезагрузите nginx.

Ошибка 499 в access.log

Nginx закрывал соединение без отправки запроса апачу. Исправляется добавлением

proxy_ignore_client_abort on

По умолчанию данный параметр равен off.

Установка spawn-fcgi для работы php в CentOS

Для начала нужно установить spawn-fcgi, который доступен в хранилищах:

yum install spawn-fcgi

Далее загрузите init-скрипт. Он доступен на странице bash.cyberciti.biz. Вот листинг скрипта самого скрипта, если он будет недоступен на странице:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#!/bin/sh
#
# php-cgi - php-fastcgi swaping via  spawn-fcgi
#
# chkconfi:   - 85 15
# description:  Run php-cgi as app server
# processname: php-cgi
# config:      /etc/sysconfig/phpfastcgi (defaults RH style)
# pidfile:     /var/run/php_cgi.pid
# Note: See how to use this script :
# http://www.cyberciti.biz/faq/rhel-fedora-install-configure-nginx-php5
# Source function library.
. /etc/rc.d/init.d/functions
 
# Source networking configuration.
. /etc/sysconfig/network
 
# Check that networking is up.
[ "$NETWORKING" = "no" ] && exit 0
 
spawnfcgi="/usr/bin/spawn-fcgi"
php_cgi="/usr/bin/php-cgi"
prog=$(basename $php_cgi)
server_ip=127.0.0.1
server_port=9000
server_user=nginx
server_group=nginx
server_childs=5
pidfile="/var/run/php_cgi.pid"
 
# do not edit, put changes in /etc/sysconfig/phpfastcgi
[ -f /etc/sysconfig/phpfastcgi ] && . /etc/sysconfig/phpfastcgi
 
start() {
    [ -x $php_cgi ] || exit 1
    [ -x $spawnfcgi ] || exit 2
    echo -n $"Starting $prog: "
    daemon $spawnfcgi -a ${server_ip} -p ${server_port} -u ${server_user} -g ${server_group} -P ${pidfile} -C ${server_childs} -f ${php_cgi}
    retval=$?
    echo
    return $retval
}
 
stop() {
    echo -n $"Stopping $prog: "
    killproc -p ${pidfile} $prog -QUIT
    retval=$?
    echo
    [ -f ${pidfile} ] && /bin/rm -f ${pidfile}
    return $retval
}
 
restart(){ 
   stop
   sleep 2
   start
}
 
rh_status(){
   status -p ${pidfile} $prog
}
 
case "$1" in
    start)
        start;;
    stop)
        stop;;
    restart)
        restart;;
    status)
        rh_status;;
    *)
        echo $"Usage: $0 {start|stop|restart|status}"
        exit 3
esac`

Сохраните его как /etc/init.d/php_cgi и сделайте исполняемым. После этого запустите скрипт:

/etc/init.d/php_cgi start

И проверьте, работает ли он:

netstat -tulpn | grep :9000

Вы должны будете увидеть такой ответ:

TCP        0      0 127.0.0.1:9000              0.0.0.0:*                   LISTEN

Скрипт готов к работе.

spawn-fcgi падает

Замечено, что этот процесс иногда падает. Я решил этот вопрос следующим образом…. У меня раз в минуту один скрипт проверяет наличие открытого 9000 порта (как это написано на этой странице). Я просто добавил строчку запуска процесса и получилось нечто подобное:

1
2
3
4
5
6
7
8
9
10
11
host=127.0.0.1
for port in  9000
do
 if nc -w 20 -z $host $port
 then
   echo port $port is up
 else
   echo port $port is down | mail -s "port result" admin@wikiadmin.net
   spawn-fcgi -a 127.0.0.1 -p 9000 -u apache -g apache -S -M 0600 -C 8 -F 1 -P /var/run/spawn-fcgi.pid -- /usr/bin/php-cgi
 fi
done`

Пробовал убить процесс вручную, в течении минуты получал сообщение, что порт down и процесс снова появлялся. Конечно же, это не есть хорошо, т.к. непонятно, почему spawn падает. Но этот вариант может спасти вас на некоторое время.