我最开始是用来学习前端vue技术,找的前后端项目资料,之前一直就用docker管理数据库和redis,也了解过一点后台docker部署,但没弄过前台项目的docker部署,正好心血来潮想部署一下前端项目,这样前台有了,后台有了,数据库和redis也有了,不就可以一键上线了吗,顺着这个思路,开搞。

项目需要本地运行和容器运行,立刻想到了需要多环境部署,既然spring有多环境,没道理vue没有,找资料问ai搞起,于是有了:

./RuoYi-Vue3/.env.development 修改
./RuoYi-Vue3/.env.production 修改

这里有一个吐槽的地方,就是环境配置的使用,在package.json中:

  "scripts": {
    "dev": "vite --mode development",
    "build": "vite build --mode production",
    "preview": "vite preview"
  },

它默认的写的脚本没有后面的–mode 部分,他们这里才有了一种约定优于配置的策略,也就是说dev默认走".env.development",而build默认走".env.production",我要吐槽的就是这种本来就写一次的配置,就别约定了,否则又容易隐藏一个"你不知道我知道"的坑,运行脚本的时候又不用输入,省这点劲儿,埋雷,真的犯不上。(我对于滥用"约定优于配置"深深痛恨,确切的说是每踩一次坑骂一次)

这俩文件若依项目本来就有,但我开始搞的项目没有,不过若依的配置内容也不是符合容器运行的,稍作调整,主要是增加一个后台地址的变量,容器网络中可以用容器名和服务名(docker compose)来访问。

# 容器环境,ruoyi-backend就是后台容器的名字
VITE_API_BASE_URL = http://ruoyi-backend:8080
# 本地环境
VITE_API_BASE_URL = http://localhost:8080

顺着原本配置代理的思路,在vite.config.js的代理中配置上多环境的后端地址变量就OK了,于是查了怎么读取环境变量,也是边试边调,继续搞。
有资料说可以这样读取环境变量配置:

const VITE_API_BASE_URL = import.meta.env.VITE_API_BASE_URL;

明明在request.js中能用,为什么在vite.config.js中就失效呢。这促进我对工程化的vue项目有了进一步理解,原来这些文件虽然都是js文件,但是并不相同,vite.config.js是给构建程序用的,而src中的代码是构建程序处理的,也就是说在构建程序启动的时候,处理src的某些工具还没有准备好,预判处理import.meta.env.VITE_API_BASE_URL;的工具就还不能用,或者根本不会处理vite.config.js文件,只能用另一种方式读环境变量:

import { defineConfig, loadEnv } from 'vite'
export default defineConfig(({command, mode}) =>{ 
  // 根据当前环境加载对应的 .env 文件
  const env = loadEnv(mode, process.cwd(), '')
}

准备好了(自己以为的)多环境配置,接下来就是写Dockerfile了,不用多说,AI走起:

# 第一阶段:node镜像打包
FROM node:20-alpine3.19 AS frontend-builder
WORKDIR /build-app
COPY . .
RUN npm install
RUN npm run build:prod

# 第二阶段:nginx打包
FROM nginx:1.29.1-alpine3.22-otel
EXPOSE 80
WORKDIR /app
# 替换nginx配置
COPY nginx.conf /etc/nginx/conf.d/default.conf
# 将第一阶段的静态文件复制到nginx中
RUN rm -rf /usr/share/nginx/html
RUN mkdir /usr/share/nginx/html
COPY --from=frontend-builder /build-app/dist /usr/share/nginx/html

# 运行
CMD ["nginx", "-g", "daemon off;"]

看看就懂了,node打包出一部署文件夹disk,部署到nginx容器中,这个牛的地方是,仔细看了半天,居然没有任何和应用相关的东西,这才是好配置!!!
对了,上面可以看到还要写nginx.conf,第二个坑他来了,配置如下:

server{
  listen        80;
  listen   [::]:80;
  server_name   localhost;

  access_log  /var/log/nginx/host.access.log  main;

  # 前端静态资源
  location / {
    root    /usr/share/nginx/html;
    index   index.html index.htm;

    # 新增下面这句,其他是nginx默认配置
    # 解决部分前端框架的路由问题,在浏览器刷新时报404
    try_files $uri $uri/ /index.html;
  }

  # 新增:反向代理 API 请求
  # 所有以 /api 开头的请求,转发到后端服务
  location /prod-api/ {
    # 注意:http://ruoyi-backend:8080 是 Docker 内部服务名 + 端口
    proxy_pass http://ruoyi-backend:8080/;

    # 以下配置确保后端能正确识别客户端信息
    proxy_set_header Host $host;
    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 $scheme;

    # 缓冲设置
    proxy_buffering off;
  }

  error_page    500 502 503 504 /50x.html;
  location = /50x.html {
    root     /usr/share/nginx/html;
  }
}

当然,免不了AI生成,只是不能用,遇到不少问题,调了又调:

try_files $uri $uri/ /index.html;

上面这个配置是因为vue这种单页面应用,url压根匹配不上,所以匹配不上的时候统统交给主页(整个网站就一个index.html)

我容器部署了调了很久,就是连不上后台,寻寻觅觅了很久才知道,vue配置的那个代理服务器(当时为了解决跨域搞的)在打包后直接消失了,没了,压根不能代理,所以前面配置的什么后台服务地址啥的,压根没用。后面AI给出了反向代理配置:

proxy_pass http://ruoyi-backend:8080/;

很多时候使用AI就会发现,他们好多时候丢三落四的,你不提它不提,最后你掉坑里,一旦你能给点提示,它还是挺能干的。

翻了下前面列出的前端调整文件列表,就这五个,说完了。后续的问题下一篇接着记录。

最后说一嘴对于AI的看法,AI可以提升效率,略微拓宽技能范围,嗯,大概就是本来600码的技能范围,可以刮到660吧。但纯外行用AI开发,就会出现,“不对,不对,不对。。。”的死循环。你帮助不了AI提示分析问题,AI帮你的能力也有限。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐