自动化部署-ts转义成shell(16)

110 阅读3分钟

源码: j-spring-eco ts版本的Spring全家桶,开发阶段。

1.前言

整个全家桶的最后一步了,这个项目的初衷就是为了方便写一些公司业务的辅助应用。快狠准就是首要目标了,开发如上,部署也更加要求简单化。

2.设计目标

编写ts代码,自动转译成shell,传到服务器进行自动化部署。

3.部署代码

1.获取应用类

import { getDockerApp, AppManager, DockerHelper } from 'j-spring-deploy';

export const appManager = new AppManager({});

/**
 * 获取部署APP 依赖docker
 * 只要使用任意app,都会在脚本头部添加安装docker的依赖shell脚本,方便一键部署。
 */
const { git, dockerNetwork, pnpm, pm2, nginx, mysql } = getDockerApp(
  appManager
);

//第一步:克隆或者更新项目地址
export const jkDemo = git.cloneOrPull({
  cwd: '/git',
  git: 'https://gitee.com/woaianqi/jk-demo.git',
  user: 'xxxxx',
  password: 'xxxxx',
});

//第二步:安装依赖并构建 使用腾讯代理 并自动构建项目  同时app内部已经设置好了包缓存策略。
pnpm.installDep(jkDemo.projectPath, { tecentProxy: true, autoBuild: true });

//第三步:创建桥接网络
export const network = dockerNetwork.createNetwork('testjob');

//第四步:启动一个mysql
mysql.start({
  containerName: 'mysql2',
  network,
  logDir: '/appLogs/mysql/log',
  dataDir: '/mysql/data',
  ports: [[6606, 3306]],
  configDir: jkDemo.safeJoin('deploy/mysql/conf'),
  rootPassword: 'dsfgzxczsdfasefrasd234',
});

//第五步:启动node服务 冗余1
pm2.start({
  containerName: 'jkDemo',
  network,
  dockerHelper: DockerHelper.create().ammount('/appLogs/jkDemo', '/log'), //追加额外的目录挂载
  env: { containerName: 'jkDemo' }, //对node项目添加环境变量, 用于API提示数据来源。
  cwd: jkDemo.projectPath,
  index: 'dist/index.js',
});

//启动node服务 冗余2
pm2.start({
  containerName: 'jkDemo2',
  network,
  dockerHelper: DockerHelper.create().ammount('/appLogs/jkDemo2', '/log'),
  env: { containerName: 'jkDemo2' },
  cwd: jkDemo.projectPath,
  index: 'dist/index.js',
});

//第六步:启动Nginx
nginx.start({
  containerName: 'nginx2',
  network,
  ports: [[80]],
  logDir: '/appLogs/nginx/log',
  configFile: jkDemo.safeJoin('deploy/nginx/nginx.conf'),
  configDir: jkDemo.safeJoin('deploy/nginx/conf'),
});

//第七步:展示活跃的docker容器
pm2.showActiveContainer();

//第八步:控制台打印输出的shell脚本
appManager.printShellScript();

//第九步:发送到对方服务器部署
appManager.publishBySSH({
  host: '192.168.42.168',
  username: 'xxxx',
  password: 'xxxx',
});

4.实际运行的shell脚本

上述代码自动生成的脚本

#!/bin/bash
if [ ! $(command -v docker) ]; then
	curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun
fi
if [ -d /git/jk-demo ]; then
	docker run --rm -v ${HOME}:/root -v /git/jk-demo:/git alpine/git pull
else
	docker run --rm -v ${HOME}:/root -v /git:/git alpine/git clone 'https://xxxxx:xxx!~@gitee.com/woaianqi/jk-demo.git'
fi
docker network create testjob 2>/dev/null
if [ -d /git/jk-demo ]; then
	docker run --rm -v /git/jk-demo:/app -v ${HOME}/pnpm-store:/pnpm-store 892280082/pnpm:v3 pnpm install --registry https://mirrors.cloud.tencent.com/npm/ 
else
	echo 'pnpm error:/git/jk-demo not exist!'
	exit 100
fi
if [ ! -e /git/jk-demo/deploy/mysql/conf ]; then
	echo 'git: /git/jk-demo/deploy/mysql/conf path not exist '
	exit 1
fi
docker stop mysql2 2>/dev/null
docker run --rm -d --name mysql2 -p 6606:3306 --network testjob -v /appLogs/mysql/log:/logs -v /git/jk-demo/deploy/mysql/conf:/etc/mysql -v /mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=dsfgzxczsdfasefrasd234 mysql:5.5 
docker stop jkDemo 2>/dev/null
docker run --rm -d --name jkDemo -e containerName=jkDemo --network testjob -v /appLogs/jkDemo:/log -v /git/jk-demo:/app -w /app 892280082/pm2:v2 pm2-runtime dist/index.js
docker stop jkDemo2 2>/dev/null
docker run --rm -d --name jkDemo2 -e containerName=jkDemo2 --network testjob -v /appLogs/jkDemo2:/log -v /git/jk-demo:/app -w /app 892280082/pm2:v2 pm2-runtime dist/index.js
if [ ! -e /git/jk-demo/deploy/nginx/nginx.conf ]; then
	echo 'git: /git/jk-demo/deploy/nginx/nginx.conf path not exist '
	exit 1
fi
if [ ! -e /git/jk-demo/deploy/nginx/conf ]; then
	echo 'git: /git/jk-demo/deploy/nginx/conf path not exist '
	exit 1
fi
docker stop nginx2 2>/dev/null
docker run --rm -d --name nginx2 -p 80:80 --network testjob -v /appLogs/nginx/log:/var/log/nginx/ -v /git/jk-demo/deploy/nginx/conf:/etc/nginx/conf.d -v /git/jk-demo/deploy/nginx/nginx.conf:/etc/nginx/nginx.conf frekele/nginx:1.10.3 
docker ps

4.项目结果分析

  • 4.1 部署APP依赖自动安装,无需设置服务器环境。

例如调用git.cloneAPI,会自动脚本安装依赖。(支持自动向上搜索多级依赖,无需调用者关心)

if [ ! $(command -v docker) ]; then
	curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun
fi
  • 4.2 脚本安全检查,防止误挂载。 例如执行jkDemo.safeJoin('deploy/nginx/conf')这段代码,脚本会自动生成校验代码,防止空挂载
# 执行jkDemo.safeJoin('deploy/nginx/conf')生成
if [ ! -e /git/jk-demo/deploy/nginx/nginx.conf ]; 
    then echo 'git: /git/jk-demo/deploy/nginx/nginx.conf path not exist ' 
    exit 1 
fi
  • 4.3 快速实现部署app
//必填参数
export type NginxOption = {
  logDir: string;
  configFile: string;
  configDir: string;
};
//实现一个start方法即可。
export class Nginx extends DockerServeApp {
  public start(op: DockerServerOption & NginxOption): void {
    this.stop(op.containerName);
    this.getHelperFromOption(op)
      .ammount(op.logDir, '/var/log/nginx/')
      .ammount(op.configDir, '/etc/nginx/conf.d')
      .ammount(op.configFile, '/etc/nginx/nginx.conf')
      .excute();
  }
  //运行镜像 可以通过DockerServerOption覆盖
  getImageName(): string {
    return 'frekele/nginx:1.10.3';
  }
  printVersion(): void {}
}