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" "-"
I'm assuming you have expose Nginx's container port 80 to docker host port 3000, that's why requests to proxy are coming at localhost:3000.Thus request to localhost:3000 are proxied requests.
Most likely your configuration file has not been picked up by the Nginx, that's why it doesn't detect the reverse proxy configuration and tries to read the file from it's static content directory.
If it had detected proxy configuration and for some reason target application is down or cannot be reached, you'll see 502 error like below instead of 404
172.17.0.1 - - [13/May/2023:19:43:13 +0000] "GET /foo/hello HTTP/1.1" 502 497 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" "-"
You can test this by accessing the proxy URL after killing your react app, if Nginx still logs 404 instead of 502, it hasn't detected the proxy settings.
Also, location context path must end with a forward slash to work, like below
location /foo/ {
proxy_pass http://Lan-IP-Of-Docker-Host:8080/;
}
Also, I'm not sure what host.docker.internal is set to, if you're running container on localhost then check if your hosts file has an entry made by docker for host.docker.internal mapped to 127.0.0.1
Windows 10 hosts file: C:\Windows\System32\drivers\etc\hosts
Linux hosts file: /etc/hosts
If it's set to 127.0.0.1, then proxy will not forward request correctly, as it will resolve to the loopback address inside the container itself. You can initially test this configuration by replacing host.docker.internal hostname with LAN IP address of Docker host. For me it's my local LAN address like 10.0.1.x
Finally, I created a simple Dockerfile for Nginx and test the proxy by modifying default.conf file, see the code below. Try running proxy with this configuration to see if this works
Dockerfie
FROM nginx:1.23.4
COPY default.conf /etc/nginx/conf.d/default.conf
default.conf
server {
listen 80;
listen [::]:80;
server_name localhost;
#access_log /var/log/nginx/host.access.log main;
# REVERSE PROXY SETTING, Context path ends with forward slash
location /foo/ {
proxy_pass http://Lan-IP-Of-Docker-Host:8080/;
}
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
Docker build, run and stop commands
docker build -t test-nginx ./
//Container will be removed after its stopped because of --rm
docker run --rm --name test-nginx -p 3000:80 test-nginx
//Stops immediately
docker stop test-nginx -t 0
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With