如何在Nginx反向代理背后服务Vite开发服务器

p5cysglq  于 2023-05-16  发布在  Nginx
关注(0)|答案(2)|浏览(410)

我正在使用turborepo开发一个Typescriptmonorepo,它包含多个微服务(nextjsexpressjscreate-react-app)。这些微服务中的每一个在其自己的PORT中被服务。为了使开发体验更加流畅,我们决定添加一个Nginx服务器(在docker映像中),它将收集每个微服务的所有端口,并将它们全部保留在一个PORT下。
当我试图添加一个Vite react app并将其放在同一个Nginx服务器后面时,它不起作用,因为它试图访问我本地机器中的node_modules中的文件。
有人有变通办法吗?
下面是我的配置示例:
Nginx配置文件:

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;

}

我的邀请会议

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的错误:

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" "-"
tvokkenx

tvokkenx1#

我假设你已经将Nginx的容器端口80暴露给docker主机端口3000,这就是为什么对代理的请求来自localhost:3000。因此对localhost:3000的请求是代理请求。
很可能你的配置文件没有被Nginx接收,这就是为什么它没有检测到反向代理配置,并试图从它的静态内容目录中读取文件。
如果它检测到代理配置,并且由于某种原因目标应用程序关闭或无法访问,您将看到如下所示的502错误,而不是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" "-"

你可以通过在杀死你的react应用程序后访问代理URL来测试这一点,如果Nginx仍然记录404而不是502,它还没有检测到代理设置。
另外,location context path必须以正斜杠结尾才能正常工作,如下所示

location /foo/ {
    proxy_pass http://Lan-IP-Of-Docker-Host:8080/;
}

另外,我不确定host.docker.internal设置为什么,如果你在localhost上运行container,那么检查你的hosts文件是否有一个由docker为host.docker.internalMap到127.0.0.1的条目
Windows 10主机文件:C:\Windows\System32\drivers\etc\hosts
Linux主机文件:/etc/hosts
如果设置为127.0.0.1,则代理将无法正确转发请求,因为它将解析到容器本身内部的环回地址。您可以通过将host.docker.internal主机名替换为Docker主机的LAN IP地址来初始测试此配置。对我来说,它是我的本地LAN地址,如10.0.1.x
最后,我为Nginx创建了一个简单的Dockerfile,并通过修改default.conf文件来测试代理,请参见下面的代码。尝试使用此配置运行代理,看看是否有效

多克菲

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和stop命令

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
vcirk6k6

vcirk6k62#

乍一看,你试图部署的react应用程序似乎没有正确地进行dockerized。即使你只是想转发开发端口,你仍然需要dockerfile来完成设置react应用程序的所有必要步骤,比如'npm install'或'yarn install'等。如果这一切都很清楚,解决这个问题的一个聪明的解决方案是在nginx容器内创建一个卷,并在容器外的相同路径上为它提供所需的文件,如果在docker compose文件中:

volume:
    -  react_app/node_modules : /etc/nginx/html/dashboard/node_modules

相关问题