如何配置 ngnix、vite 和 laravel 通过反向代理与 HMR 一起使用?

Reu*_*ben 2 nginx laravel docker hot-module-replacement vite

我刚刚接触 Laravel/Vue3,所以我正在学习基础知识。不过,我有一个现有的 Docker 生态系统,用于本地开发,还有一个 nginx 反向代理,用于将我的许多项目分开。

我在使 HMR 工作时遇到困难,更难以找到有关如何配置 Vite 和 Nginx 的适当文档,以便我可以在 nginx 中拥有单个 HTTPS 入口点并代理回 Laravel 和 Vite。

该构建基于https://github.com/laravel-presets/inertia/tree/boilerplate

为了完整起见,这是 package.json,以防万一它发生变化:

{
    "private": true,
    "scripts": {
        "dev": "vite",
        "build": "vite build"
    },
    "devDependencies": {
        "@vitejs/plugin-vue": "^2.3.1",
        "@vue/compiler-sfc": "^3.2.33",
        "autoprefixer": "^10.4.5",
        "postcss": "^8.4.12",
        "tailwindcss": "^3.0.24",
        "vite": "^2.9.5",
        "vite-plugin-laravel": "^0.2.0-beta.10"
    },
    "dependencies": {
        "vue": "^3.2.31",
        "@inertiajs/inertia": "^0.11.0",
        "@inertiajs/inertia-vue3": "^0.6.0"
    }
}
Run Code Online (Sandbox Code Playgroud)

为了简单起见,我将尝试让它仅在 HTTP 下工作,稍后再处理 HTTPS。

因为我在容器中运行开发服务器,所以我0.0.0.0在 vite.config.ts 中将 server.host 设置为,将 server.hmr.clientPort 设置为 80。这将允许从容器外部连接到开发服务器,并希望实现公共端口是 80,而不是默认的 3000。

我尝试将 DEV_SERVER_URL 设置为与 APP_URL 相同,以便来自公共站点的所有流量都到达同一位置。但我不确定 nginx 方面应该是什么样子。

我还尝试将 DEV_SERVER_URL 设置为http://0.0.0.0:3000/,以便我可以看到正在尝试生成的流量。这几乎可行,但完全错误。当涉及到 ws://0.0.0.0/ 通信时它会失败,并且当涉及到 HTTPS 时它不合适。

我注意到对 的调用/__vite_plugin,我假设这是通常在 中设置的默认 ping_url config/vite.php

寻找有关哪些 nginx 位置应转发到 Laravel 端口、哪些位置应转发到 Vite 端口以及应该是什么样子的指南,以便也能满足 Web 套接字通信的需求。

我看到有人讨论 Vite 3 可能会让这个设置变得更容易,但我想讨论一下现在可用的内容。

Reu*_*ben 5

答案似乎在于知道哪些目录要代理到 Vite,并能够隔离用于 HMR 的 Web 套接字。

为此,您需要执行以下操作:

  • 确保您的.env APP_URLDEV_SERVER_URL匹配。
  • 在您的 中vite.config.ts,确保为server.host“0.0.0.0”,以便可以接受来自容器外部的连接。
  • 在您vite.config.ts指定一个base例如,'/app/'以便在您运行时可以隔离所有 HMR 流量并将其重定向到 Vite 服务器npm run dev。如果该路径可能与 Laravel 或 Vite 应用程序中的真实路径冲突,您可能希望使用其他路径,例如/_dev//_vite'
  • 在您config/vite.php设置一个值ping_urlas http://localhost:3000。这允许 Laravel 在本地 ping Vite 服务器,以便不使用清单而使用 Vite 服务器。这还假设ping_before_using_manifest设置为true
  • 最后,您需要配置 nginx 代理,以便将多个位置专门代理到 Vite 服务器,其余位置则代理到 Laravel 服务器。

我不是 Nginx 专家,所以可能有一种方法可以简洁地声明以下内容。

Nginx 服务器条目示例

# Some standard proxy variables 
map $http_x_forwarded_proto $proxy_x_forwarded_proto {
  default $http_x_forwarded_proto;
  ''      $scheme;
}

map $http_x_forwarded_port $proxy_x_forwarded_port {
  default $http_x_forwarded_port;
  ''      $server_port;
}

map $http_upgrade $proxy_connection {
  default upgrade;
  '' close;
}

map $scheme $proxy_x_forwarded_ssl {
  default off;
  https off;
}

server {
  listen *:80;
  server vite-inertia-vue-app.test;
  
  /* abridged version that does not include gzip_types, resolver, *_log and other headers */

  location ^~ /resources/ {
    proxy_pass            http://198.18.0.1:3000;
    include               /etc/nginx/vite-inertia-vue-app.test.include;
  }

  location ^~ /@vite {
    proxy_pass            http://198.18.0.1:3000;
    include               /etc/nginx/vite-inertia-vue-app.test.include;
  }

  location ^~ /app/ {
    proxy_pass            http://198.18.0.1:3000;
    include               /etc/nginx/vite-inertia-vue-app.test.include;
  }

  location / {
    proxy_pass            http://198.18.0.1:8082;
    include               /etc/nginx/vite-inertia-vue-app.test.include;
  }     
}  
Run Code Online (Sandbox Code Playgroud)

vite-inertia-vue-app.test.include包括常见的代理设置

proxy_read_timeout    190;
proxy_connect_timeout 3;
proxy_redirect        off;
proxy_http_version    1.1;
proxy_set_header      Host $host;
proxy_set_header      Upgrade $http_upgrade;
proxy_set_header      Connection $proxy_connection;
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 $proxy_x_forwarded_proto;
proxy_set_header      X-Forwarded-Ssl $proxy_x_forwarded_ssl;
proxy_set_header      X-Forwarded-Port $proxy_x_forwarded_port;
proxy_set_header      Proxy "";
Run Code Online (Sandbox Code Playgroud)

我的 Nginx 实例在本地 Docker Swarm 中运行,我使用环回接口 (198.18.0.1) 来访问我的计算机上的开放端口。你的旅费可能会改变。3000端口用于Vite服务器。端口 9082 用于 Laravel 服务器。

在某些时候,我可能会调查使用堆栈中声明的主机名docker-compose,尽管我不太确定在 Docker Swarm 和常规容器堆栈之间进行通信时这种情况有多好。重点是,如果我最终同时运行多个项目,则不必为 Laravel 和 Vite 服务器分配唯一的端口。

入口点/@vite/resources是应用程序最初启动时的入口点,它们由标头中的脚本和链接标签使用。此后,所有 HMR 活动都使用/app/.

下一个挑战将是添加自签名证书,因为我计划集成一些 Azure B2C 登录,但我认为这可能只涉及更新 Nginx 配置以适应 TLS 并更新APP_URLDEV_SERVER_URL匹配.env