源码: 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 {}
}