Настраиваем сервер для LiveStreet. Часть VII. NGINX.

Предыдущие части:

Общие замечания:
  1. Для продвинутых: рекомендуется не ставить nginx из бинарников, а пересобрать его из исходного кода только с нужными модулями. В бинарной сборке «по умолчанию», действительно, очень много для LiveStreet лишнего. Однако, я не считаю это простой задачей и поэтому описывать не буду. Кроме того, хотя эта идея, без сомнений, хорошая, драматического эффекта она не даст.
  2. Частично конфигурация снова взята из поста господина xyz
  3. Обращаю особое внимание на использование специального раздела для временных файлов, который, следуя советам господина Orhideous , мы создали во второй части

Ставим:
apt-get install nginx


Общий конфигурационный файл /etc/nginx/nginx.conf делаем таким:
user www-data;
worker_processes 4;
pid /var/run/nginx.pid;
timer_resolution 100ms;
worker_rlimit_nofile 8192;
worker_priority -5;
error_log /var/log/nginx/error.log;

events {
	worker_connections 1024;
	# multi_accept on;
}

http {

	##
	# Basic Settings
	##

	client_body_temp_path /var/spool/nginx/client_temp 1 2;
	proxy_temp_path  /var/spool/nginx/proxy_temp 1 2;	

	charset utf-8;
	autoindex off;

	sendfile on;
	# tcp_nopush on;
	# tcp_nodelay on;
	keepalive_timeout 65;
	types_hash_max_size 2048;
	server_tokens off;
        reset_timedout_connection on;

	# server_names_hash_bucket_size 64;
	# server_name_in_redirect off;

	include /etc/nginx/mime.types;
	default_type application/octet-stream;

	##
	# Logging Settings
	##

	## Log Format
	log_format  main  '$remote_addr $host $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" $ssl_cipher $request_time';

	access_log /var/log/nginx/access.log main buffer=32k;

	##
	# Gzip Settings
	##

	gzip on;
	gzip_disable "msie6";

	gzip_vary on;
	gzip_proxied any;
	gzip_comp_level 6;
	gzip_buffers 16 8k;
	gzip_http_version 1.1;
	gzip_types text/css application/x-javascript application/xml application/xml+rss application/rss+xml text/javascript;


	##
	# Virtual Host Configs
	##


	# Default by nginx guideline
	client_header_timeout  3m;
	client_body_timeout    3m;
	send_timeout           3m;

	client_header_buffer_size    1k;
	large_client_header_buffers  4 4k;

	client_max_body_size       100m;
	client_body_buffer_size    128k;

	# Hash Table
	server_names_hash_bucket_size 64;

	# Proxy
	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 64k;

        server {
            listen      80 default_server;
            return      444;
        }

	include /etc/nginx/sites-enabled/*;
}

  • В случае VPS, настоятельно рекомендую уменьшить количество worker_processes. 4, imho, в этом случае много. Можно даже поставить 1.
  • мелкое замечание — LiveStreet использует не совсем стандартный MIME для RSS: application/rss+xml, поэтому gzip_types им расширен.

Создаем каталоги для конфигураций сайтов, по аналогии с Apache (мне это кажется удобным стилем):
mkdir /etc/nginx/sites-available
mkdir /etc/nginx/sites-enabled

Сoздаём .htpasswd. Такие файлы изначально придуманы для Apache-а, содержат хэшированные аккаунты для доступа к ресурсу. Используется, в частности, для закрытия доступа к сайту (или какой-то его части) с помощью HTTP Auth. nginx тоже умеет с этим работать, и именно таким образом мы закроем доступ к паре «административных» страниц которые нам понадобятся в будущем. Создается просто:
htpasswd -bc /etc/nginx/sites-enabled/.htpasswd USERNAME PASSWORD
Эта команда сразу создаст нужный нам файл .htpasswd в нужном месте.

Создаём конфигурационный файл для нашего сайта /etc/nginx/sites-available/superls.ru:
server {
        listen 80;
        server_name  www.superls.ru;
        return 301 $scheme://superls.ru$request_uri;
}

server {
        listen 80;
        server_name superls.ru;

        access_log /var/www/superls.ru/logs/nginx.access.log;
        error_log /var/www/superls.ru/logs/nginx.error.log;

        root /var/www/superls.ru/public/;

        # Static Contents
        location ~* ^.+.(jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|pdf|ppt|txt|tar|mid|midi|wav|bmp|rtf)$ {
                access_log off;
                log_not_found off;                
                expires 1y;                
        }

        # CSS and JS
        location ~* ^.+.(css|js)$ {
                access_log off;
                log_not_found off;                
        }

        # this will prevent files like .htaccess .htpassword .secret etc from being served
        # You can remove the log directives if you wish to
        # log any attempts at a client trying to access a hidden file
        location ~ /\. { deny all; access_log off; log_not_found off; }

        location ~ \.(tpl|log)$ {deny all; access_log off; log_not_found off; }

        location = /apc.php {
            auth_basic "Super LS";
            auth_basic_user_file /etc/nginx/sites-enabled/.htpasswd;

            proxy_set_header X-Forwarded-For $remote_addr;
            proxy_set_header Host $host;
            proxy_pass http://127.0.0.1:8080;
        }

        location = /memcache.php {
            auth_basic "Super LS";
            auth_basic_user_file /etc/nginx/sites-enabled/.htpasswd;

            proxy_set_header X-Forwarded-For $remote_addr;
            proxy_set_header Host $host;
            proxy_pass http://127.0.0.1:8080;
        }

        # Dydamic Content forward to Apache
        location / {
            proxy_set_header X-Forwarded-For $remote_addr;
            proxy_set_header Host $host;
            proxy_pass http://127.0.0.1:8080;
        }
}

В самом начале обеспечивается HTTP 301 с домена с WWW на домен без WWW. Если оно не надо — просто удалить весь первый блок «server».

«Активируем» сайт:
ln -s /etc/nginx/sites-available/superls.ru /etc/nginx/sites-enabled/superls.ru

Ре-стартуем:
/etc/init.d/nginx restart


Нужно протестировать. Предполагается, что доменное имя уже публично видно. Просто вызываем наш сайт из браузера:
http://superls.ru/info.php


Теперь нужно протестировать правильно ли работает mod-rpaf (модуль апача который обеспечивает сохранение оригинального клинского IP при проксировании). Для этого создаем простенький файл /var/www/superls.ru/public/ip.php следующего содержания:
<?php
echo $_SERVER['REMOTE_ADDR'];
?>

Вызываем:
http://superls.ru/ip.php
и смотрим на IP. Если там НЕ 127.0.0.1, то всё в порядке.

Вдогонку: обращаю внимание на очень полезную ветку комментариев: livestreet.ru/blog/dev_documentation/14894.html#comment240202

Продолжение в следующей части:
Часть VIII. APC, Memcached & Sphinx.

61 комментарий

avatar
Только хотел пойти спать, думаю дай обновлю вкладку, почитаю что ещё пишут, и тут на. :)
Такс. А что с дефолт сервером будем делать? Ок, будем как и положено думать, что это у нас первый виртуал хост, который будет активирован.
Придёт к нам запрос на айпишку, или на значение заголовка Host, которое не определёно не в одном сервере директивой server_name. Что будем делать? Отправим юзера на этот самый наш виртуалхост с LS? А апач это одобрит или энжиниксу придётся отдать ответ какой нить 502?
avatar
хм. apache одобрит. Но, да, вы правы — как-то не хорошо. Предложения?
avatar
nginx.org/ru/docs/http/request_processing.html
Там правда рекомендуют возвращать 444, но я принципиально стараюсь поступать более дружелюбно, ставлю страничку заглушку с надписью «Сайт не найден или заблокирован».
avatar
тоже добавил пока в самом базовом варианте. но лучше чем нечего.
avatar
И ещё, нет смысла определять в конфиге параметры со значениями, которые итак имеют такое-же дефолтное значение.
И ещё, рекомендуется в принципе reset_timedout_connection on, и настройка модулей limit_reg, limit_conn, иначе пачка апача с fpm скажет нам привет как нибудь багодаря студенту, которому скучно.
avatar
Давайте сразу опции со значениями, я как обычно, протестирую и внесу исправления :)
avatar
Настройка лимитов дело в принципе интимного характера, т.к все сайты устроены по разному.
avatar
reset_timedout_connection on; протестил и добавил в конфиг.
avatar
Прокси таймауты 90сек. Не много-ли, с учётом, что особенно бэкэнд на локальном сервере.
avatar
На само деле зависит, от сервера. Для выделенного — много. для дешевенького и как следствие совсем не быстрого VPS — вполне нормально. Плюс, на самом деле, там таймаут в насройках mod-fastcgi галавным образом решает и он, по умолчанию 30 сек. Так что зла особого нет — тут просто с запасом.
avatar
Аналогично :)
avatar
Я еще ставлю
        rewrite ^([^.]*[^/])$ $1/ permanent;
чтобы добавлять конечный слеш для всех страниц в URL которых нет точки и нет конечного слеша — убирает возможные дубли. Но это дело вкуса.
avatar
Идея полезная, но случай редкий, мне кажется. Это скорее похоже на исправление какого-то собственного косяка :)
avatar
Ну как… Никакой гарантии, что свежеиспеченные шаблоностроители все делают правильно. Не говоря уже о плагиностроителях, кто с версткой может вообще не дружить. Поэтому… Лучше подуть на воду :)
avatar
На самом деле эта штука должна выглядеть вот так:

if ($request_method != POST ) {
        rewrite ^([^.]*[^/])$ $1/ permanent;
}
чтобы ajax POST запросы не редиректились.
avatar
А из каких реп его ставить, дотдеб комментировать или нет?
avatar
дотдеб комментировать сразу после установки PHP (о чем прямо писалось в прошлой части) и больше не трогать. Ставится nginx из собственного родного репозитория который подключали в третей части
avatar
А обновлять разве не надо будет php? Ведь бывают даже обновления безопасности. Лучше это делать с dotdeb, раз ставили от туда.
зы. В 7-ом дебиане fpm ожидается в официальных репозиториях.
avatar
оно не будет обновятся не с dotdeb (когда он закомментирован), я лично считаю обновление php без контроля (т.е. без проверки чего там точно поменялось) делом опасным. До конца установки, в любом случае, держим в комментированном состоянии, чтобы путаница не возникла, потом для обновлений, можно включить.
avatar
Ну проверил наличие обновлений, если есть, глянул aptitude changelog, потом обновляй.
avatar


Поставил, пропали все картинки
avatar
у меня тоже самое было. запускал через встроенный сервер в php(начиная с версии php 5.4). в остальном пока что все гладко
avatar
Еще фаилы ругается на диру

nginx: [emerg] mkdir() "/var/spool/nginx/client_temp" failed (2: No such file or directory)
...@qlcom /tmp # mkdir /var/spool/nginx
...@qlcom /tmp # service nginx start
nginx: [emerg] open() "/.../.../.../logs/nginx.access.log" failed (2: No such file or directory)
avatar
С самого начала еще раз все переустановил, теперь Api нормальный а не апаче хэндлер, и этих ошибок в процессе установки не было, просто в прошлый раз пытался накатить сверху. Так что все ок, спасибо за мануал!
avatar
Думал ещё, поделится сразу или нет. Ну ладно. Не на что не предентую, просто как идея, и маленький help, тем, кто не особо шарит. Хорошим тоном будет отдать ещё специальную страничку ошибок клиенту, (более понятную обычному юзеру) чем скучную дефолтную ошибку энжиникса или апача. (Мы-же хотим быть дружелюбней к юзеру?)
Архив с конфигом энжиникса и самими страничками.
Раскидать всё так, как лежит в архиве. Странички ошибок в /usr/share/nginx/error_pages
Конфиг определяющий что отдавать в /etc/nginx/conf.d/error_pages.conf.
В каждый server существующий добавить
include /etc/nginx/conf.d/error_pages.conf;
    location /error_pages/ {
        internal;
        root /usr/share/nginx;
    }

Пример странички 404.
avatar
Это ценно не столько дружественностью, сколько наличием правильного линка на главную страницу сайта. Спасибо. :)
avatar
В apache кстати тоже надо будет настроить странички ошибок, раз он у вас на бэкэнде.
avatar
Не факт… по идее если не правильный запрос успешно передался на Apache то сработает 404 LiveStreet
avatar
Факт. :)
mmozg.net/engine/ Это мне напоминает уже дефолтный ответ апача. Не так-ли?
avatar
avatar
угу. :) вы правы :)
avatar
может выложите аналог того, что Вы выложили для nginx? Для тех, кто не очень шарит)
avatar
Как всегда, в топик будут вносится изменения на основе обсуждений в комментариях. Посмотрим, возможно и эта тема тоже.
avatar
Что именно выложить вам?
avatar
сами страницы есть в том архиве для nginx, а как настроить переадресацию на них с apach'a если сам сайт не отдаст 404 или еще какую ошибку?
avatar
Alias /error_pages/ "/usr/share/nginx/error_pages/"

ErrorDocument 400 /error_pages/400.html
ErrorDocument 401 /error_pages/401.html
ErrorDocument 402 /error_pages/402.html
ErrorDocument 403 /error_pages/403.html
ErrorDocument 404 /error_pages/404.html
ErrorDocument 405 /error_pages/405.html
ErrorDocument 406 /error_pages/406.html
ErrorDocument 407 /error_pages/407.html
ErrorDocument 408 /error_pages/408.html
ErrorDocument 409 /error_pages/409.html
ErrorDocument 410 /error_pages/410.html
ErrorDocument 411 /error_pages/411.html
ErrorDocument 412 /error_pages/412.html
ErrorDocument 413 /error_pages/413.html
ErrorDocument 414 /error_pages/414.html
ErrorDocument 415 /error_pages/415.html
ErrorDocument 416 /error_pages/416.html
ErrorDocument 417 /error_pages/417.html
ErrorDocument 500 /error_pages/500.html
ErrorDocument 501 /error_pages/501.html
ErrorDocument 502 /error_pages/502.html
ErrorDocument 503 /error_pages/503.html
ErrorDocument 504 /error_pages/504.html
ErrorDocument 505 /error_pages/505.html
avatar
Мы, видимо, не поняли друг друга. Этот файл есть в том же архиве.
В apache кстати тоже надо будет настроить странички ошибок, раз он у вас на бэкэнде.
Как это настроить?
avatar
В архиве конфиг определяющий странички ошибок на nginx и сами странички.
То, что я привёл, щас — это конфиг для апача.
avatar
Я так понимаю, что подкючать его надо в /etc/apache2/apache2.conf, а как это сделать? (для nginx вставляли в секцию server, а тут надо тоже самое во все секции virtualhosts вставить?)
avatar
В принципе можно закинуть в /etc/apache2/conf.d/error_pages.conf.
Апач сам должен будет от туда заинклюдить, если в /etc/apache2/apache2.conf ничего не меняли.
avatar
я так и сделал в итоге, да, апач сам инклудит этот конфиг)
avatar
у меня не работает этот вариант — все те же стандартные страницы ошибок. Конфиг нгинкса:

server {
                server_name www.site.ru;
		listen XX.XX.XX.XXX;
                rewrite ^(.*) http://site.ru$1 permanent;
                include /etc/nginx/conf.d/error_pages.conf;
                location /error_pages/ {
                        internal;
                        root /usr/share/nginx;
                }          
        }
         server {
		server_name site.ru;
		listen XX.XX.XX.XXX;
		disable_symlinks if_not_owner from=$root_path;
		set $root_path /var/www/site/data/www/site.ru;
		location ~* ^.+\.(jpg|jpeg|gif|png|svg|js|css|mp3|ogg|mpe?g|avi|zip|gz|bz2?|rar|swf)$ {
			root $root_path;
			access_log /var/www/nginx-logs/site isp;
			access_log /var/www/httpd-logs/site.ru.access.log ;
		
		}
                include /etc/nginx/conf.d/error_pages.conf;
                location /error_pages/ {
                        internal;
                        root /usr/share/nginx;
                }        
		location / {
			proxy_pass http://XX.XX.XX.XXX:81;
			proxy_redirect http://XX.XX.XX.XXX:81/ /;
			proxy_set_header Host $host;
			proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
			proxy_set_header X-Forwarded-Proto $scheme;
			proxy_set_header X-Real-IP $remote_addr;
                        
                       
		}
		location ~* ^/(webstat|awstats|webmail|myadmin|pgadmin)/ {
			proxy_pass http://XX.XX.XX.XXX:81;
			proxy_redirect http://XX.XX.XX.XXX:81/ /;
			proxy_set_header Host $host;
			proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
			proxy_set_header X-Forwarded-Proto $scheme;
			proxy_set_header X-Real-IP $remote_addr;
		}
		location @fallback {
			proxy_pass http://XX.XX.XX.XXX:81;
			proxy_set_header Host $host;
			proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
			proxy_set_header X-Forwarded-Proto $scheme;
			proxy_set_header X-Real-IP $remote_addr;
		}
               
		include /usr/local/ispmgr/etc/nginx.inc;

                 
	}

Все папки и файлы на нужных местах, но эффекта нет (
avatar
Как поняли что это не работает? nginx перезапускали?
avatar
добавил в location строку, вызывающую 500-ю ошибку и посмотрел на нее)
Само собой перезапускал
avatar
Дайте в личку адрес сайта где делали. Глянем.
avatar
Я поступил проще, чем преложено у ewden . Просто скопировал папку /error_pages/ со всем страницами в document-root сайта. После чего прописал для Nginx директивы error_page в секции server для сайта, и для апача ErrorDocument в секции VirtualHost.

И у nginx и у apache директива работает отталкиваясь от document-root. Так что ничего больше и не надо пробивать. Более того так даже Imho правильнее потому что можно придать этим страницам специфический дизайн соответствующий именно этому сайту. И иметь уникальный набор таких страниц для каждого сайта на сервере.
avatar
Можно всё конечно по желанию. :) На своих сайтах я не запаривался с этим особо. Ибо цель была сделать просто странички ошибок мение пугающие обычных юзеров.
На сайтах конторы где работаю, там тоже, все странички ошибок имеют просто дизайн приближённый к дизайну основного сайта компании.
avatar
Возможно кому нибудь пригодится habrahabr.ru/post/84172/
avatar
Вот еще qrator.net/about/news/2/
avatar
Я уж было подумал вы предлагаете тут услугами qrator воспользоваться… ))
Вообще, мой вам совет, не читайте советских газет до обеда.
Это всё даст очень сильное ложное чувство защищённости.
avatar
Пара весьма любопытных идей есть. " Быстро отлавливаем «GET / » например.
avatar
Недавно голову ломал над проблемой, два практически одинаковых сайта на LS на одном выделенном сервере, отличие небольшое в плагинах, на одном и другом порядка 30 плагинов. Первый сайт выдавал порядка PHP: time load modules: 0,1 full time: 0,8
Второй выдавал PHP: time load modules: 0,33 full time: 1,5
Сначала я думал, что какой то плагин (плагины) на втором сайте влияют на показатели. Сделал плагины один в один с первым — результаты не изменились. Потом полез в конфиг nginx — оказывается для первого домена была такая запись
location ~* ^.+\.(jpg|jpeg|gif|png|svg|js|css|mp3|ogg|mpe?g|avi|zip|gz|bz2?|rar|swf|ico|tgz|gz|bz2|doc|xls|exe|pdf|ppt|txt|tar|mid|midi|wav|bmp|rtf|js|flv)$ {

Для второго было так:
location ~* ^.+\.(jpg|jpeg|gif|png|svg|js|css|mp3|ogg|mpe?g|avi|zip|gz|bz2?|rar|swf)$ {

Сделал все как в первом — показатели выровнялись. Более глубоко не копал, но может быть кому то будет полезно. Также интересует какой здесь оптимальный список расширений должен быть.
avatar
Скажите, а почему Вы в конфиге сайта не посылаете php скрипты в fast-cgi на обработку? (например так):

location ~ \.php {
                       fastcgi_pass  unix:/tmp/fastcgi.socket;
                       fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                       include fastcgi_params;
                }
  • dsg
  • 0
avatar
Потому что эта конфигурация рассчитана на работы в связке с апачем.
avatar
тогда зачем здесь мы ставили fastcgi?

Не ругайте сильно), просто пытаюсь разобраться и понять
avatar
ну и попутно вопрос: в предлагаемой Вами конфигурации php используется все таки, как модуль апача или как fastcgi? (что мне в панели isp для домена ставить?)
avatar
apache(mpm_worker)+mod-fastcgi+php-fpm.
mod-fastcgi нужен чтобы подключить php-fpm используя опцию FastCGIExternalServer
почитайте внимательно предыдущую часть.
avatar
Подскажите пожалуйста, если у меня есть желание запустить на настроенном по данному гайду сервере ещё один сайт на лайвстрит, мне лишь нужно создать ещё один конфиг для нового сайта как в /etc/apache2/sites-available/ так и /etc/nginx/sites-enabled/, и всё?
avatar
Вот у меня тоже вопрос: инклудится в основном конфиге вот это
include /etc/nginx/sites-enabled/*;

А конфиг для виртуального хоста создаем почему то в /etc/nginx/sites-available/superls.ru:

Автор поясни пожалуйста где создавать конфиги для всех сайтов… а то я уже не могу портянку для кучи сайтов нормально редактировать:)
avatar
Обычная практика, когда настройки всех сайтов хранятся в каталоге «sites-available», а в каталоге «sites-enabled» создаются символьные или жесткие ссылки на конфигурационные файлы для активных (включенных) сайтов.
avatar
А понял, вот это объясняет
ln -s /etc/nginx/sites-available/superls.ru /etc/nginx/sites-enabled/superls.ru
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.