0

I have an nginx server proxying my express application (which renders ejs files to html), and in trying to load static css/image files it throws a 404 from nginx. This works locally (where I don't have nginx).

<!-- This is the relevant part of head of my index.ejs file -->
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" type="text/css" href="/style.css">
    <title>Document</title>
</head>

<!-- Additionally, I want to load an image later: -->
<img src="logo.png" class="img-fluid rounded" alt="Image failed to load">
// this is where the directory is registered to be static
app.use(express.static(join(__dirname, "public")));

Below is my file tree structure

public/
    style.css
    logo.png
views/
    index.ejs

index.js

The relevant part of the Nginx config:

server {
  listen                               :443 ssl http2;
  listen                               [::]:443 ssl http2;
  server_name                          cygrind.xyz;

  # . files
  location ~ /\.(?!well-known) {
    deny all;
  }

  # logging
  access_log /var/log/nginx/cygrind.xyz.access.log;
  error_log  /var/log/nginx/cygrind.xyz.error.log warn;

  # index.php
  index      index.php;

  # reverse proxy
  location / {
    proxy_pass                         http://The IP was here:8080;
    proxy_http_version                 1.1;
    proxy_cache_bypass                 $http_upgrade;

    # Proxy headers
    proxy_set_header Upgrade           $http_upgrade;
    proxy_set_header Connection        "upgrade";
    proxy_set_header Host              $host;
    proxy_set_header X-Real-IP         $remote_addr;
    proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Forwarded-Host  $host;
    proxy_set_header X-Forwarded-Port  $server_port;

    # Proxy timeouts
    proxy_connect_timeout              60s;
    proxy_send_timeout                 60s;
    proxy_read_timeout                 60s;
  }

  # favicon.ico
  location = /favicon.ico {
    log_not_found off;
    access_log    off;
  }

  # robots.txt
  location = /robots.txt {
    log_not_found off;
    access_log    off;
  }

  # assets, media
  location ~* \.(?:css(\.map)?|js(\.map)?|jpe?g|png|gif|ico|cur|heic|webp|tiff?|mp3|m4a|aac|ogg|midi?|wav|mp4|mov|webm|mpe?g|avi|ogv|flv|wmv)$ {
    expires    7d;
    access_log off;
  }

  # svg, fonts
  location ~* \.(?:svgz?|ttf|ttc|otf|eot|woff2?)$ {
    add_header Access-Control-Allow-Origin "*";
    expires    7d;
    access_log off;
  }
}

The full nginx config file can be found here (please ignore any syntax errors regarding curly braces)

You can find the site here to view the dev console if need be

Thanks in advance!

Zac Anger
  • 6,983
  • 2
  • 15
  • 42
diceGD
  • 125
  • 1
  • 1
  • 4
  • Can you please post the Nginx config? That would seem to be where the issue is, if assets are loading just fine when you hit the server without Nginx. – Zac Anger Jan 16 '21 at 19:58
  • Yes, [here](https://pastebin.pl/view/2423537a) it is – diceGD Jan 16 '21 at 20:38
  • I get a timeout trying to hit that domain... can you post it in an edit in your question instead? – Zac Anger Jan 16 '21 at 20:48
  • Very sorry about that, it seems that the site must have just gone down. Anyway, I've edited the question with a working link now – diceGD Jan 16 '21 at 20:51
  • Thanks, I copied just the part that's relevant to your issue into the question since it's a pretty long config – Zac Anger Jan 16 '21 at 21:27

2 Answers2

0

Your issue is that you have location blocks for various assets (css, favicon, etc.) to turn off logging, but they don't do anything else, the request just ends there, so Nginx returns a 404. You can see that it's not even hitting Express by looking for the x-powered-by header (from your Express app, it's coming back as Express; from the styles, favicon, etc. routes, that response header isn't there).

Location blocks don't get combined. (See the section "When Does Location Block Evaluation Jump to Other Locations?" here for situations exceptions.)

For each of your more specific location blocks, you'll need to add the same proxy-related directives. You could also nest them under the location / which might cut down in the copy-pasting a little bit, but request handlers aren't inherited from parent location blocks, so you will still have some duplication there.

Zac Anger
  • 6,983
  • 2
  • 15
  • 42
-1

Make sure you have this command: app.use(express.static('public')); Also, make sure that your view engine is set properly in your main express file. Express will look in the views folder that should be set at the root level of your project. I would assume for your question it has to be with Nginx config file. May I ask why are you using nginx? for production deploy for simple nodejs apps, I use PM2 for running the app and Docker for containerization.

augdog97
  • 257
  • 5
  • 17
  • The question shows that `express.static` is being used correctly, and the site renders fine loads so the view engine is working. – Zac Anger Jan 16 '21 at 19:59
  • I'm using nginx because having a signed SSL cert at both the host and cloudflare is a lot more secure than just securing traffic between cf and the browser. Regarding the nginx config, I'm not sure what's wrong but I'm assuming it's to do with that because, as I mentioned, it works locally where there is no nginx. As a sidenote, there's no root directory for static files in the config file. Should there be one? If so, should I make it point to the static directory on the nodejs app? – diceGD Jan 16 '21 at 20:37
  • I would assume yes, but as I said I'm not super familiar with nginx. I did find a couple of resources that may be able to help. https://stackoverflow.com/questions/12806893/use-nginx-to-serve-static-files-from-subdirectories-of-a-given-directory https://docs.nginx.com/nginx/admin-guide/web-server/serving-static-content/ – augdog97 Jan 16 '21 at 22:33