Reputation: 4950
I have multiple apps running on the Nginx
server:
http://example.com/app1/ctrl/view
http://example.com/app2/ctrl/view
...
I would like to assign these apps DNS like so:
http://app1.example.com
http://app2.example.com
...
For that I've tried the following server block:
server {
listen 80;
server_name app1.example.com;
location / {
proxy_pass http://example.com/app1/$request_uri;
}
}
If a user is not logged in, my app would redirect to URI:
app1/ctrl/user/login?_next=/app/ctrl/view
Essentially $request_uri
becomes (Note doubled app1 instance):
app1/app1/ctrl/user/login?_next=/app/ctrl/view
Is there a convenient way to modify $request_uri
or a better method to get around this problem?
EDIT1
It seems I've solved my problem with the following server block:
server {
listen 80;
server_name app1.example.com;
location / {
set $new_request_uri $request_uri;
if ($request_uri ~ ^/app1/(.+)$) {
set $new_request_uri $1;
}
proxy_pass http://example.com/app1/$new_request_uri;
}
}
If someone knows a better (or proper "Nginx
") way to do this please don't hesitate to post an answer.
EDIT2
Based on the comments I've also tried the following:
server {
listen 80;
server_name app1.example.com;
location / {
proxy_pass http://example.com/app1/;
proxy_redirect /app1/ /;
}
location ~ ^/app1/(.+)$ {
return 301 http://$server_name/$1;
}
}
This one looks better on screen, as it eliminates app1 instance in the $request_uri
part completely, but you must have two location
blocks.
EDIT3
The most efficient way to solve my problem apparently is as shown in this config:
server {
listen 80;
server_name app1.example.com;
location / {
proxy_pass http://example.com/app1/;
proxy_redirect /app1/ /;
}
location /app1/ {
rewrite ^/app1(.+) $1 permanent;
}
}
This is due to the fact, that Nginx
always tries to match the longest prefix
first and then (if ^~
modifier is not present) starts sequentially processing regexes
until the first regex match
is found. Essentially this means that all regexes
are processed on every request, regardless if any of these find a match, therefore it's better to have regexes
inside location
directives.
Upvotes: 15
Views: 54807
Reputation: 14354
You don't need to go complex way. Solution is much simpler
server {
listen 80;
server_name app1.example.com;
location / {
proxy_pass http://app1.example.com/app1/;
}
location /app1/ {
proxy_pass http://app1.example.com/app1/;
# or
# rewrite ^/app1(.+) $1 permanent;
}
}
Nginx will take care of adding /app1/
to request and strip it from Location
header.
See proxy_redirect directive.
Upvotes: 7