Before I say it, put the address cycle.bucai.cc/ first , the development environment is running, it is a bit slow, please wait patiently for loading.
GitHub: github.com/notbucai/cb…
This is a record of my attempt to use a process-based approach to project development and implementation.
As for why the existing and perfect framework on the market is not applicable, it is because I haven't written a complete and meaningful thing for a long time, and of course I will still "learn" from some mature projects.
design
source of demand
Recently, I have been intermittently proud to upgrade and optimize the blog function points. The project is divided into the background nestjs project, the foreground nuxtjs, and the management system vue.js. The current deployment method uses Docker to compile the local image and push it to the private warehouse before entering the server. Restart after pull. There is also multi-person collaborative development. Everyone needs to install the server environment (Docker, etc.) locally to ensure environment consistency.
It is not difficult to find from the above description:
- The compilation methods cannot be unified due to differences in the templates, languages, and states (static, services) used by the project after deployment.
- Repetitive issues with the current manual deployment process.
- The server environment needs to be matched, and the local development computer configuration requirements are high.
target expectations
- Project deployment templates, and different templates can be selected for packaging according to different types.
- Transition manual deployments to automated deployments.
- Depends on branch monitoring, push automatically triggers deployment, and solves high local configuration requirements.
research
Because most people need this tool in their daily work, the survey is simply explained.
Research objectives: Netlify (foreign), Tencent Cloud Webify (domestic).
what problems do they solve
- Deploy the resource.
- CI/CD workflow.
their disadvantages (Forcibly increase the height of the current project)
- Netlify abroad, dddd.
- Webify cloud manufacturers conduct operation and maintenance, and start to cut leeks when they are not guaranteed.
demand analysis
Through the above content, it is very intuitive to obtain the required function points of the project.
core analysis
The core function is to operate "task" as a unit, create tasks and manage tasks.
The so-called "task" means that the state needs to be transferred. At present, tasks are divided into in-progress, failed, and stopped.
Each trigger should generate a subtask, and if there is an ongoing subtask at the time of triggering, it should stop and start a new task.
进行中的任务包含子状态:编译中、编译成功、编译失败。 用户交互以及核心环节请看下方流程图。
功能设计
-
创建任务
主要对某个仓库的分支进行webhook的注册,并将任务信息写入数据库。
-
管理任务
主要对创建后的任务信息进行管理,删除、暂停、开始。
-
开始
对暂停的任务继续进行。
-
暂停
对正在进行中的任务进行。
-
删除
删除此条数据,并删除webhook。
-
-
任务执行
通过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
作为前端布局样式组件。
其在交互上主要分为三步:
-
选择托管平台
github、gitee等平台,选择的托管平台必须是授权登录过的。
-
输入信息
输入任务所必须的数据字段
-
确认信息
确认输入的是否符合要求
由于设计比较简单,直接以图片形式展示。
任务列表字段:任务名称/ID、托管平台、模版、状态、创建人、创建时间、更新时间、操作时间。
详情页
数据库设计
只展示核心表的设计
用户表
托管平台表
模版表
任务表
子任务表
接口设计
包含crud,直接查看接口文档:
技术选型
选择的方案的标准是 我会
、简单
。
目前选择egg + mysql + redis + vue
架构,编码尽量ts化。其他框架也考虑过比如nestjs、koa,相对而言nest太大了,koa又太小了,选 vue 其实只是想试一下3.x的版本。
eggjs: 为企业级框架和应用而生。
vue: 懂得都懂。
项目架构
架构很简单,就是存储配合依赖进行触发。
服务器运维架构
独立当前应用,用户可共享自己的服务并独立运行(隔离),原则上每个用户都可以申请一些存储与其他资源(待定),不过仍然建议使用远程/第三方资源。
编译/部署 触发 流程
是否编译:有些node项目是不需要编译的步骤
是否运行:静态资源不需要运行,直接打到nginx中即可
实现
核心功能实现(暂时只做实现 github 相关业务,其他平台预留接口)。
绑定托管平台
引用阮一峰一图,一文,绑定流程基本上就是浏览器重定向,后返回code,拿到code换token,然后将token保存。
获取相关信息
通过以下api进行操作
创建任务
创建任务写入 webhook。
任务执行
等待webhook回调
任务执行相关模版每次触发都执行,使用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')
进行镜像的构建。
Use exec(docker cp $(docker create --rm ${imageName}):/app/${buildPath} ./dist)
to copy the data in the container to the host.
Use docker-compose down
to stop an existing mirror image.
Use 'docker-compose restart
the restart of the image container.
Use docker-compose up
the boot-compiled image.