skip to Main Content

I’m working on a Typescript monorepo using turborepo that holds multiple microservices (nextjs, expressjs, create-react-app).
each of these microservices is served in its own PORT.
In order to make the development experience more fluid, we decided to add a Nginx server (in a docker image) that will collect all the ports from each Microservice and reserve them all under one PORT.

When I tried to add a Vite react app and put it behind the same Nginx server, it didn’t work because it is trying to access the files in node_modules in my local machine.

Does anyone have a workaround?

Below is a sample of my configs:

Nginx config file :

upstream imgproxy {
    server imgproxy:3000;
}


server {
    listen 80;

    location / {
        return 301 https://$host:3000$request_uri;
    }
}


server {
    listen 443 ssl;
    client_max_body_size 240M;
    ssl_certificate    cert/localhost3000.crt;
    ssl_certificate_key    cert/localhost3000.key;

    location /api/v1/auth {
          proxy_pass http://host.docker.internal:4001;
    }

    location /dashboard {
          proxy_pass https://host.docker.internal:3001;
    }

    location /api/v1/blogs {
          proxy_pass http://host.docker.internal:4010;
    }

    location / {
          proxy_pass http://host.docker.internal:4200;
    }

    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $host;

    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    include h5bp/tls/policy_balanced.conf;
    # Custom error pages
    include h5bp/errors/custom_errors.conf;

    # Include the basic h5bp config set
    include h5bp/basic.conf;

}

My vite.conf.ts

import { defineConfig, loadEnv } from "vite";
import react from "@vitejs/plugin-react-swc";
import fs from "fs";
import tsconfigPaths from "vite-tsconfig-paths";
// https://vitejs.dev/config/
export default defineConfig(({ mode }) => {
  return {
    base: "/dashboard",
    server: {
      port: 3001,
      https: {
        cert: fs.readFileSync("../../nginx/cert/localhost3000.crt"),
        key: fs.readFileSync("../../nginx/cert/localhost3000.key"),
      },
    },
    plugins: [react(), tsconfigPaths()],
  };
});

Nginx’s errors :

2023/05/05 13:54:02 [error] 33#33: *2 open() "/etc/nginx/html/dashboard/node_modules/.vite/deps/react_jsx-dev-runtime.js" failed (2: No such file or directory), client: 172.20.0.1, server: , request: "GET /dashboard/node_modules/.vite/deps/react_jsx-dev-runtime.js?v=12d55949 HTTP/1.1", host: "localhost:3000", referrer: "https://localhost:3000/dashboard/src/index.tsx"
172.20.0.1 - - [05/May/2023:13:54:02 +0000] "GET /dashboard/node_modules/.vite/deps/react_jsx-dev-runtime.js?v=12d55949 HTTP/1.1" 404 178 "https://localhost:3000/dashboard/src/index.tsx" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36" "-"
172.20.0.1 - - [05/May/2023:13:54:02 +0000] "GET /dashboard/@react-refresh HTTP/1.1" 200 3393 "https://localhost:3000/dashboard" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36" "-"
2023/05/05 13:54:03 [error] 33#33: *2 open() "/etc/nginx/html/dashboard/node_modules/.vite/deps/react.js" failed (2: No such file or directory), client: 172.20.0.1, server: , request: "GET /dashboard/node_modules/.vite/deps/react.js?v=12d55949 HTTP/1.1", host: "localhost:3000", referrer: "https://localhost:3000/dashboard/src/index.tsx"
172.20.0.1 - - [05/May/2023:13:54:03 +0000] "GET /dashboard/node_modules/.vite/deps/react.js?v=12d55949 HTTP/1.1" 404 178 "https://localhost:3000/dashboard/src/index.tsx" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36" "-"
2023/05/05 13:54:03 [error] 35#35: *6 open() "/etc/nginx/html/dashboard/node_modules/.vite/deps/react-redux.js" failed (2: No such file or directory), client: 172.20.0.1, server: , request: "GET /dashboard/node_modules/.vite/deps/react-redux.js?v=12d55949 HTTP/1.1", host: "localhost:3000", referrer: "https://localhost:3000/dashboard/src/index.tsx"
172.20.0.1 - - [05/May/2023:13:54:03 +0000] "GET /dashboard/node_modules/.vite/deps/react-redux.js?v=12d55949 HTTP/1.1" 404 178 "https://localhost:3000/dashboard/src/index.tsx" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36" "-"
172.20.0.1 - - [05/May/2023:13:54:03 +0000] "GET /dashboard/@fs/C:/Users/nader/Documents/devProjects/boilerplate/packages/browser/core-ui/DarkModeProvider/index.tsx HTTP/1.1" 200 2026 "https://localhost:3000/dashboard/src/index.tsx" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36" "-"

2

Answers


  1. It seems like your Nginx server is trying to access files in the node_modules directory on your local machine, which is not what you want. The reason for this is that the Vite server running your React app is serving files from the local node_modules directory. However, since the Nginx server is running in a Docker container, it cannot access these files on your local machine.

    One possible solution to this is to configure Vite to serve the files from the Docker container’s node_modules directory instead of the local directory. To do this, you can set the root option in your Vite configuration file to the Docker container’s working directory, which should be the same as the directory where the node_modules directory is located.

    In your vite.config.ts file:

    import { defineConfig } from "vite";
    import react from "@vitejs/plugin-react-swc";
    import tsconfigPaths from "vite-tsconfig-paths";
    
    export default defineConfig(({ mode }) => {
      return {
        base: "/dashboard",
        root: "/app", // this should be the path to your app in the Docker container
        server: {
          port: 3001,
          https: {
            cert: "/cert/localhost3000.crt",
            key: "/cert/localhost3000.key",
          },
        },
        plugins: [react(), tsconfigPaths()],
      };
    });
    

    Adjust the value of /app directort if your app is located in a different directory.

    Alternatively, you can also try using a Docker volume instead of a bind mount to map your project directory to the container’s file system. This will ensure that the container has its own copy of the project files and dependencies, and will prevent conflicts between your local machine and the container.

    Login or Signup to reply.
  2. It looks like the issue is that Nginx is trying to serve the Vite app’s files from the node_modules directory on your local machine instead of within the Docker container. One possible workaround is to modify your Vite app’s config to use a base URL that Nginx can proxy.

    In your Vite config file, you currently have base: "/dashboard". You can change this to a full URL like base: "https://your-domain.com/dashboard". This tells Vite to serve the app at the /dashboard path under your domain, which is what Nginx is already configured to proxy.

    Next, update your Nginx config file to proxy requests to the new base URL. Replace the following block:

    location /dashboard {
        proxy_pass https://host.docker.internal:3001;
    }
    

    with:

    location /dashboard {
        proxy_pass http://localhost:3001;
        proxy_set_header Host your-domain.com;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
    

    Make sure to replace your-domain.com with your actual domain. This configuration sets up Nginx to proxy requests to the Vite app at http://localhost:3001, and sets the necessary headers to forward the correct host and protocol information.

    Finally, update your Vite app’s config to use the --host and --port flags to start the dev server. Replace the following block:

    server: {
      port: 3001,
      https: {
        cert: fs.readFileSync("../../nginx/cert/localhost3000.crt"),
        key: fs.readFileSync("../../nginx/cert/localhost3000.key"),
      },
    },
    

    with:

    server: {
      // Remove the port configuration
      https: {
        cert: fs.readFileSync("../../nginx/cert/localhost3000.crt"),
        key: fs.readFileSync("../../nginx/cert/localhost3000.key"),
      },
    },
    

    Then, start the Vite app’s dev server with the following command:

    yarn dev --host localhost --port 3001
    

    This starts the Vite dev server on http://localhost:3001, which is the URL that Nginx is configured to proxy. Now, when you visit https://your-domain.com/dashboard in your browser, Nginx should correctly proxy requests to the Vite app’s dev server running in Docker, and the app should be able to find its dependencies in the container’s node_modules directory.

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