Vincent
Vincent

Reputation: 167

Nginx reverse-proxy route returns its index.html for static asset requests (ex. .css files)

I have a docker-compose/ Nginx setup that returns the built (via Webpack) React.js project (dashboard container) on the /dashboard route. Returning the index.html file works.

Somehow all my static asset requests (ex. /dashboard/main.css) also return the /dashboard index.html file. I guess this comes from the fact, that the index.html is set as the default return (in the dashboard nginx.config). Which would mean the server cannot find the files.

According to Docker (I ran an ls during build on the directory used inside the container) they are in the same directory (root /app , see nginx.config for the dashboard container) as the index.html file. I am not sure why it still returns the 404/ default page (index.html) in this case though. Any ideas?

docker-compose.yml

version: '3.7'
services:
  # Proxies requests to internal services
  nginx-server:
    image: nginx:1.17.10
    container_name: nginx-server
    depends_on:
      - dashboard
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
    ports:
      - "80:80"
  # harvest dashboard
  dashboard:
    build:
      context: ./harvest-dashboard/client
      dockerfile: Dockerfile
    image: dashboard
    container_name: dashboard
    depends_on:
      - api-server
    ports:
      - "3000:80"
    restart: always
  api-server:
    build:
      context: ./harvest-dashboard/server
      dockerfile: Dockerfile
    image: api-server
    container_name: api-server
    ports:
      - "8000:8080"
    restart: always

nginx-server (root) nginx.config

user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;

events {
  worker_connections 1024;
}

http {
  server {
    listen 80;
    server_name localhost 127.0.0.1;

    location /dashboard/ {
      proxy_pass            http://dashboard:80;
      proxy_set_header  X-Real-IP  $remote_addr;
      proxy_set_header  Host       $host;
      proxy_redirect off;
      proxy_intercept_errors on;
    }
  }
}

dashboard (container) nginx.config

user  nginx;
worker_processes  1;
error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;

events {
  worker_connections  1024;
}

http {
  include            /etc/nginx/mime.types;
  default_type       application/octet-stream;
  log_format  main   '$remote_addr - $remote_user [$time_local] "$request" '
  '$status $body_bytes_sent "$http_referer" '
  '"$http_user_agent" "$http_x_forwarded_for"';
  access_log         /var/log/nginx/access.log  main;
  sendfile           on;
  keepalive_timeout  65;

  server {
    listen       80;
    server_name  localhost;
    root   /app;

    location / {
      index  index.html;
      try_files $uri $uri/ /index.html;
    }

    location /api { 
      proxy_pass http://api-server:8080;
      proxy_http_version 1.1;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection 'upgrade';
      proxy_set_header Host $host;
      proxy_cache_bypass $http_upgrade;
    }

    error_page   500 502 503 504  /50x.html;

    location = /50x.html {
      root   /usr/share/nginx/html;
    }
  }
}

index.html from the dashboard container

<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport"
        content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <link href="main.css" rel="stylesheet">
</head>

<body>
    <div class="app-container"></div>
    <script type="text/javascript" src="main.js"></script>
    <script type="text/javascript" src="vendor.js"></script>
</body>

</html>

Upvotes: 1

Views: 2563

Answers (1)

Vincent
Vincent

Reputation: 167

For anyone running into the same issue later on. This was the fix:

nginx-server (root) nginx.config

http {
  server {
    ...
    location /dashboard/ {
      proxy_pass            http://dashboard:80/;
      ...
    }
  }
}

You have to add the / at the end for your proxy_pass value ( http://dashboard:80/ ). Then it worked :)

Upvotes: 2

Related Questions