Nginx routing to multiple locations with multiple roots in angular ssr build

Viewed 1401

I have my website running and hosted on the server. Let's say my website is http://example.com. It built in angular and I built and deployed the dist folder which contains the code on the server, let's say, at /opt/example_web/dist/browser. Now when I hit the site, it redirects and loads fine.

I have another two builds (can say) running on the same server, one http://example.com/api which is build on Node.js and another angular based http://example.com/admin. API works fine but the problem is coming up with admin. The home page loads but it isn't able to find the styles and javascript files which are located at /opt/example_admin/dist/browser. Error it displays in console is -

2019/01/13 10:04:57 [error] 5474#5474: *6 open() "/opt/example_web/dist/browser/admin/styles.3397081055411503ca7a.css" failed (2: No such file or directory), client: 103.82.102.67, server: edupeeth.com, request: "GET /admin/styles.3397081055411503ca7a.css HTTP/1.1", host: "edupeeth.com", referrer: "https://edupeeth.com/admin"
2019/01/13 10:04:57 [error] 5474#5474: *6 open() "/opt/example_web/dist/browser/admin/runtime.c65c5993662350a7e065.js" failed (2: No such file or directory), client: 103.82.102.67, server: edupeeth.com, request: "GET /admin/runtime.c65c5993662350a7e065.js HTTP/1.1", host: "edupeeth.com", referrer: "https://edupeeth.com/admin"
2019/01/13 10:04:57 [error] 5474#5474: *6 open() "/opt/example_web/dist/browser/admin/polyfills.0e3ee22c9a47318954a0.js" failed (2: No such file or directory), client: 103.82.102.67, server: edupeeth.com, request: "GET /admin/polyfills.0e3ee22c9a47318954a0.js HTTP/1.1", host: "edupeeth.com", referrer: "https://edupeeth.com/admin"
2019/01/13 10:04:57 [error] 5474#5474: *8 open() "/opt/example_web/dist/browser/admin/main.0008150f761fd2143e37.js" failed (2: No such file or directory), client: 103.82.102.67, server: edupeeth.com, request: "GET /admin/main.0008150f761fd2143e37.js HTTP/1.1", host: "edupeeth.com", referrer: "https://edupeeth.com/admin"

I think I am doing something wrong in nginx config. I am copying below my configuration for nginx. Please suggest the mistake I am doing here.

upstream ssr_edu_web {
    server 127.0.0.1:4200;
}

upstream ssr_edu_admin {
    server 127.0.0.1:8081;
}

server {
    listen 443 ssl;

    server_name example.com www.example.com; # <--- Change this part

    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot
      ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

    root /opt/example_web/dist/browser; # <-- Notice where we're point to    

    location / {

        try_files $uri $uri @backend; # <--- This looks for requests (statics i.e js/css/fonts)
                                      # in /ssr/dist/browser folder. If nothing found, calls @backend
    }

    location @backend {
        # NOTE THERE IS NO TRAILING SLASH AT THE END. NO TRAILING SLASH. NO SLASH. NO!
        proxy_pass http://ssr_edu_web; # <--- THIS DOES NOT HAVE A TRAILING '/'
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_http_version 1.1;
        proxy_set_header X-NginX-Proxy true;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_cache_bypass $http_upgrade;
        proxy_redirect off;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

      location /api {
         proxy_pass http://127.0.0.1:8080/api;
         proxy_redirect    off;
         proxy_set_header  Host            $host;
         proxy_set_header  X-Real-IP        $remote_addr;
         proxy_set_header  X-Forwarded-For  $proxy_add_x_forwarded_for;
       }

    location /admin {
        alias /opt/example_admin/dist/browser;
        proxy_pass http://ssr_edu_admin; # <--- THIS DOES NOT HAVE A TRAILING '/'        
       }       

}

  server {
      listen 80;
      server_name example.com;
      return 301 https://$server_name$request_uri?;
  }

Following is index.html -

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>Admin</title>
  <base href="/">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" type="image/x-icon" href="favicon.png">
  <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
  <link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500" rel="stylesheet">
<link rel="stylesheet" href="/admin/styles.3397081055411503ca7a.css"></head>
<body>
  <app-root></app-root>
<script type="text/javascript" src="/admin/runtime.c65c5993662350a7e065.js"></script><script type="text/javascript" src="/admin/polyfills.0e3ee22c9a47318954a0.js"></script><script type="text/javascript" src="/admin/main.0008150f761fd2143e37.js"></script></body>
</html>

If I do a curl after logging in to the server where I hosted my website, I am able to do so on http://127.0.0.1:8081.

2 Answers

I'm not sure this will help, but can you try to split your /admin location block in two?

    location /admin {
        alias /opt/example_admin/dist/browser;
        try_files $uri @admin;
    }
    location @admin {
        proxy_pass http://ssr_edu_admin; # <--- THIS DOES NOT HAVE A TRAILING '/'        
    }       

Also take a look at nginx error.log, it can contain information about paths where nginx looking for your .js and .css files.

please refer to Running Angular2 In Subdirectory

in your case, changes <base href="/"> to <base href="/admin"> and in your nginx configuration, change to following, included partial answer from @ivan-shatsky:

location /admin {
    root /your/admin/app/root/here;
    try_files $uri @admin;
}
location @admin {
    proxy_pass http://ssr_edu_admin; # <--- THIS DOES NOT HAVE A TRAILING '/'        
}   
Related