skip to Main Content

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!

2

Answers


  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.

    Login or Signup to reply.
  2. 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.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search