You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

K8s集群部署Vue.js应用时history模式下非首页刷新/直接访问出现404错误的技术求助

问题分析与解决方案

看起来你的核心问题是Vue Router history模式下,刷新子页面或直接访问子路径时出现404,这是因为服务器没有配置路径回退到index.html的规则。结合你的配置文件,我发现几个关键错误,下面一步步帮你修正:


1. 冗余容器与路径不匹配(Deployment的核心问题)

你在Deployment里部署了两个容器(vue-nginx和vue),还用emptyDir共享静态文件——这完全没必要!你的Dockerfile已经把Vue构建产物打包到Nginx镜像里了,额外的vue容器属于冗余设计,还会导致文件路径混乱。

同时,你的ConfigMap里的Nginx配置监听8080端口,但Service的targetPort是80,容器端口和服务端口不匹配,请求根本无法正确到达后端Nginx的规则处理逻辑。

修正后的Deployment

只保留一个容器,使用你构建好的Vue-Nginx镜像:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: "my-deployment"
spec:
  replicas: 1
  selector:
    matchLabels:
      app: "my-app"
  template:
    metadata:
      labels:
        app: "my-app"
    spec:
      containers:
        - name: "vue-nginx"
          image: XXX/my_image:latest  # 替换为你实际的镜像地址
          ports:
            - containerPort: 80
          imagePullPolicy: "Always"
      imagePullSecrets:
        - name: registry-secret
      restartPolicy: Always

2. Nginx配置路径与端口错误(ConfigMap/Dockerfile问题)

你的ConfigMap里的default.conf存在两个关键错误:

  • root /var/www/app:但你的Dockerfile把Vue构建产物放到了/usr/share/nginx/html,路径完全不匹配
  • listen 8080 default:和容器、服务的80端口不一致

更简单的方案:直接在Dockerfile中嵌入正确配置

不需要使用ConfigMap,直接在构建镜像时加入符合Vue history模式的Nginx配置,这样更可靠:

第一步:在本地项目根目录创建nginx/default.conf

server {
    listen 80;
    root /usr/share/nginx/html;
    index index.html;

    # 核心规则:所有不存在的路径回退到index.html,支持Vue Router history模式
    location / {
        try_files $uri $uri/ /index.html;
    }

    # 可选:给静态资源添加缓存,优化加载速度
    location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
        expires 1y;
        add_header Cache-Control "public, immutable";
    }
}

第二步:修改Dockerfile

# 构建环境
FROM node:12.2.0-alpine as build
WORKDIR /app
ENV PATH /app/node_modules/.bin:$PATH
COPY ./[项目文件夹]/ .
RUN npm config set unsafe-perm true
RUN npm install --silent
RUN npm install @vue/cli@3.7.0 -g
RUN npm run build

# 生产环境
FROM nginx:1.16.0-alpine
# 加入Vue history模式需要的Nginx配置
COPY ./nginx/default.conf /etc/nginx/conf.d/default.conf
# 复制构建好的静态文件到Nginx默认目录
COPY --from=build /app/dist /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

3. Ingress配置简化优化

你的Ingress配置用了/.*正则路径,其实没必要这么复杂。只要设置path: /并指定pathType: Prefix,就能让所有路径都转发到后端服务,再由后端Nginx处理回退逻辑。

修正后的Ingress.yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: foo-ingress-lb
  annotations:
    kubernetes.io/ingress.class: "nginx"
    kubernetes.io/tls-acme: "true"
    cert-manager.io/issuer: letsencrypt-prod
    # 移除不必要的正则注解
spec:
  tls:
    - hosts:
        - www.foo.com
      secretName: tls-secret
  rules:
    - host: www.foo.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: my-service
                port:
                  number: 80

验证步骤(确保问题解决)

  1. 本地测试镜像:先在本地运行镜像,确认历史模式正常工作

    docker build -t vue-app .
    docker run -p 8080:80 vue-app
    

    访问http://localhost:8080/your-sub-page,刷新页面看是否还会404。

  2. K8s容器内验证配置:部署后进入容器检查Nginx配置和静态文件

    kubectl exec -it <你的Pod名称> -- cat /etc/nginx/conf.d/default.conf
    kubectl exec -it <你的Pod名称> -- ls /usr/share/nginx/html
    
  3. 检查Ingress规则:确认Ingress已经正确生效

    kubectl describe ingress foo-ingress-lb
    

内容的提问来源于stack exchange,提问作者Brice Le Roux

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 05:02:36