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

2025-05-27 0 85

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

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

效果图

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

直接上代码

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120
/**

* @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

});

实现思路和注意事项

  • 首先考虑命令行交互的方式,将需要做的配置以选择的方式让开发人员确认,最后选择要发布的模块
  • 提前登录阿里云账号
  • 这里可以选择并发执行所选全部模块,但是这样日志输出会无序,且电脑压力极大会暂时死机;因此这里我用依次处理的方式
  • 打包所选模块的前端静态资源
  • 执行docker-compose build xxx 打包所选模块镜像

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

  1. 制作镜像标签。这里我会制作一个本次发布时间戳的版本和一个lastet版本,前面方便回退,后面方便运维部署时无需关心标签版本。也可以拉取git tag来做镜像的tag。
  2. 制作镜像后上传至阿里云镜像中心

原文链接:https://segmentfault.com/a/1190000039272760

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

快网idc优惠网 行业资讯 使用脚本一键打包并上传docker镜像的实现代码 https://www.kuaiidc.com/64637.html

相关文章

发表评论
暂无评论