NGINX and Angular, custom locations

I have the build of an Angular app located at:

/Users/myName/Documents/myApp/app1/dist

I’d like to serve the app directly from this build. I’ve set up an Nginx server with the following additional configuration:

server {

    listen 4200 ssl;
    server_name mysubdomain.com;

    index index.html;

    location / {
        root /Users/myName/Documents/myApp/app1/dist;
        try_files $uri $uri/ /index.html;
    }

    access_log /opt/homebrew/var/log/nginx/access.log;
       error_log  /opt/homebrew/var/log/nginx/error.log;
}

When I open the following URL, everything works correctly and I can see the expected page:

https://mysubdomain.com:4200/login

Now, I’d like to change the configuration so that the app is served under a suffix (e.g. mysubdomain.com:4200/app1/login), while keeping the rest exactly the same; I think, I should change the location but just adding a suffix after “/” there doesn’t work. The idea is to prepare for the future, where I’ll need to differentiate between two sub-apps (app1 and app2).

For several reasons, I cannot change the structure of the current Angular application (e.g. the base href). I only want to differentiate the location in Nginx, without modifying anything else in the app or its configuration.

How can I achieve this?

Thank you very much!

Update

If I try to use the alias, in this way:

server {

    listen 4200 ssl;
    server_name mysubdomain.com;

    index index.html;

    location / {
        alias /Users/myName/Documents/myApp/app1/dist/;
        try_files $uri $uri/ /index.html;
    }

    access_log /opt/homebrew/var/log/nginx/access.log;
       error_log  /opt/homebrew/var/log/nginx/error.log;
}

and if I serve the app by using the same address as before, it still works. But, if I try to change the location and the try_files like suggested in the first comment, the application is not longer able to load anything (in the console, network, I see that main.js, styles.css, polyfills and any other resource are not found).

Just to be fully clear, this is the result in my console just after:

  1. Changing the location from / to /app1/

  2. Changing try_files from try_files $uri $uri/ /index.html; to try_files $uri $uri/ /app1/index.html;

  3. Changing the url from .../login to .../app1/login

Now, I believe that my description is really clear. Thanks again for your help and your time.

JS applications sometimes need a change inside the code to adapt for a new webroot (APP_BASE_HREF in terms of angular). Also, by changing the location you are changing $uri.

Try the following location:

   location /app1 {
        root /Users/myName/Documents/myApp/app1/dist;
        try_files $uri $uri/ /index.html;
    }

And check logs. There are two options: either the application requests for /app1/login and there is no ‘app1’ directory under dist, so index.html is always served. Or the application requests /login (without the app1 prefix) and then there is no location to serve the request.

You will probably have to create a separate directory (like /Users/myName/Documents/apps) and link both applications under it (ln -s /Users/myName/Documents/myApp/app1/dist /Users/myName/Documents/apps/app1) then use /Users/myName/Documents/apps/ as a root.

Thanks for the effort, but not so clear to me. The structure of the file system is …/app1/dist and inside the dist I have the index file.

And, the base href of the Angular app should not be changed, as from the Angular point of view nothing changes and everything is in the “relative“ root. I just added a location, without touching nothing else.

So, the structure is …/app1/dist and inside all the Angular dist with index etc etc. No app1 under dist, but the dist as said is under app1. What location / configuratio can I try, by considering this additional info?

Thanks again for your time and your effort.

It is important to consider what requests application makes. File layout is important but nginx task is to match requests to files, right?

Try moving application to /app1 url. Then look at what requests the browser makes. And then check error.log to see which file nginx tried to find.

Let’s concentrate our effort on a single file that works before the move but fails after. Please, post here a file URL, file path on the disk. We’ll also need nginx configuration for the location and a screenshot of devtools from a browser with a url that the app requests.

Having all that I will be able to help you with nginx configuration (and probably other stuff around it).

Thank you very much for your effort, I appreciate, this problem is really important. I’ll do exactly what you suggested. Just a minute

Ok, the app is entirely moved under …/app1. Under app1, in other words, we have index.html, main.js and so on. Here is the new location

location /app1 {

	        alias /Users/myname/Documents/myapp/app1;
    	    try_files $uri $uri/ /index.html =404;	
        }

And, if I call https://mydomain.com:4200/app1/login (and consider that login is a route of the app, that at the very first beginning of my post, with a location /, worked perfectly), I see in the browser console 404 not found for main.js, styles.scss, polyfills and chunk-MVGP3CFP.js.

That’s all. Thanks again.

PS Please consider the first part of my topic, without that custom location, before, everything worked perfectly.

You can find even more detailed info here

A discussion I opened about it, more detailed, with screenshots, and also with the result of a suggestion from a user that didn’t work.

I suspect you have to set the application root one way or another (through APP_BASE_HREF or ). But on nginx side it’s pretty simple.

If an application requests https://mydomain.com:4200/styles.scss - it is not served by the location /app1, right? So you get 404 because there is nothing to serve. You should click the request in dev tools and on the right it will open a pane with additional information. the full request string (at the top of ‘Headers’ is what you need).

Another option - the application requests https://mydomain.com:4200/app1/styles.scss. Then the location /app1 will be used indeed. Next, try_files will use the directory from alias and remove the part mentioned in location from $uri . So /Users/myname/Documents/myapp/app1/styles.scss will be tried. And served, if it exists.

Does it fail for you? What is the request from access.log? Where is the corresponding file?

Lets do a step backward, please. With this configuration:

server {

	listen 4200 ssl;
	server_name myserver.com;

	location / {
         
	    alias /Users/myuser/Documents/myapp/app1/;
    	try_files $uri $uri/ /index.html =404;	
    }

	access_log /opt/homebrew/var/log/nginx/access.log;
    error_log  /opt/homebrew/var/log/nginx/error.log;
}

with this url

https://myserver.com/login

(login is a route)

and this file system, same as yesterday

/Users/myuser/Documents/myapp/app1/
|-index.html
|-main.js
(etc)

everything works perfectly and this should exclude a lot of problems from our analysis. Now, just a very simple question:

starting from this configuration, how can I simple add a “app1“ after the location (so, from “/“ to “/app1“?

Thanks

HINT: I have the “stomach feeling“ that something should be done in try_files…

Yes, you can simply add /app1 to your location and it should work.

To work out nginx configuration - you can exclude the application from the test. Try it with curl: curl https://myserver.com/app1/main.js should work for you after you change the location.

I would expect that you open application as https://myserver.com/app1/login but it still requests https://myserver.com/main.js.

Maybe my message was not clear enough… I want know how can I do it, as if I simply add that prefix doesn’t work! This was the purpose of the discussion. :frowning:

does it work with curl?

If the application always requests https://myserver.com/main.js you can’t fix it in nginx. You have to tell the application it was moved to another location.

The application request that url if the location is “/“, obviously. And curl (and also open by browser directly the main.js) it works perfectly, as I can see the content of the main file. The purpose is to change that url to something different.

If I change the location to “/app1“ and I try to open directly the main.js from mylocation:myport/myapp/main.js without touching nothing else I can see the content of main.js perfectly. So, is not related to the app, as said.

The problem is sure the configuration of nginx: and, I have the “feeling“ that something should be done at the try_files. If we can be concentrated of that part please… How should I change it, after a change of the location?

If https://myserver.com/app1/main.js gives you the js file then nginx is configured properly.

Can you show me a screenshot showing the application request for /app1/main.js that fails?

If I change only location from / to /app1 and try_files to $uri $uri/ /app1/index.html, by opening

https://mydomain.com:4200/app1/main.js

I can see the content of main.js directly in the browser.

But, if I try to open

https://mydomain.com:4200/app1/login

And /login is an Angular route that before worked perfectly, I see a series of 404:

You cut off the most interesting part. What is the prefix before the main.js? Does it match the location?

Have you seen this doc: Angular ?

No, it doesn’t match. Sorry, I cutted the image due to privacy reason. That path in the console was again without app1, very strange. So in the screenshot was,

https://mydomain.com:4200/main.js

And, as said, base_href didn’t fix the problem, as tried many times. I worked with Angular from 10 years and I know your link; but, as the topic is related to an extra location in nginx (and, as said, without that extra location everything worked), it should be fixed in nginx.

Angular (once again) doesn’t know nothing about the path of the app (I could also have invented another name for my folder): once again, the app would have worked perfectly. The reason is only that suffix on the location.

Please, stay concentrated on the topic without proposing in loop always the same solution. I appreciate your time and your effort, but I have to fix a probelm. If no idea, I prefer that you just say it.

Thanks again.

The base href doc specifically describes your problem. <base href=”/app1” /> is exactly what you are looking for. No amount of nginx configuration will make angular request /app1/main.js.

As already said base_href I already tried, doesn’t work and is not the solution.

PS To be precise, with that setting I see (for any route) a blank page, without error messages in the console, and same for any route (even …/fakeroute instead of login). It was already mentioned in one discussion I linked before.

If I might suggest an alternative approach – running Angular in a Node server should hopefully fix some of these issues, and you can then proxy into the Node server using NGINX. Angular also seems to have gone EoL so I sadly don’t know how much help either us or Angular will be able to provide.