Eu tenho um aplicativo da web em execução http://example.com/
e quero "montar" outro aplicativo em um servidor separado no http://example.com/en
. Servidores upstream proxy_pass
parecem funcionar, mas com um problema:
upstream luscious {
server lixxxx.members.linode.com:9001;
}
server {
root /var/www/example.com/current/public/;
server_name example.com;
location /en {
proxy_pass http://luscious;
}
}
Ao abrir example.com/en
, meu aplicativo upstream retorna 404 not found /en
. Isso faz sentido, pois o upstream não possui o path /en
.
É proxy_path
a solução certa? Devo reescrever "upstream" para que ele ouça /en
, como caminho raiz? Ou existe uma diretiva que me permite reescrever o caminho passado para o upstream?
Responder1
Esta é provavelmente a maneira mais eficiente de fazer o que você deseja, sem o uso de expressões regulares:
location = /en {
return 302 /en/;
}
location /en/ {
proxy_pass http://luscious/; # note the trailing slash here, it matters!
}
Responder2
Gostaria de abordar uma resposta mais recente baseada em regex que está ganhando popularidade.
location ~ ^/en(/?)(.*)$ { # OOPS!
proxy_pass http://luscious/$2$is_args$args; # OOPS!
}
A solução pode parecer mais bonita à primeira vista, mas está errada por vários motivos.
O regex acima corresponderia a um uri de solicitação
/enjoy
, redirecionando-o para/joy
o upstream. Isso é realmente intencional?Uma solicitação for
/en
não resultará em nenhum redirecionamento, atendendo diretamente a/
partir do upstream (quase como se uma solicitação for/en/
tivesse sido feita, mas não exatamente). Se você usar URIs relativos no upstream da sua página raiz (caso contrário, por que você não teria o/en/
prefixo ali mesmo nos URIs upstream?), por exemplosrc="style.css"
(que pode fazer referência a um idioma específicourl("menu.png")
, por exemplo), então o navegador solicitará que como/style.css
em vez de/en/style.css
. (Ou mesmo se você usar URIs absolutos em todos os lugares, e se alguém fizer referência relativa a um recurso semi-opcional obscuro?) Ops, de repente o site pode não funcionar, mas apenas às vezes ou em casos extremos.De acordo com meuconselho anterior em outra questão já mencionada pela própria resposta do OP, o uso de expressões regulares evita o
proxy_redirect
diretiva de ter o valor padrão dedefault
, diminuindo-ooff
para. Isso significa que se o upstream responderLocation: http://127.0.0.1:8080/en/dir/
quando uma solicitação/en/dir
for feita, então é isso que o cliente verá, o que obviamente não funcionará corretamente. (O que teria sido especialmente irônico para uma/en
solicitação que solicita o uso de regex em primeiro lugar, mas essa implementação específica sofre de outro problema, como já mencionado acima.) Além disso, se você já estiver usando oupstream
diretiva, então pode ficar ainda mais feio se você tentar usar uma personalizada, especialmente se você tiver mais de um servidor upstream - como você tem um servidor separadoproxy_redirect
para cada um deles? Vocêproxy_redirect
também pode usar expressões regulares em , talvez até para corresponder a qualquer host, mas e se você decidir fornecer um redirecionamento entre domínios no futuro?
Para tentar resolver alguns dos pontos acima com um único local baseado em regex, poderíamos fazer o seguinte (observe que proxy_pass
também tivemos que eliminar a referência a um servidor de uma upstream
diretiva baseada em -, para tornar proxy_redirect
mais simples):
location ~ ^/en/?((?<=/).*)?$ {
location = /en { return 302 /en/; }
proxy_pass http://127.0.0.1:8080/$1$is_args$args;
proxy_redirect http://127.0.0.1:8080/ /en/;
}
Então, se você me perguntar, osolução original com os dois locais irmãos de nível superiorainda seria uma ideia melhor do que se enterrar na toca do coelho seguindo a rota regex.
Responder3
Então, eu encontrei oresposta no stackoverflow:
upstream luscious {
server lixxxx.members.linode.com:9001;
}
server {
root /var/www/example.com/current/public/;
server_name example.com;
location ~ ^/en(/?)(.*) {
proxy_pass http://luscious/$2;
}
}
Basicamente: passando um regex para location e passando o backref para o URL proxy_pass.
Responder4
Experimentei a solução aceita acima, mas descobri que ela estava causando redirecionamentos duvidosos para todos os ativos CSS e JS. No final, me inspirei na forma como são feitas as configurações do LinuxServer SWAG Nginx. Você pode encontrá-losaqui. Dê uma olhada pihole.subfolder.conf.sample
.
Como tal, minha solução é assim:
location /en {
return 302 $scheme://$host/en/;
}
location ^~ /en/ {
set $upstream_app lixxxx.members.linode.com;
set $upstream_port 9001;
set $upstream_proto http;
proxy_pass $upstream_proto://$upstream_app:$upstream_port;
rewrite /en(.*) $1 break;
}