У меня есть особые потребности в прокси Nginx
new.example.com
, и старое приложение, работающее по другому URL old.example.com
/admin
к old.example.com/admin
new.example.com
Чтобы упростить задачу, у меня есть блоки @location, представляющие каждое приложение (но, возможно, это несовместимо с остальными, скажите мне)
location @newapp {
proxy_pass http://new.example.com:8080;
}
location @oldapp {
proxy_pass http://old.example.com:8080;
}
Сейчас, когда мое новое приложение находится в разработке, я бы хотел /admin
URL-адреса для перенаправления на мое старое приложение. Я нашел где-то в Интернете трюк с использованием try_files с файлом maintenance.html
location /admin {
try_files /maintenance.html @oldapp;
}
Теперь все становится еще серьезнее, так как - Моему новому приложению требуется предварительная отрисовка - Моему старому приложению не требуется предварительная отрисовка и используется в качестве запасного варианта, когда требуются мета - На данный момент у меня нет приложения предварительного отрисовки (я установлю / настрою prerenderer. io позже), поэтому я использую свое старое приложение в качестве предварительного отрисовки для движков ботов.
location @prerenderer {
try_files /maintenance.html @oldapp # will later be changes to prerenderer.io
}
# in the core nginx server block
server {
...
set $prerender 0;
# [all bot/img logic that may set prerender to 1][1]
}
Также мне пришлось отредактировать мой @newapp, чтобы принудительно переключиться на @prerenderer
location @newapp {
if ($prerender = 1) {
try_files /maintenance.html @prerenderer;
}
if ($prerender = 0) {
try_files /maintenance.html @newapp;
}
}
Но при этом я получаю несколько ошибок nginx, и я не уверен, что мне разрешено, а что нет.
nginx: [Emerg] директива try_files не разрешена здесь, в
Похоже, что nginx не любит try_files
в if
блок.
Как бы вы написали файл конфигурации nginx?
Мой полный файл конфигурации nginx выглядит так
server {
listen 80;
listen 443 ssl;
server_name www.example.com;
access_log /var/log/nginx/www.example.com.log;
auth_basic "Dev's Area";
auth_basic_user_file /etc/nginx/.htpasswd;
# https://gist.github.com/thoop/8165802
set $prerender 0;
if ($http_user_agent ~* "baiduspider|twitterbot|facebookexternalhit|rogerbot|linkedinbot|embedly|quora link preview|showyoubot|outbrain|pinterest|slackbot|vkShare|W3C_Validator") {
set $prerender 1;
}
if ($args ~ "_escaped_fragment_") {
set $prerender 1;
}
if ($http_user_agent ~ "Prerender") {
set $prerender 0;
}
if ($uri ~* "\.(js|css|xml|less|png|jpg|jpeg|gif|pdf|doc|txt|ico|rss|zip|mp3|rar|exe|wmv|doc|avi|ppt|mpg|mpeg|tif|wav|mov|psd|ai|xls|mp4|m4a|swf|dat|dmg|iso|flv|m4v|torrent|ttf|woff|svg|eot)") {
set $prerender 0;
}
#resolve using Google's DNS server to force DNS resolution and prevent caching of IPs
resolver 8.8.8.8;
# Defaults map to new APP EXCEPT if prerendering needed
location / {
if ($prerender = 1) {
try_files /maintenance.html @prerenderer;
}
if ($prerender = 0) {
try_files /maintenance.html @oldapp;
}
}
# Many Static pages not available => mapped to old app
location ~ /(privacy|faq|about_us|terms|press|legal) {
try_files /maintenance.html @oldapp;
}
# Admin stuff => old app
location /company/admin/ {
try_files /maintenance.html @oldapp;
}
location @prerenderer {
# For now old app, will use prerenderer.io later
try_files /maintenance.html @oldapp
}
location @newapp {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
if ($prerender = 1) {
try_files /maintenance.html @prerenderer;
}
if ($prerender = 0) {
proxy_pass http://new.example.com:8080;
}
}
location @oldapp {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_pass https://old.example.com;
proxy_redirect off;
}
#ssl stuff here
client_max_body_size 4G;
keepalive_timeout 10;
}
Ошибка возникает из-за try_files
не допускается внутри if
блок.
Я бы попробовал реализовать выбор бэкэнда с map
директива:
map $http_user_agent $render {
default $argcheck;
"~* (baiduspider|twitterbot|facebookexternalhit|rogerbot|linkedinbot|embedly|quora link preview|showyoubot|outbrain|pinterest|slackbot|vkShare|W3C_Validator)" old.example.com;
}
map $args $argcheck {
default oldapp;
~_escaped_fragment_ prerender;
}
С этими двумя картами вы получите переменную $render
, который будет содержать oldapp
, когда ни одно из указанных правил не соответствует, или prerender
когда либо пользовательский агент совпадает, либо аргументы запроса содержат определенную строку.
Я не уверен на 100% в этой части, но тогда вы можете использовать переменную следующим образом:
location / {
try_files /maintenance.html @$render;
}
Таким образом вы сможете избежать if
заявления, которые злые.