最近闲来无事,去学了学docker这方面的东西,之前的公司也用到过docker去管理项目,但是一些打包脚本写的不是很好,很多东西都需要在打包之前去硬改,手动替换,导致新手去发布的时候,造成了很多事故,很自豪的告诉你们,我也是其中一个,那时候的我弱小又无助,也没有能力去搞脚本docker这类的,每发次版都要心脏病发作一次,公司这方面的制度也是挺严格的,出了问题之后就开始投鼠忌器,一颗冉冉升起的新星就这样熄灭了,好了,废话又多起来了,每次写文章感觉知识点没有,全是些废话。
那么今天我们就来直面心魔,大声喊出:王侯将相宁有种乎?(tips:好像就是挺有种的),我们能不能自己去写一套docker打包的脚本呢?答案是能的。前提是你看过docker文档,配置好了Dockerfile跟docker-compose.yml两个文件,那么这一套发布的脚本你值得拥有。
考虑到很多同学使用的window系统,而且用不惯git bash或者cmder之类的工具,所以舍弃shell脚本的想法,采用node的inquirer包,来进行一个打包菜单的选择,让你无惧系统兼容,为所欲为,基本流程就是本地docker build项目,登录远程dockerhub仓库,再进行push操作,非常的敢单。
const inquirer = require('inquirer');
const fs = require('fs');
const exec = require('child_process').execSync;
const FILENAME = 'docker-log';
const COMPOSENAME = 'docker-compose.yml';
const dockerBuild = () => {
return exec('docker-compose up --build', {
stdio: 'inherit'
});
}
const login = (cb) => {
inquirer.prompt([{
type: "input", // 密码为密文输入
message: "请输入用户名:",
name: "username"
}, {
type: "password", // 密码为密文输入
message: "请输入密码:",
name: "password"
}]).then(r => {
// 先登录
try {
exec(`docker login -u=${r.username} -p=${r.password}`, {
stdio: 'inherit'
})
cb();
} catch(e) {
login();
}
})
}
let versionType = 0; // 0 原版本 | 小版本 | 大版本
let versionDes = ''; // 版本描述
let versionNum = '1.0.0'; // 当前版本号
let envMaps = ['pro', 'beta', 'dev'];
let vTypeMaps = ['原版本', '小版本', '大版本'];
// 生成docker-log
const createDockerLog = (envText) => {
let vNum;
try {
const r = fs.readFileSync(FILENAME, 'utf8');
const arr = r.split('\n');
const len = arr.length;
const version = arr[len - 3];
vNum = version.split('-')[1];
const va = vNum.split('.');
console.log(va);
switch (versionType) {
case 0:
versionNum = vNum;
break;
case 1:
versionNum = `${va[0]}.${va[1]}.${++va[2]}`;
break;
case 2:
versionNum = `${++va[0]}.${va[1]}.${va[2]}`;
break;
}
fs.appendFileSync(FILENAME, `${envText}-${versionNum}\n${versionDes}\n`, 'utf8');
} catch (e) {
fs.writeFileSync(FILENAME, `${envText}-${versionNum}\n${versionDes}\n`);
}
// 把最新信息写入compose中
const cr = fs.readFileSync(COMPOSENAME, 'utf8');
fs.writeFileSync(COMPOSENAME, cr.replace(vNum, versionNum));
}
const clearBuild = () => {
versionNum = '';
versionType = 0;
versionDes = '';
}
const createCompose = () => {
return new Promise((resolve, reject) => {
inquirer.prompt([{
type: 'list',
message: '请选择运行环境:',
name: 'env',
choices: envMaps
}]).then(r => {
inquirer.prompt([{
type: 'list',
message: '请选择发布的版本类型:',
name: 'versionType',
choices: ['原版本', '小版本', '大版本']
}]).then(r1 => {
versionType = vTypeMaps.indexOf(r1.versionType);
inquirer.prompt([{
type: "input", // 密码为密文输入
message: "请填写当前版本描述:",
name: "des"
}]).then(r2 => {
versionDes = r2.des;
createDockerLog(r.env);
resolve();
})
})
})
});
}
const dockerPush = () => {
try {
exec(`docker push xxx/xxx:${ versionNum }`, {
stdio: 'inherit'
});
clearBuild();
} catch(e) {
login(dockerPush);
}
}
const start = async () => {
// 先生成最新compose
await createCompose();
// 先用本地docker打包
dockerBuild();
// 推送
dockerPush();
}
start();