25

My current nginx config is this:

upstream nodejs {
    server 127.0.0.1:3000;
}

server {
    listen 8080;
    server_name localhost;
    root ~/workspace/test/app;
    index index.html;

    location / {
        proxy_pass http://nodejs;
        proxy_set_header Host $host ; 
        proxy_set_header X-Real-IP $remote_addr; 
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

I'm very very new to nginx, but at the very least I know that nginx is better than node/express at serving static files. How can I configure the server so that nginx serves the static files?

m0meni
  • 16,006
  • 16
  • 82
  • 141
  • If you're going to be so condescending could you at least link it and then I'll delete my question. I've looked and I've had trouble finding it. – m0meni Apr 01 '15 at 05:44

2 Answers2

28

I solved it using this new configuration:

upstream nodejs {
    server localhost:3000;
}

server {
    listen 8080;
    server_name localhost;
    root ~/workspace/test/app;

    location / {
        try_files $uri @nodejs;
    }

    location @nodejs {
        proxy_redirect off;
        proxy_http_version 1.1;
        proxy_pass http://nodejs;
        proxy_set_header Host $host ; 
        proxy_set_header X-Real-IP $remote_addr; 
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

Thanks to the following Stack Overflow post:


How to serve all existing static files directly with NGINX, but proxy the rest to a backend server.

m0meni
  • 16,006
  • 16
  • 82
  • 141
  • `try_files $uri /$uri @nodejs;` should be `try_files $uri $uri/ @nodejs;` – Alexey Ten Apr 02 '15 at 13:05
  • This config means that first the nginx tries to serve static file, if it cannot find, then it redirects to nodejs server? – Santosh May 21 '16 at 07:10
  • @HS yeah that's exactly what it means. – m0meni Jun 15 '16 at 12:59
  • @garkin agreed, but I wanted to know how to do it without an explicit `/public/` folder at the time. I get that it's probably exploitable that a file can be served from pretty much any path that leads to a file. – m0meni Nov 23 '16 at 05:44
  • This config smells bad. You should not proxy each request to file system before backend. Static files should be served from a determined separate url. Local folder with a shared content should be obviously named, like PUBLIC. (sorry, for ninja edit) – garkin Nov 23 '16 at 05:47
  • 1
    This was doing an error 403 on the root url. Fix: change to `try_files $uri @nodejs;` so that nginx only tries to serve files, not directories. – François Romain May 21 '17 at 21:03
23

You'll probably want another location block within your server for the static files.

location /static {
  alias /path/to/static/files;
}

This uses the alias directive. Then you can hit files at localhost:8080/static/some_file.css

P.S. You don't need the root or index that you have set currently. (root is similar to alias with a slight difference in usage)

Community
  • 1
  • 1
Sanketh Katta
  • 5,961
  • 2
  • 29
  • 30
  • what i want is to have stuff out of /static be served up even when `static` is not in the URI ... – dcsan Aug 27 '19 at 22:23
  • @dscan then you can set your location block to `location / {` and set the alias to point to your static files – Sanketh Katta Aug 28 '19 at 01:55
  • but a `location /` would surly interfere with the `try {} ` block and routing to the app server itself? Are request paths tested in order from top to bottom? cos the app server will accept anything and 404 if there's no route inside the app. – dcsan Aug 28 '19 at 10:20