Итак, имеем веб сервер
Nginx в качестве фронтэнда, на бакэндах
Apache и какой-нибудь
fastcgi (
spawn-fcgi или
php-fpm). Функциональные возможности серверов, nginx и apache, несколько различаются, и одно из различий как раз в том, что nginx не поддерживает обработку файлов htaccess, которые в apache используются практически повсеместно. Большинство сайтовых движков (CMS), поддерживают возможность генерировать так называемые ЧПУ(человекопонятный урл, в оригинале, SEF -
search engines friendly url), но для этого, веб сервер, должен обрабатывать строку запроса определенным образом, что apache и делает с помощью
mod_rewrite и правил в файле
.htaccess. Задача: заменить правила
.htaccess, соответствующими директивами в конфигурационном файле
nginx.conf.
Приведу несколько вариантов, для распространенных движков.
Все приведенные ниже варианты, рабочие, настроены и проверены на сервере под управлением
операционной системы FrereBSD 7.1, версия
Nginx 7.59.
Данные настройки касаются стандартных SEF модулей, встроенных в движки.
во всех примерах подразумевается, что версия nginx поддерживает именованные location и директиву try_files
Конфигурация Nginx и Apache для Joomla 1.0.15
Правила htaccess:
[apache]
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
## RewriteCond %{REQUEST_URI} ^(/component/option,com) [NC,OR] ## опционально ##
RewriteCond %{REQUEST_URI} (/|\.htm|\.php|\.html|/[^.]*)$ [NC]
RewriteRule ^(content/|component/) index.php
[/apache]
Эквивалент для настройки сервера nginx
[apache]
location / {
index index.php index.html index.htm;
}
## в поставляемом с дистрибутивом, файле htaccess, есть опциональная строка, по-умолчанию закомментирована
## данный блок ее эквивалент для nginx
#
# location ^~ /component/option,com {
# index index.php index.html index.htm;
# try_files $uri $uri/ @joomla;
# }
#####
location ~* (\.html?|/|/[^.]*)$ {
try_files $uri $uri/ @joomla;
index index.php index.html index.htm;
}
location ~ \.php$ {
try_files $uri @joomla;
fastcgi_pass unix:/tmp/php-fpm.sock; ## Ваш fastcgi сервер
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params; ## стандартный файл, идущий с nginx
}
location @joomla {
fastcgi_pass unix:/tmp/php-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root/index.php;
include fastcgi_params;
}
[/apache]
Конфигурация Nginx и Apache для Joomla 1.5.10
Правила htaccess:
[apache]
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !^/index.php
RewriteCond %{REQUEST_URI} (/|\.php|\.html|\.htm|\.feed|\.pdf|\.raw|/[^.]*)$ [NC]
RewriteRule (.*) index.php
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization},L]
[/apache]
Эквивалент для настройки сервера nginx
[apache]
location / {
index index.php index.html index.htm;
}
location ~* (/|\.html?|\.feed|\.pdf|\.raw|/[^.]*)$ {
try_files $uri $uri/ @joomla;
}
location ~ \.php$ {
try_files $uri @joomla;
fastcgi_pass unix:/tmp/php-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
location @joomla {
fastcgi_pass unix:/tmp/php-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root/index.php;
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 REDIRECT_STATUS 200;
fastcgi_param SCRIPT_NAME /index.php;
fastcgi_param REQUEST_URI $request_uri;
fastcgi_param DOCUMENT_URI $document_uri;
fastcgi_param DOCUMENT_ROOT $document_root;
fastcgi_param SERVER_PROTOCOL $server_protocol;
fastcgi_param GATEWAY_INTERFACE CGI/1.1;
fastcgi_param SERVER_SOFTWARE nginx/$nginx_version;
fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param REMOTE_PORT $remote_port;
fastcgi_param SERVER_ADDR $server_addr;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_NAME $server_name;
}
[/apache]
Примечание: в первом примере, fastcgi_param были загружены из стандартного файла, идущего в поставке nginx, во втором, я не стал инклудить файл с параметрами а просто прописал их в конфиг, обратите внимание что параметр SCRIPT_NAME, отличается от первого примера.
Конфигурация Nginx и Apache для Wordpress 2.7.1
Правила htaccess:
[apache]
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
[/apache]
Эквивалент для веб сервера nginx
[apache]
location / {
try_files $uri $uri/ @wordpress;
index index.php index.html index.htm;
}
location ~ \.php$ {
try_files $uri @wordpress;
fastcgi_pass unix:/tmp/php-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
location @wordpress {
fastcgi_pass unix:/tmp/php-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root/index.php;
include fastcgi_params;
}
[/apache]
Как видите, тут мы тоже просто инклудим стандартный файл с
fastcgi параметрами
Конфигурация Nginx и Apache для Drupal 6.12
Правила htaccess:
[apache]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !=/favicon.ico
RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]
[/apache]
Эквивалент для сервера nginx
[apache]
location / {
try_files $uri $uri/ @drupal;
index index.php index.html index.htm;
}
location ~ \.php$ {
try_files $uri @drupal;
fastcgi_pass unix:/tmp/php-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
location @drupal {
fastcgi_pass unix:/tmp/php-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root/index.php;
---------------------------------------------------------------------------------------------------------------------
fastcgi_param QUERY_STRING q=$uri&$args;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
fastcgi_param REDIRECT_STATUS 200;
fastcgi_param SCRIPT_NAME /index.php;
fastcgi_param REQUEST_URI $request_uri;
fastcgi_param DOCUMENT_URI $document_uri;
fastcgi_param DOCUMENT_ROOT $document_root;
fastcgi_param SERVER_PROTOCOL $server_protocol;
fastcgi_param GATEWAY_INTERFACE CGI/1.1;
fastcgi_param SERVER_SOFTWARE nginx/$nginx_version;
fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param REMOTE_PORT $remote_port;
fastcgi_param SERVER_ADDR $server_addr;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_NAME $server_name;
---------------------------------------------------------------------------------------------------------------------
Весь список fastcgi параметров приведен для наглядности, данный блок можно сократить до:
include fastcgi_params;
fastcgi_param QUERY_STRING q=$uri&$args;
fastcgi_param SCRIPT_NAME /index.php;
}
[/apache]
Более короткий и красивый вариант.
[apache]
location / {
try_files $uri $uri/ /index.php?q=$uri&$args;
index index.php index.html index.htm;
}
location ~ \.php$ {
fastcgi_pass unix:/tmp/php-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
[/apache]
Вот собственно и все, единственное что стоит добавить, все рассмотренные правила касаются именно
SEF, я здесь не затрагивал правила безопасности, так-же добавляемые в htaccess почти всеми движками, возможно распишу попозже)
Всем удачи.
Комментарии
Благодарю ответившего - таки все заработало, за исключением того, что главная открывается только с указанием индексного файла. А по неверным символам в URL пришлось дописать строчку в конфиг CI. Есть решение одно здесь http://codeigniter.com/forums/viewthread/62347/ , но как выставить в конфиге base64, я так и не понял...
честно говоря не понял при чем тут base64, с CI вообще не сталкивался
попробуйте дописать в первый location
base4 здесь при том, что, при внутренних правилах роутинга переход на любую страницу (с уже оптимизированными под структуру проекта uri адресам) выдавалось сообщение "ваш uri содержит недопутимые символы". Но это уже проблема настройки самого CI. Если удастся побороть, то отпишу сюда рабочий конфиг того и другого. Кстати, а каким то образом можно отловить внутренний uri, который выдает CI после вебсервера дабы проверить, на какой символ он ругается ?
*base64 конечно же.
Благодарю, теперь все работает. Но подскажите, если главная открывается и с указанием индексного файла, то как мне запретить такой uri ?
разве это не подойдет ?
http://vds-admin.ru/nginx/nginx-i-301-redirekt-301-moved-permanently
в вашем случае, скорее всего, достаточно прописать
В любом из случаев с этими строчками в конфиге веб сервер предлагает скачать некий текстовый файл default.txt, отказываясь грузить главную напрочь.
а если целиком ?
Отлично! Спасибо огромное! С меня причитается, в любом случае.
В итоге конфиг получился такой:
server {
listen 80;
server_name http://www.example.com;
rewrite ^ http://example.com$request_uri? permanent; #301 redirect
}
server {
listen 80;
server_name .example.com;
access_log /var/log/nginx/localhost.access.log;
root /var/www/nginx-default;
# removes access to "system" folder, also allows a "System.php" controller
if ($request_uri ~* ^/system) {
rewrite ^/(.*)$ /index.php?/$1 last;
break;
}
location = /index.php {
if ($request_uri = /index.php) {
rewrite ^ http://$host? permanent;
}
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
location / {
try_files $uri $uri/ /index.php?$request_uri;
index index.php;
}
error_page 404 /index.html;
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /var/www/nginx-default$fastcgi_script_name;
include fastcgi_params;
}
location ~* \.(jpg|jpeg|gif|png|ico|css|js)$ {
access_log off;
gzip_static on;
expires max;
}
}
Может быть есть какие идеи по оптимизации с целью уменьшения количества строк ?
а без этого не работает ?
Без этого работает - это я поставил для закрытия доступа к папке с CI самим. Думаю, надо оставить. а в остальном нормально ?
вроде нормально, но я движка не знаю
в смысле к файлам в этой папке ?
лучше тогда сделать что-то типа:
или так
Покумекал и вот чего получилось в итоге (все работает как надо):
server {
listen 80;
server_name http://www.example.com;
rewrite ^ http://example.com$request_uri? permanent;
}
server {
listen 80;
server_name .example.com;
access_log /var/log/nginx/localhost.access.log;
root /var/www/nginx-default;
if ($request_uri ~* ^/system) {
rewrite ^/(.*)$ /index.php?/$1 last;
break;
}
location / {
if ($request_uri = /index.php) {
rewrite ^ http://$host? permanent;
}
try_files $uri $uri/ /index.php?$request_uri;
index index.php;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_scr 24 ipt_name;
include fastcgi_params;
}
location ~* \.(jpg|jpeg|gif|png|ico|css|js|exe|gz|avi|html)$ {
access_log off;
gzip_static on;
expires max;
}
error_page 404 /index.html;
}
Думаю, можно и количество серверов до одного уменьшить.
Я тоже движка не знаю, но оказалось, что все не так сложно и это можно побороть.
В предыдущем сообщении опечатка закралась.
Вместо
_scr 24 ipt_name;
должно быть конечно же
_sript_name;
Поглядел доку по nginx 0.8 ветки, похоже можно выкрутится (пока проверить не могу, так как сайт пока временно без домена на vds):
server {
listen 80;
server_name ~^(www\.)?(?.+)$;
access_log off;
root /var/www/nginx-default;
if ($host = www.example.com) {
rewrite ^ http://$domain$request_uri? permanent;
}
if ($request_uri ~* ^/system) {
rewrite ^ / permanent;
break;
}
location / {
if ($request_uri = /index.php) {
rewrite ^ http://$host? permanent;
}
try_files $uri $uri/ /index.php?$request_uri;
index index.php;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_scr 27 ipt_name;
include fastcgi_params;
}
location ~* \.(jpg|jpeg|gif|png|ico|css|js|exe|gz|avi|html)$ {
access_log off;
gzip_static on;
expires max;
}
error_page 404 /index.html;
}
Еще бы проверить, но нет пока возможности.
Если в этом блоке в троке server_name не будет знаков больше и меньше, то этот листинг получается не полноценный. Вобщем, тут речь идет о переменной domain.
Итог трудового дня (минимально необходимый конфиг):
server {
listen 80;
server_name ~^(www\.)?(?.+)$;
access_log off;
root /var/www/nginx-default;
if ($host = www.softvault.ru) {
rewrite ^ http://$domain$request_uri? permanent;
}
location / {
if ($request_uri = /index.php) {
rewrite ^ http://$host? permanent;
}
try_files $uri $uri/ /index.php?$request_uri;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
location ~* \.(jpg|jpeg|gif|png|ico|css|js|exe|gz|avi|html)$ {
gzip_static on;
expires max;
}
}
а откуда должна взяться переменная $domain ?
и от этого лучше избавиться:
сделав через
разработчик не рекомендует использовать if без крайней нужды, в данном случае никакой крайней нужды я не вижу)
Глядим сюда и видим в описании директивы server_name переменную domain.
То есть, придется возвращаться к варианту с двумя server {} ?
*сюда http://sysoev.ru/nginx/docs/http/ngx_http_core_module.html#server
Вот на этом пока остановлюсь. Вместо стандартной 404 страницы выдается в точности 404 страница, генерируемая самим CI. Это оказалось сделать проще, чем придумывать правила и усложнять сам конфиг nginx.
Ошибочка, вместо:
rewrite ^ http://$host? permanent;
долно быть:
rewrite ^ / permanent;
может все таки внимательно прочитаете документацию ?
эта переменная появляется при создании именованного выделения, а у вас в конфиге, кторый был приведен выше, обычное
Если вы внимательно посмотрите на конфиг, под которым я это писал, то там все в точности так, как написано у вас.
Впрочем, это уже не имеет значения, так как можно обойтись и без этого. Тем более, что работает это только в ветке 0.8, тогда как может так случиться, что придется поднимать на 0.7
я и привел кусок вашего конфига, в котором используется не существующая переменная $domain, вот он:
Уважаемый, я ценю вашу помощь, но здесь нельзя размещать " domain " <- вот такое выражение из примера с сайта nginx. Переменная, со знаками "меньше" перед domain и "больше" после domain (вместо пробелов), просто накуй вырезается. Как я уже говорил, все это работает только в 0.8 ветке. Посему решено отказаться от такого варианта в пользу более универсального.
А располагается это выражение после комбинации вот этих символов "?(?" в строке server_name, что и является инициализацией существующей переменной $domain. Посмотрите здесьhttp://sysoev.ru/nginx/docs/http/ngx_http_core_module.html#server_name и все станет понятно. Еще раз повторюсь. Здесь этот набор символов просторежется напрочь, поэтому его и нет в моем примере.
да все понял уже, нужно было просто так и написать, что парсер отрезал символы
как-то не обращал на это внимания
Теперь вопрос. Правда он уже касается самого CI. Может ли обработка допустимых символов в uri зависеть от версии php. На старом хостинге php более древний, чем на vds. Но на старом php то список обрабатывается корректно, в отличие от нового на vds. Может с функциями опять намудрили чего. Собственно, это единственное препятствие для полноценного переноса сайта.
Похоже, действительно, была виновата версия php. Установил олдстэйбл 5.2.14 и все заработало со старыми настройками.
Спасибо Анонимному пользователю за участие. Надеюсь, описанное здесь будет полезным кому-либо и ему не придется тратить время на такие оказии.
Подскажите пожайлуста, как правильно сделать рерайт для
RewriteEngine on
RewriteRule ^([a-zA-Z]{0,25}+).html([a-zA-Z0-9\&\=]{0,100}+)? index.php?page=$1$2 [L]
RewriteRule ^page-([0-9]{0,10}+).html? index.php?page=page&id=$1 [L]
RewriteRule ^news-([0-9]{0,10}+).html? index.php?page=news&id=$1 [L]
такого htaccess
Заранее благодарен
Вот тут есть что то похожее, но кумекайте сами ибо я не настолько силен в регулярных выражениях.
http://forum.nginx.org/read.php?21,110209,110410
Подскажите, как настроить RewriteRule для efront
Особенность заключается в том, что efront ставится не в корень, а в папку www (и только в неё).
Соответственно на nginx у меня папка /var/www/client/web/
т.е. не www и в папку /client/ я писать не могу, т.к. нет прав.
Получается, что efront надо установить в папку /var/www/client/web/www/
Вопрос - как настроить RewriteRule чтобы в адресной строке не было /www/, но файлы брались оттуда?
Я добавил
location / {
alias /var/www/client/web/www/;
}
но, теперь надо вводить адрес полностью, вместе с php
и странная штука (для меня не понятная)
если я ввожу просто адрес, без .php то все работает как надо, но берется файл index.html
с файлами .php все работает как будто нет связки alias
добавлял index index.php index.html - не помогает
все решилось
в секции server {
поправил root добавив в конце /www
и добавил своё правило
location / {
root /var/www/client/web/www/;
}
только уже с root, а не alias
в итоге получилось так
server {
listen *:80;
...
root /var/www/client/web/www/;
...
location / {
root /var/www/client/web/www/;
}
}
небольшая поправка - можно просто поменять root и не добавлять
location / {
root /var/www/client/web/www/;
}
т.е. сделать так:
server{
...
listen *:80;
...
root /var/www/client/web/www/;
...
}
И не забыть перечитать настройки
#sudo /etc/init.d/nginx reload
Не как не могу настроить работу joomla 3.4.1 работающие под управлением FactCGI+(Nginx+PHP-FPM)
Вот мой конфиг nginx /etc/nginx/nginx.conf
и конфиг сайта /etc/nginx/vhosts/ciberbox.ru.conf
Как мне настроить? помогите пожалуйста, уже все перепробовал
Отправить комментарий