Nginx config to serve JavaScript application from different locations

rgov asked:

I have a JavaScript-based web application to deploy. It ships as a JavaScript bundle (produced by webpack), an index.html file that loads this bundle, and some other static resource files, like images. I place all these files in /usr/src/app/dist.

The intention is that for a given request URL, nginx looks for and serves a static resource if available, otherwise it returns the index.html file so that the JavaScript application can handle the URL.

For example, if the base URL for the application is /my-app/, it should be that:

  • /my_app/logo.png serves /usr/src/app/dist/logo.png
  • /my_app/thing/1 (no such file) serves /usr/src/app/dist/index.html

Or if the base URL is just /, then:

  • /logo.png serves /usr/src/app/dist/logo.png
  • /thing/1 (no such file) serves /usr/src/app/dist/index.html

So far it seems simple. I have a template nginx config that looks like this. At startup, %ROOT_PATH% is substituted with the base URL.

    location %ROOT_PATH% {
        alias /usr/src/app/dist;
        try_files $uri $uri/ %ROOT_PATH%/index.html;

However, I am struggling to get a simple way to do this substitution that works for both base path examples given, /my_app/ and /.

For example, in the location directive, it seems that the path must not end with a /, unless it is exactly the string /. So I can’t just strip the final / from %ROOT_PATH%.

If I don’t strip a lone /, then %ROOT_PATH%/index.html becomes //index.html and nginx does not seem to like that either.

What is the best way to make this work? (I’m happy to use other types of built-in variable substitution, also, but it seems like there are shortcomings in where you are permitted to use nginx config variables.)

My answer:

You should be using a trailing slash, and it must appear in both the location and in the alias.

location /my_app/ {
    alias /usr/src/app/dist/;
    try_files $uri $uri/ /my_app/index.html

In the final URL, the location will be directly substituted with the alias when looking for a file in the filesystem. This will result in /usr/src/app/dist/index.html being loaded from storage.

View the full question and any other answers on Server Fault.

Creative Commons License
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.