• 企业400电话
  • 微网小程序
  • AI电话机器人
  • 电商代运营
  • 全 部 栏 目

    企业400电话 网络优化推广 AI电话机器人 呼叫中心 网站建设 商标✡知产 微网小程序 电商运营 彩铃•短信 增值拓展业务
    使用脚本一键打包并上传docker镜像的实现代码

    笔者搞了一年多微前端项目,一个团队管理十个微应用,换成docker镜像部署后,发布操作一下从原来的脚本直连服务器的1分钟变成了几十分钟,尤其上传每个应用到各自的阿里云仓库。这里就再写个脚本一键打包docker镜像并上传阿里云。

    本文只讲怎么制作一个脚本帮助去减轻开发人员负担,关于docker-compose的配置见: 使用各种姿势舒服的部署微前端项目(上:打包与上传)

    效果图

    直接上代码

    /**
     * @name docker镜像打包上传脚本
     * @author weilan
     * @time 2021.02.22
     */
    const fs = require('fs');
    const path = require('path');
    const util = require('util');
    const { log } = require('../utils/log');
    const exec = util.promisify(require('child_process').exec);
    const sub_app_ath = path.resolve();
    let sub_apps = fs.readdirSync(sub_app_ath).filter(i => /^subapp|master/.test(i));
    const inquirer = require('inquirer'); // 用于命令行交互
    
    /**
     * @name 命令行交互配置项
     */
    const question = [
     {
      type: 'confirm',
      name: 'dist',
      message: '是否需要打包前端静态资源?',
     },
     {
      type: 'confirm',
      name: 'env',
      message: '请选择是否需要打包成不联网的内网部署',
      when: function (answers) { // 当answer为true的时候才会提问当前问题
       return answers.dist
      }
     },
     {
      type: 'checkbox',
      name: 'apps',
      message: '请选择要发布的模块',
      choices: sub_apps,
      validate: function (val) {
       if (val.length) { // 校验
        return true;
       }
       return "选择不能为空";
      }
     },
    ]
    
    /**
     * @name 根据命令交互配置结果做逻辑处理
     */
    inquirer.prompt(question).then(async (answer) => {
     let subApps = answer.apps;
     let buildScript = answer.env ? 'yarn build --Intranet' : 'yarn build';
     let needDist = answer.dist;
     let now = +new Date();
     // 登录阿里云
     const { error: loginError } = await exec('docker login --username=哈哈哈 --password=嘿嘿 registry.cn-zhangjiakou.aliyuncs.com');
     if (loginError) {
      log.red(loginError, '登录镜像中心失败')
      return;
     }
     console.log(`开始依次处理 ${JSON.stringify(subApps)} ......`);
     subApps.reduce((chain, item) => {
      return chain.then(() => publishIamge(item, now, needDist, buildScript))
     }, Promise.resolve())
    });
    
    /**
     * @name 打包镜像并推送阿里云
     * @param {String} moduleName 模块名
     * @param {String} now 当前版本时间戳
     * @param {Boolean} needDist 是否需要打包前端静态资源
     * @param {String} buildScript 前端静态资源打包命令
     */
    async function publishIamge(moduleName, now, needDist, buildScript) {
     // 打包前端静态资源
     if (needDist) {
      console.log('开始打包前端静态资源' + moduleName);
      const { error } = await exec(buildScript, { cwd: path.resolve(moduleName) });
      if (error) {
       log.red(moduleName, '前端代码打包错误:', error)
       return;
      }
      log.green(moduleName + '前端代码打包成功')
     }
     // 打包镜像
     console.log(`开始打包镜像 ${moduleName} ......`);
     const { stdout: buildStdout, error: buildError } = await exec('docker-compose build ' + moduleName);
     if (buildError) {
      log.red(buildError, '镜像打包错误')
      return;
     }
     log.cyan(buildStdout)
     log.green('镜像打包完成,开始制作镜像标签')
     // 更新镜像标签
     const imageName = 'ibp2fe_' + moduleName;
     const { error: tagError } = await exec(`docker tag ${imageName} registry.cn-zhangjiakou.aliyuncs.com/futureweb/${imageName}:${now}`);
     if (tagError) {
      log.red(tagError, '镜像标签异常')
      return;
     }
     log.green('镜像版本标签更新完毕,开始更新last标签')
     // 更新镜像标签last版本
     const { error: tagLastError } = await exec(`docker tag ${imageName} registry.cn-zhangjiakou.aliyuncs.com/futureweb/${imageName}`);
     if (tagLastError) {
      log.red(tagError, '镜像last标签异常')
      return;
     }
     log.green('镜像last标签更新完毕,开始上传')
     const { stdout: pushStdout, error: pushError } = await exec('docker push registry.cn-zhangjiakou.aliyuncs.com/futureweb/' + imageName);
     if (pushError) {
      log.red(pushError, '镜像上传失败')
      return;
     }
     log.cyan(pushStdout)
     log.green('镜像上传成功')
    }
    
    process.on('unhandledRejection', (reason, p) => {
     console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
     // application specific logging, throwing an error, or other logic here
    });

    实现思路和注意事项

    这里有个需要注意的点,因为是工具函数处理,每个模块的路径由node读取,因此你的模块名和docker-compose.yml里的服务名、容器名最好都一致;另外注意你的镜像打包后是你docker-compose.yml外的根目录下划线连接你的docker-compose服务名,因此你的阿里云镜像仓库命名最好和这个组合后镜像名一致;以上都是为了方便工具函数能够通用处理各个模块镜像。

    1. 制作镜像标签。这里我会制作一个本次发布时间戳的版本和一个lastet版本,前面方便回退,后面方便运维部署时无需关心标签版本。也可以拉取git tag来做镜像的tag。
    2. 制作镜像后上传至阿里云镜像中心
    上一篇:docker安装pxc集群的详细教程
    下一篇:基于nginx实现上游服务器动态自动上下线无需reload的实现方法
  • 相关文章
  • 

    © 2016-2020 巨人网络通讯 版权所有

    《增值电信业务经营许可证》 苏ICP备15040257号-8

    使用脚本一键打包并上传docker镜像的实现代码 使用,脚本,一键,打包,并,