Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

nginx serve from static if not found try reverse proxy

Tags:

nginx

I have an application which is developed using angularjs and the entire application loads when the dist/ folder is accessed.

What am trying todo is, that when page is not found on angularjs, to try on a reverse proxy, I tried to do the below setup but nginx does not allow setting up the same location twice in single block

server {
    listen 80;
    server_name example.com;
    keepalive_timeout 60;
    client_max_body_size 10M;
    root /var/lib/www/dist;
    charset utf-8;

    location / {
        expires -1;
        add_header Pragma "no-cache";
        add_header Cache-Control "no-store, no-cache, must-revalidate, post-check=0, pre-check=0";
        root /var/lib/www/dist;
        try_files $uri $uri/ /index.html =404;
    }

    location / {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_redirect off;
        proxy_buffering off;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        if (!-f $request_filename) {
            proxy_pass http://app_root;
            break;
        }
    }

    error_page 500 502 503 504 /500.html;
    location = /500.html {
        root /var/lib/app/etc/templates;
    }

}

so basically, if the URL 404'ed on angularjs I want it to try and pass it to proxy_pass http://app_root; any one can advise on how to achieve this setup?

Thanks,

UPDATE

So am trying approach proposed by "Mohammad AbuShady", and updated my nginx settings to following, but still not working, instead it tries to find the page in the AngularJS app and not move to the @proxy up_stream setup

upstream app_root {
    server unix:/tmp/app_root.sock fail_timeout=0;
}

server {
    listen 80;
    server_name example.com;
    keepalive_timeout 60;
    client_max_body_size 10M;
    root /var/lib/www/dist;
    charset utf-8;

    location / {
        expires -1;
        add_header Pragma "no-cache";
        add_header Cache-Control "no-store, no-cache, must-revalidate, post-check=0, pre-check=0";
        root /var/lib/www/dist;
        try_files $uri$args $uri$args/ $uri/ /index.html @proxy;
    }

    location @proxy {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_redirect off;
        proxy_buffering off;
        if (!-f $request_filename) {
            proxy_pass http://app_root;
            break;
        }
    }

    error_page 500 502 503 504 /500.html;
    location = /500.html {
        root /var/lib/app/etc/templates;
    }

}
like image 904
Mo J. Mughrabi Avatar asked Feb 17 '15 22:02

Mo J. Mughrabi


People also ask

How does Nginx detect reverse proxy?

To see Nginx function as a reverse proxy, simply restart the server to load the new configuration. When the server comes online, try to access the backend server through the Nginx reverse proxy. In this example, we can access the Tomcat server running on port 8080 through Nginx.

Is Nginx reverse proxy safe?

nginx is built to be stable and secure, but it will only be as secure as the user who configures it. Once nginx is built and installed, configuring the server to be as minimal as possible is important.

What is Try_files in Nginx?

The try_files directive exists for an amazing reason: It tries files in a specific order. NGINX can first try to serve the static content, and if it can't, it moves on. This means PHP doesn't get involved at all.

Is Nginx forward or reverse proxy?

Nginx is an open source web server that can also serve as a reverse proxy. Apart from being used to host websites, it's also one of the most widely used reverse proxy and load balancing solutions.


1 Answers

You're over thinking it, a single location can handle it and then give it a fallback

location / {
  # omitted extra settings
  # check notes below
  try_files $uri @proxy;
}

location @proxy {
  # omitted proxy settings
  proxy_pass http://app_root;
}

Notes:

  1. No need for a second root inside location, it's already defined in server block
  2. I've removed $uri/ because you don't have index in your server.
  3. I also removed /index.html, if you do want to use it then you might want to define it as index in the server block and put the $uri/ back

    server {
      index index.html;
      location / {
        try_files $uri $uri/ @proxy;
      }
    }
    
  4. I have no idea where app_root is, but I'm assuming it's an upstream defined somewhere else.
like image 69
Mohammad AbuShady Avatar answered Oct 04 '22 23:10

Mohammad AbuShady