10

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;
    }

}
1
  • So what would be the actual url of when you render 404 page? Commented Feb 17, 2015 at 23:17

2 Answers 2

23

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.
Sign up to request clarification or add additional context in comments.

6 Comments

Hello mohamed, I tried to approach you proposed above, it didn't quite work out, I updated my question and added more details from the nginx conf.. can you please advise?
explain this line try_files $uri$args $uri$args/ $uri/ /index.html @proxy;
its inspired from this post gist.github.com/cjus/b46a243ba610661a7efb because angularjs passes $uri and $args to index.html in order to render, I tried couple approaches from different manuals and this only one that worked, others worked too. but had problems when refreshing the page
I tried this approach too andredublin.github.io/blog/2014/08/18/… it works when you open the root / url and then when click on links i navigates correctly.. but when you click refresh it gives 404, thats they i had to change
I personally didn't try angular before, so I don't know what should come before what
|
-3

Try this Mo:

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;
    error_page 404 = @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;
    }
}

location @404 {
    proxy_pass http://app_root;
}

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

}

1 Comment

Nginx will throw error if you use same route multiple times

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.