How to handle relative urls correctly with a nginx reverse proxy
The problem is basically that using a proxy_pass
directive won't rewrite HTML code and therefor relative URL's to for instance a img src="/assets/image.png"
won't magically change to img src="/bbb/assets/image.png"
.
I wrote about potential strategies to address that in Apache httpd here and similar solutions are possible for nginx as well:
-
If you have control over
example.com
and the how the application/content is deployed there, deploy in the same base URI you want to use on example.net for the reverse proxy
--> deploy your code inexample.com/bbb
and then yourproxy_pass
will become quite an easy as /assets/image.png will have been moved to /bbb/assets/image.png:location /bbb/ { proxy_pass http://example.com/bbb/;
If you have control over
example.com
and the how the application/content is deployed:
change to relative paths, i.e. rather thanimg src="/assets/image.png"
refer toimg src="./assets/image.png"
from a pageexample.com/index.html
and toimg src="../../assets/image.png"
from a pageexample.com/some/path/index.html
-
Maybe you're lucky and example.com only uses a few URI paths in the root and non of those are used by example.net, then simply reverse proxy every necessary subdirectory:
location /bbb/ { proxy_pass http://example.com/; } location /assets/ { proxy_pass http://example.com/assets/; } location /styles/ { proxy_pass http://example.com/styles/;
-
give up using a example.com as subdirectory on example.net and instead host it on a subdomain of example.net:
server { server_name bbb.example.net location / { proxy_pass http://example.com/; } }
-
rewrite the (HTML) content by enabling the nginx ngx_http_sub_module. That will also allow you to rewrite absolute URL's with something similar to:
location /bbb/ { sub_filter 'src="/assets/' 'src="/bbb/assets/'; sub_filter 'src="http://example.com/js/' 'src="http://www.example.net/bbb/js/' ; sub_filter_once off; proxy_pass http://example.com/; }
Related videos on Youtube
Comments
-
a.barbieri almost 2 years
Sure I'm not the first one that tried to serve a domain
example.com
from aexample.net/bbb
, but I haven't found a solution yet.My NGINX configuration follows the guidelines and looks something like this:
server { listen 80; server_name example.net; root /path/to/aaa; location /bbb/ { proxy_pass http://example.com/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } location / { try_files $uri $uri/ /index.html; } location ~ \.(svg|ttf|js|css|svgz|eot|otf|woff|jpg|jpeg|gif|png|ico)$ { access_log off; log_not_found off; expires max; } }
I can manage to render the root of
example.com
inexample.net/bbb
but:ISSUE 1
example.net/bbb/some/path
doesn't work as expected and theindex.html
ofexample.net
is rendered.ISSUE 2
Any asset in
example.com/assets
gives 404 because the browser look forexample.net/assets
. Be great if I could solve this without placing absolute paths everywhere. -
a.barbieri almost 6 yearsI can definitely do the first option. The last one is pretty extreme but it's good to know there's such an alternative.
-
Sammy over 4 yearsExcellent explanation of the implementation options. I've been looking for a breakdown like this for quite some time, happy I finally found it. Thank you.