需求:VUE项目,开发提供源代码,部署生产环境,使用域名访问生产环境。

一、思路分析

  • VUE项目,只提供源码:构建镜像时,使用Nodejs和NGINX两个基础镜像多阶段构建;
  • 部署生产环境:通过configmap创建配置。
  • 使用域名访问生产环境:部署Deployment Controller 、Service、Ingress。
  • 从远端定时拉取资源:需要使用sidecar模式,一个vue容器,一个img容器,共享存储路径,实现静态资源远端拉取更新。

二、构建docker镜像

说明:构建镜像时需要在外网环境中执行,要不然会因为网络问题构建失败

在这个案例中,我们只有git仓库的地址。因此我们首先要克隆代码,然后再执行打包并测试。

#查看Dockerfile
[root@master01 ~]# cd /root/5/vue3_web_element-demo-plus
[root@master01 vue3_web_element-demo-plus]# cat Dockerfile
FROM registry.cn-hangzhou.aliyuncs.com/github_images1024/node:18.12.0 AS build
COPY . /opt/vue
WORKDIR /opt/vue
RUN npm cache clean --force \
&& npm config set strict-ssl false \
&& npm i \
&& npm install -g cnpm --registry=https://registry.npmmirror.com \
&& npm run build

FROM registry.cn-hangzhou.aliyuncs.com/zq-demo/nginx:1.21.6
COPY --from=build /opt/vue/dist /opt/vue/dist
RUN rm /etc/nginx/conf.d/default.conf
COPY vue.conf /etc/nginx/conf.d/vue.conf
CMD ["nginx", "-g","daemon off;"]

#构建镜像
[root@master01 vue3_web_element-demo-plus]# docker build -t registry.cn-hangzhou.aliyuncs.com/abroad_images/vue:v1-aming .

#后台启动测试容器
[root@master01 vue3_web_element-demo-plus]# docker run -it --rm  -p 8088:80 registry.cn-hangzhou.aliyuncs.com/abroad_images/vue:v1-aming

#验证
[root@master01 vue3_web_element-demo-plus]# curl localhost:8088 -i -I
HTTP/1.1 200 OK
Server: nginx/1.27.4
Date: Sun, 30 Mar 2025 08:42:18 GMT
Content-Type: text/html
Content-Length: 429
Last-Modified: Sun, 30 Mar 2025 08:31:09 GMT
Connection: keep-alive
ETag: "67e9014d-1ad"
Access-Control-Allow-Origin: *
Accept-Ranges: bytes

三、推送至harbor私有镜像仓库

构建好镜像测试无误后,接下来就可以推送到harbor私有镜像仓库中

#打标签
[root@master01 springdemo]# docker tag  registry.cn-hangzhou.aliyuncs.com/abroad_images/vue:v1-aming harbor.zhang-qing.com/demo/vue:v1-aming

#推送到harbor私有镜像仓库
[root@master01 springdemo]# docker push harbor.zhang-qing.com/demo/vue:v1-aming

四、创建configmap资源

创建生产环境nginx的配置文件。

[root@master01 vue3_web_element-demo-plus]# cat configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: vue
data:
  default.conf: |-
    server {
      listen       80;
      server_name   vue-test.zhang-qing.com; # 生产环境域名
      location /img {             # 访问img路径下资源时重定向到百度页面
          return 301 https://www.baidu.com;
      }
      location / {
          root  /opt/vue/dist;
          index  index.html index.htm;
          try_files $uri $uri/ /index.html;
          add_header Access-Control-Allow-Origin *;
      }
    }

#应用
[root@master01 vue3_web_element-demo-plus]# kaf configmap.yaml

五、创建deployment资源

[root@master01 vue3_web_element-demo-plus]# cat deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: vue
spec:
  replicas: 1
  selector:
    matchLabels:
      app: vue
  template:
    metadata:
      labels:
        app: vue
    spec:
      containers:
      - name: vue
        image: harbor.zhang-qing.com/demo/vue:v1-aming
        resources:
          limits:
            memory: "1Gi"
            cpu: "1"
          requests:
            memory: "128Mi"
            cpu: "100m"
        ports:
          - containerPort: 80
            name: web
        livenessProbe:
          httpGet:
            port: web
            path: /
        readinessProbe:
          tcpSocket:
            port: web
        volumeMounts:
          - mountPath: /etc/nginx/conf.d/default.conf
            subPath: default.conf
            name: nginx-config
          - mountPath: /media
            name: media
      volumes:
        - name:  nginx-config  # 使用生产模式nginx配置文件
          configMap:
            name:  vue
        - name: media          # 挂载空目录用于存放远端资源
          emptyDir: {}

#应用
[root@master01 vue3_web_element-demo-plus]# kaf deployment.yaml

六、创建service资源

[root@master01 vue3_web_element-demo-plus]# cat service.yaml
apiVersion: v1
kind: Service
metadata:
  name: vue
spec:
  type: ClusterIP
  selector:
    app: vue
  ports:
  - name: http
    port: 80
    protocol: TCP
    targetPort: 80

#应用
[root@master01 vue3_web_element-demo-plus]# kaf service.yaml

七、创建ingress资源

[root@master01 vue3_web_element-demo-plus]# cat ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    konghq.com/https-redirect-status-code: "301"
    konghq.com/protocols: http
    konghq.com/regex-priority: "1000"
  name: vue-ing
spec:
  ingressClassName: nginx
  rules:
  - host: vue-test.zhang-qing.com
    http:
      paths:
      - backend:
          service:
            name: vue
            port:
              number: 80
        path: /
        pathType: ImplementationSpecific

#应用
[root@master01 vue3_web_element-demo-plus]# kaf ingress.yaml

##配置hosts
在阿里云域名做A记录
10.0.0.11 vue-test.zhang-qing.com

八、访问验证

打开浏览器输入http://vue-test.zhang-qing.com/进行访问,如果出现504 Gateway Time-out报错信息,重启pod后,重新刷新页面即可

[root@master01 vue3_web_element-demo-plus]# k delete po vue-6456c8fff5-7l25j
pod "vue-6456c8fff5-7l25j" deleted

image-20250330170501857

如果访问http://vue-test.zhang-qing.com/img/images.jpg时,会301重定向到百度界面。

image-20231224130922593

九、环境复原

[root@master01 vue3_web_element-demo-plus]# k delete -f  ingress.yaml -f  service.yaml -f deployment.yaml -f configmap.yaml

十、编译Dockerfile遇到的问题

问题1:sh: 1: vite: Permission denied

# 问题1报错内容: sh: 1: vite: Permission denied
[root@master01 vue3_web_element-demo-plus]# docker build -t vue:v1 .
...
...
sh: 1: vite: Permission denied
The command '/bin/sh -c npm install --registry https://registry.npm.taobao.org  && npm run build' returned a non-zero code: 127

# 问题1处理方法: sh: 1: vite: Permission denied
[root@master01 vue3_web_element-demo-plus]# rm -rf node_modules/