zoukankan      html  css  js  c++  java
  • DevOps 前端项目(angular、vue、react)打包静态资源生成一份Docker镜像支持部署不同环境

    1、前言


    为了尽可能地轻量化前端镜像(非node承载),将前端编译成静态资源通过nginx承载。
    与后端程序不同的是,当使用静态资源方式时页面是直接加载到浏览器进行渲染,无法读取服务端机器中 env 的环境变量。
    当有部署多个环境(dev、uat、pro)需求时,就无法像后端程序一样满足生成一个镜像部署不同环境。
    如果你有同样的需求请往下看。

    2、使用ngx_http_js_module


    参考 ngx_http_js_module

    njs是JavaScript语言的子集,它允许扩展nginx功能。njs的创建符合 ECMAScript 5.1 (严格模式)以及某些 ECMAScript 6 和更高版本的扩展。合规性还在不断发展

    default.conf

    主要关注 location /env { js_content getenv; } 部分内容,getenv 是一个 JavaScript function 函数。

    server {
      listen       80;
      # listen 443;
      # ssl on;
      # ssl_certificate /etc/nginx/ssl/server.crt;
      # ssl_certificate_key /etc/nginx/ssl/server.key;
    
      server_name  localhost;
    
      #charset koi8-r;
      #access_log  /var/log/nginx/host.access.log  main;
    
      location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
        try_files $uri $uri/ /index.html;
        proxy_set_header    Host        $host;
        proxy_set_header    X-Real-IP   $remote_addr;
        proxy_set_header    X-Forwarded-For $proxy_add_x_forwarded_for;
      }
    
      location /env {
            js_content getenv;
      }
    
      #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;
      }
    }
    
    

    nginx.conf

    主要关注 js_include env.js; 部分内容,引入js。

    user  nginx;
    worker_processes  auto;
    
    error_log  /var/log/nginx/error.log warn;
    pid        /var/run/nginx.pid;
    
    load_module modules/ngx_http_js_module.so;
    
    events {
        worker_connections  1024;
    }
    
    
    http {
        js_include env.js;
        include       /etc/nginx/mime.types;
        default_type  application/octet-stream;
    
        log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                          '$status $body_bytes_sent "$http_referer" '
                          '"$http_user_agent" "$http_x_forwarded_for"';
    
        access_log  /var/log/nginx/access.log  main;
    
        sendfile        on;
        #tcp_nopush     on;
    
        keepalive_timeout  65;
    
        #gzip  on;
        include /etc/nginx/conf.d/*.conf;
    }
    

    env.js

    对应 default.conf 中使用的方法。

    function getenv(r) {
        var strEnv = '{"Shortsha": "'+ process.env.SHORTSHA +'","UI_ENVIRONMENT": "'+ process.env.UI_ENVIRONMENT +'"}';
        r.headersOut['Content-Type'] = "application/json; charset=utf-8";
        r.return(200, strEnv);
    }
    
    • 效果示意

    3、前端部分(以angular为例)


    文件夹 /assets 中预先配置多个环境的配置文件 appconfig.dev.json 、appconfig.uat.json 、appconfig.pro.json

    是不是和 .net core 中后端程序配置很像,启动配置的环境变量 "ASPNETCORE_ENVIRONMENT": "Development" 配置文件 appsettings.json、appsettings.Development.json ...

    同样的道理只要在渲染生命周期比较开始的位置获上文在 nginx 中配置的 env 地址中拿到环境配置在赋值到 AppConsts.remoteServiceBaseUrl 全局变量中。

      private static getApplicationConfig(injector: Injector,httpClient: HttpClient,callback: () => void
      ) {
        //能满足ng build --|dev|uat|pro 编译时指定不同环境变量
        let envName = '';
        if (environment.production) {
          envName = 'pro';
        } else {
          envName = 'dev';
        }
        //nginx容器中环境变量
        const envUrl = window.location.protocol + '//' + window.location.host + "/env";
        httpClient.get(envUrl).subscribe(
          (result: any) => {
            envName = result.UI_ENVIRONMENT;
    
            callback();
          },
          error => {
            alert(`获取环境变量出错,信息:
    
    ${error.message}`);
          }
        );
    
        //assets 文件夹存放不同环境配置文件
        const url = '/assets/appconfig.' + envName + '.json';
        httpClient.get(url).subscribe(
          (result: any) => {
            //后端服务地址
            AppConsts.remoteServiceBaseUrl = result.remoteServiceBaseUrl;
    
            callback();
          },
          error => {
            alert(`初始化配置出错,信息:
    
    ${error.message}`);
          }
        );
      }
    

    4、镜像、部署


    Dockerfile

    在 cicd 流水线 build 拿到产出的 /dist 静态资源打包Docker镜像。

    FROM nginx:1.17.3-alpine as base
    EXPOSE 80
    WORKDIR /usr/share/nginx/html
    
    COPY /_nginx/nginx.conf /etc/nginx/nginx.conf
    COPY /_nginx/env.js /etc/nginx/env.js
    COPY /_nginx/default.conf /etc/nginx/conf.d/default.conf
    
    COPY /dist /usr/share/nginx/html
    
    CMD ["nginx", "-g", "daemon off;"]
    

    部署的yaml中配置

    value 中的值均通过流水线变量获取,文中使用具体值示意。

    env: 
    - name: UI_ENVIRONMENT
        value: "uat"   #流水线中不同分支对应不同环境
    - name: SHORTSHA
        value: "v1.0"  #源码仓库的签名
    

    5、总结


    水平有限,难免有所纰漏,欢迎批评指正。本文纯属抛转引玉,大家有更好思路欢迎留言评论。

  • 相关阅读:
    [Leetcode] 225. Implement Stack using Queues
    前端面试题2
    数据结构_stack
    数据结构 station
    数据结构_wow(泡泡的饭碗)
    数据结构_XingYunX(幸运儿)
    数据结构 nxd(顺序对)
    数据结构 hbb(汉堡包)
    数据结构 elegant_sequence(优雅的序列)
    数据结构 i_love(我喜欢)
  • 原文地址:https://www.cnblogs.com/ddrsql/p/13861584.html
Copyright © 2011-2022 走看看