设计并实现一个简单自动化部署工具

不才
• 阅读 801

说之前先放地址 https://cycle.bucai.cc/,开发环境运行的,有点慢请耐心等待加载。

GitHub: https://github.com/notbucai/cb-cycle

这是我尝试用流程化的思路进行项目开发实现的记录。

至于为什么不适用市面上现有且完善的框架,是因为我好久没写完整且有意义的东西了,当然依然会“借鉴”一些成熟的项目。

设计

需求来源

近期间歇性踌躇满志的对博客功能点进行升级、优化,该项目分为后台nestjs项目、前台nuxtjs、管理系统vue.js,目前部署方式采用Docker进行本地的镜像编译后push到私有仓库后再进入服务器pull之后重启。还有是多人协作开发每个人都需要在本地安装服务器环境(Docker等)来确保环境一致性。

通过上述描述不难发现:

  1. 由于项目使用的模版、语言以及部署后的状态(静态、服务)都有区别导致编译方式无法统一。
  2. 目前的手动部署流程的重复性问题。
  3. 需要匹配服务器环境,本地开发电脑配置要求高。

目标期望

  1. 项目部署模版化,针对不同类型可选择不同模板进行打包。
  2. 将手动部署过渡成自动化部署。
  3. 依赖分支监控,push自动触发部署,解决本地配置要求高。

调研

因为大多数人平时工作中都接触是有需要这套工具的,所以调研简单说明。

调研目标:Netlify(国外)、腾讯云Webify(国内)。

它们解决了什么问题

  1. 将资源进行部署。
  2. CI/CD 工作流。

它们的缺点(强行提高现在所做的项目高度

  1. Netlify 国外,dddd。
  2. Webify云厂商进行运维,保不齐什么时候就开始割韭菜。

需求分析

通过上述内容很直观的得到项目需要功能点。

核心分析

核心功能是以“任务”为单元进行操作,创建任务和管理任务。

所谓“任务”即需要对状态进行流转的,目前任务分为 进行中、失败、已停止。

每次触发都应该生成一个子任务,如果触发时有进行中的子任务应当停止后启用新任务。

进行中的任务包含子状态:编译中、编译成功、编译失败。 设计并实现一个简单自动化部署工具 用户交互以及核心环节请看下方流程图。 设计并实现一个简单自动化部署工具

功能设计

  1. 创建任务

    主要对某个仓库的分支进行webhook的注册,并将任务信息写入数据库。

  2. 管理任务

    主要对创建后的任务信息进行管理,删除、暂停、开始。

    1. 开始

      对暂停的任务继续进行。

    2. 暂停

      对正在进行中的任务进行。

    3. 删除

      删除此条数据,并删除webhook。

  3. 任务执行

    通过webhook触发执行,找到当前数据进行执行。

任务执行设计

如何不同配置进行不同的编译/运行方式?

所有编译都采用docker进行隔离编译,运行根据不同类型进行选择不同的方式。

目前区分两种类型,一种是静态、一种是动态:

  • 静态:采用采用docker编译后上传cdn方式,当然只是模拟暂只放nginx静态目录中。
  • 动态:使用docker编译后docker运行。
web service
无需端口 端口
nginx 转发资源 nginx 转发端口
可能需要编译 可能需要编译
不需要容器运行 需要容器运行
动作 spa项目 普通网页 Ts node 项目 普通node项目
构建
编译
运行

上方从资源类型和项目类型进行对比,直观的表达了任务的执行动作。

静态资源(web)容器构建后,通过docker cp 将镜像中dist数据copy到主机中,然后转移到nginx中。

服务资源(service)容器构建编译后,再运行起来,然后添加nginx将容器映射到机器端口上。

端口后续进行维护,容器内端口不做管理,靠nginx容器进行映射维护。

用户自己的任务容器之间可以相互通信,通过任务id即可访问,如果是静态资源需要访问后续通过配置将接口进行转发,同时用户可以绑定自己的域名到当前机器上。

页面设计

前端采用naive-ui作为前端布局样式组件。

其在交互上主要分为三步:

  1. 选择托管平台

    github、gitee等平台,选择的托管平台必须是授权登录过的。

  2. 输入信息

    输入任务所必须的数据字段

  3. 确认信息

    确认输入的是否符合要求

由于设计比较简单,直接以图片形式展示。

设计并实现一个简单自动化部署工具

设计并实现一个简单自动化部署工具

任务列表字段:任务名称/ID、托管平台、模版、状态、创建人、创建时间、更新时间、操作时间。

设计并实现一个简单自动化部署工具

详情页

设计并实现一个简单自动化部署工具

数据库设计

只展示核心表的设计

设计并实现一个简单自动化部署工具

用户表

设计并实现一个简单自动化部署工具

托管平台表

设计并实现一个简单自动化部署工具

模版表

设计并实现一个简单自动化部署工具

任务表

设计并实现一个简单自动化部署工具

子任务表

设计并实现一个简单自动化部署工具

接口设计

包含crud,直接查看接口文档:

https://www.apifox.cn/apidoc/project-741496/api-14138505

技术选型

选择的方案的标准是 我会简单

目前选择egg + mysql + redis + vue架构,编码尽量ts化。其他框架也考虑过比如nestjs、koa,相对而言nest太大了,koa又太小了,选 vue 其实只是想试一下3.x的版本。

eggjs: 为企业级框架和应用而生。

vue: 懂得都懂。

项目架构

架构很简单,就是存储配合依赖进行触发。

设计并实现一个简单自动化部署工具

服务器运维架构

设计并实现一个简单自动化部署工具

独立当前应用,用户可共享自己的服务并独立运行(隔离),原则上每个用户都可以申请一些存储与其他资源(待定),不过仍然建议使用远程/第三方资源。

编译/部署 触发 流程

设计并实现一个简单自动化部署工具

是否编译:有些node项目是不需要编译的步骤

是否运行:静态资源不需要运行,直接打到nginx中即可

实现

核心功能实现(暂时只做实现 github 相关业务,其他平台预留接口)。

项目进度查看

设计并实现一个简单自动化部署工具

绑定托管平台

设计并实现一个简单自动化部署工具 引用阮一峰一图,一文,绑定流程基本上就是浏览器重定向,后返回code,拿到code换token,然后将token保存。

获取相关信息

通过以下api进行操作

用户储存库列表

获取分支列表

获取指定文件内容

创建任务

创建任务写入 webhook。

创建webhook

任务执行

等待webhook回调

https://docs.github.com/cn/developers/webhooks-and-events/webhooks/testing-webhooks

任务执行相关模版每次触发都执行,使用ejs进行配置渲染生成。

// 注入内容
{
  user, // 数据库user model
  task, // 数据库task model
  taskChild, // 数据库task_child model
  template, // 数据库template
  path: {
    ...path, // 相关路径
    code: relativeCodePath // 代码与配置的相对位置
  }
}
# dock er file
FROM node:12.18.2

LABEL maintainer="<%= user.id %><<%= user.email %>>"

ADD <%= path.code %> /app/

WORKDIR /app

RUN rm -rf node_modules

RUN rm -rf <%= path.build %>

RUN npm config set sharp_binary_host https://npm.taobao.org/mirrors/sharp

RUN npm config set sharp_libvips_binary_host https://npm.taobao.org/mirrors/sharp-libvips

RUN npm config set sass_binary_site https://npm.taobao.org/mirrors/node-sass

RUN npm install --registry https://registry.npm.taobao.org --max-old-space-size=4096

ENV NODE_ENV production

<% if (template.is_build) { %>
RUN npm run <%= task.build_script %>
<% } %>

<% if (template.is_run) { %>
EXPOSE <%= task.server_port %>

CMD  nohup sh -c 'npm run <%= task.run_script %>'
<% } %>
# docker compose config
version: "3.7"

services:
  "<%= task.id %>":
    build: .
    image: <%= task.id %>:<%= taskChild.version || '0.0.1' %>
    container_name: <%= task.id %>
    restart: always
<% if (template.is_run) { %>
    networks:
      <%= user.id %>-network:
        ipv4_address: <%= task.ip %>

networks:
  <%= user.id %>-network:
    external: true
<% } %>

构建/编译/运行 相关

node child_process exec进行命令执行:

使用 exec('docker-compose build')进行镜像的构建。

使用 exec(docker cp $(docker create --rm ${imageName}):/app/${buildPath} ./dist)将容器内数据copy到主机中。

使用docker-compose down将已有镜像镜像停止。

使用'docker-compose restart镜像容器的重启。

使用docker-compose up启动编译好的镜像。

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
4个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Stella981 Stella981
3年前
KVM调整cpu和内存
一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid
Stella981 Stella981
3年前
Android So动态加载 优雅实现与原理分析
背景:漫品Android客户端集成适配转换功能(基于目标识别(So库35M)和人脸识别库(5M)),导致apk体积50M左右,为优化客户端体验,决定实现So文件动态加载.!(https://oscimg.oschina.net/oscnet/00d1ff90e4b34869664fef59e3ec3fdd20b.png)点击上方“蓝字”关注我
Easter79 Easter79
3年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
为什么mysql不推荐使用雪花ID作为主键
作者:毛辰飞背景在mysql中设计表的时候,mysql官方推荐不要使用uuid或者不连续不重复的雪花id(long形且唯一),而是推荐连续自增的主键id,官方的推荐是auto_increment,那么为什么不建议采用uuid,使用uuid究
Python进阶者 Python进阶者
10个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这