Цель: Предоставить конфигурацию виртуального сервера Nginx для работы Битрикс-cms в связке Nginx+PHP-FPM. Который в прочем подойдёт и для связки Nginx+Apache2, с небольшими доработками.
Целевая аудитория: Администраторы серверов, продвинутые администраторы сайтов, программисты.
Cтатей на эту тему достаточно, но если смотреть не официальные, то там как правило содержатся ошибки, а в официальных полно if которые в Nginx использовать не желательно. Надеюсь после того как я выложу данный конфиг к связке Nginx+PHP-FPM станут относиться серьёзнее.
Вот официальный конфиг для работы композитного кэша с отдачей через nginx.
Я покажу реализацию отдачи файлового композитного кэша. В целом отдача с memcached делается по аналогии. В конфигурации отдачи файлового кэша я насчитал 11 if, от которых я и избавился переделав их на map.
Начну с упрощённого варианта ЧПУ для тех кому нужна просто связка Nginx+PHP-FPM без отдачи композитного кэша через Nginx. Подразумевается что секция server уже настроена, с доменными именами и передачей в php-fpm.
Как не удивительно смотря на те полотна конфигов которые мне попадались, этого достаточно чтобы битрикс корректно заработал. Если нужен редирект с index.php и index.html на без, то нужно ещё дописать вот эту строку:
К сожалению тут достойной замене if нет. Но данная строчка работает не создавая проблем.
Хочу подчеркнуть что это именно минималистичная конфигурация без правил для статики, сжатия, и я там прикрыл только файлы композитного кэша от прямого доступа. Конфигурация которая прикрывает определённые места от прямого доступа через nginx довольно индивидуальна. У меня есть вот такой набор который может кому-то подойти. Но использовать нужно аккуратно с осознанием дела. Учитите что внесение данных локейшенов в свою конфигурацию может привести к неработоспособности сайта или части его функций.
Ну и конечно пример location для статических файлов
Теперь перейдём к конфигу для работы композита с отдачей файлов кэша через nginx. Первым делом необходимо определить можно ли отдавать данному запросу композитный кэш или его нужно отправить на обработку через php. Для этого в Nginx в секции http добавим несколько map, а так же несколько директив:
Далее уже непосредственно в секции server прописываем
Ну и для понимания как примерно будет выглядеть минимальная конфигурация секции server
Буду рад вопросам и предложениям по поводу данного конфига, а так же за радость посмотрю Ваши наработки.
Целевая аудитория: Администраторы серверов, продвинутые администраторы сайтов, программисты.
Cтатей на эту тему достаточно, но если смотреть не официальные, то там как правило содержатся ошибки, а в официальных полно if которые в Nginx использовать не желательно. Надеюсь после того как я выложу данный конфиг к связке Nginx+PHP-FPM станут относиться серьёзнее.
Вот официальный конфиг для работы композитного кэша с отдачей через nginx.
Я покажу реализацию отдачи файлового композитного кэша. В целом отдача с memcached делается по аналогии. В конфигурации отдачи файлового кэша я насчитал 11 if, от которых я и избавился переделав их на map.
Начну с упрощённого варианта ЧПУ для тех кому нужна просто связка Nginx+PHP-FPM без отдачи композитного кэша через Nginx. Подразумевается что секция server уже настроена, с доменными именами и передачей в php-fpm.
location / { try_files $uri $uri/ /bitrix/urlrewrite.php$is_args$args; }
Как не удивительно смотря на те полотна конфигов которые мне попадались, этого достаточно чтобы битрикс корректно заработал. Если нужен редирект с index.php и index.html на без, то нужно ещё дописать вот эту строку:
if ($request_uri ~ ^(.*)/index.(html|php)) { return 301 $1/$is_args$args; }
К сожалению тут достойной замене if нет. Но данная строчка работает не создавая проблем.
Пример минималистичной конфигурации
server {
listen 80;
server_name site.ru;
root /var/www/site.ru/;
index index.php;
location ~ \.php$ {
include /etc/nginx/fastcgi_params;
fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_intercept_errors on;
}
if ($request_uri ~ ^(.*)/index.(html|php)) { return 301 $1/$is_args$args; }
location / { try_files $uri $uri/ /bitrix/urlrewrite.php$is_args$args; }
location ~* @.*\.html$ { internal; }
}
Хочу подчеркнуть что это именно минималистичная конфигурация без правил для статики, сжатия, и я там прикрыл только файлы композитного кэша от прямого доступа. Конфигурация которая прикрывает определённые места от прямого доступа через nginx довольно индивидуальна. У меня есть вот такой набор который может кому-то подойти. Но использовать нужно аккуратно с осознанием дела. Учитите что внесение данных локейшенов в свою конфигурацию может привести к неработоспособности сайта или части его функций.
Фрагмент конфига закрывающий доступ к файлам которые должны быть доступны только при обращении из PHP
location ~ \.php$ {
location ~* /\.\./ { internal; }
location ~ /\.[^/]+$ { internal; }
location ~* ^/upload/1c_[^/]+/ { internal; }
location ~* ^/(bitrix/(cache|images|tmp)|upload)/ { internal; }
location ~* ^/bitrix/(footer|header|license_key)\.php$ { internal; }
location ~* ^/(bitrix|local)/components/(.*)/(.*)/(class|component)\.php$ { internal; }
location ~* ^/(bitrix|local)/(backup|blocks|bx_cloud_upload|local_cache|module|modules|managed_cache|php_interface|public|stack_cache)/ { internal; }
include /etc/nginx/fastcgi_params;
fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_intercept_errors on;
}
location ~* \.(hg|svn|git|bzr)$ { internal; }
location ~* /\.\./ { internal; }
location ~* @.*\.html$ { internal; }
location / {
location ~* ^/(bitrix|local)/(backup|blocks|bx_cloud_upload|local_cache|module|modules|managed_cache|php_interface|public|services|stack_cache)/ { internal; }
location ~ /\.[^/]+$ { internal; }
location ~* ^/upload/1c_[^/]+/ { internal; }
try_files $uri $uri/ /bitrix/urlrewrite.php$is_args$args;
}
Ну и конечно пример location для статических файлов
location ~* \.(jpg|jpeg|png|tiff|gif|webp|xml|html|yml|ogg|ogv|svg|svgz|eot|otf|woff|woff2|mp4|ttf|rss|atom|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|rtf|pdf|txt|js|css|bmp|pnm|pbm|ppm)$ {
access_log off;
expires 97d;
}
Теперь перейдём к конфигу для работы композита с отдачей файлов кэша через nginx. Первым делом необходимо определить можно ли отдавать данному запросу композитный кэш или его нужно отправить на обработку через php. Для этого в Nginx в секции http добавим несколько map, а так же несколько директив:
modern_browser_value "modern";
modern_browser msie 10.0;
modern_browser unlisted;
map "$cookie_BITRIX_SM_LOGIN:$cookie_BITRIX_SM_UIDH:$cookie_BITRIX_SM_CC" $storedAuth {
default "";
"~*:*:Y" "";
"~*:*:*" 1;
"~*:*:" 1;
}
map "$request_method:$http_bx_action_type:$cookie_BITRIX_SM_NCC:$http_x_forwarded_scheme:$modern_browser:$storedAuth" $usecache {
default "1";
"~GET:::*https*" "1";
"~GET:::*:*:" "";
}
Далее уже непосредственно в секции server прописываем
set $i "index@";
location / { try_files /bitrix/html_pages/$host$uri$i${args}.html /bitrix/html_pages/$host$uri$i${args}=.html /bitrix/html_pages/$host$uri/$i${args}.html$usecache /bitrix/html_pages/$host$uri/$i${args}=.html$usecache $uri $uri/ /bitrix/urlrewrite.php$is_args$args; }
Ну и для понимания как примерно будет выглядеть минимальная конфигурация секции server
Пример минималистичной конфигурации с отдачей файлового композитного кэша через nginx
server {
listen 80;
server_name site.ru;
root /var/www/site.ru/;
index index.php;
location ~ \.php$ {
include /etc/nginx/fastcgi_params;
fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_intercept_errors on;
}
if ($request_uri ~ ^(.*)/index.(html|php)) { return 301 $1/$is_args$args; }
set $i "index@";
location / { try_files /bitrix/html_pages/$host$uri$i${args}.html /bitrix/html_pages/$host$uri$i${args}=.html /bitrix/html_pages/$host$uri/$i${args}.html$usecache /bitrix/html_pages/$host$uri/$i${args}=.html$usecache $uri $uri/ /bitrix/urlrewrite.php$is_args$args; }
location ~* @.*\.html$ { internal; }
}
Буду рад вопросам и предложениям по поводу данного конфига, а так же за радость посмотрю Ваши наработки.
Комментарии (5)
mvs
04.02.2019 13:29Не нужно тащить
fastcgi_index index.php
иfastcgi_intercept_errors on
в location'ы, достаточно указать на уровнеserver
.
internal
в большинстве location'ов лучше заменить наdeny all
.castomi Автор
04.02.2019 13:32Собственно это образец. И я его взял с дефолтного локейшена php в Debian. Суть моего подхода излагается выше и кратко, всего одним локейшеном.
inkvizitor68sl
> if ($request_uri ~ ^(.*)/index.(html|php)) { return 301 $1/$is_args$args; }
Почему бы этот if не убрать, попробовав завести соответствующий location?
castomi Автор
Ну хотя бы потому что такой if нельзя заменить локейшеном. Цитирую документацию nginx
Если провернуть тоже самое с локейшеном, то после редиректа запрос снова будет попадать в этот же локейшен и зациклится. Что вызовет ошибку 500.
Попробую наглядно…
запрашиваем /index.php
В обоих случаях и с if и location произойдёт редирект на /
Теперь запрос в / и $request_uri тут равно /, а значит редиректа не будет, в случае с локейшеном у нас отрабатывает директива index и происходит внутреннее перенаправление на index.php и снова идёт запрос на обработку в location, а там редирект)… и так до бесконечности)
Если вдруг Вы нашли способ избавиться от такого if и при этом не сломать работу сайта, поделитесь) Буду признателен. Уверен что не только я.
castomi Автор
Решил всё таки заморочиться и сделать без if. Вот что у меня получилось
Пока применил у себя на дев-сайте. Страшно сразу выбрасывать на прод, помучаю сначала.
Позже добавлю в статью если нормально всё работать будет.
P.S. Немного поправил от первоначального состояния. Пересмотрите те кто смотрел первоначальный вариант комментария. Оттестирую этот вариант у себя и если всё хорошо. допишу его в статью.