diff --git a/README.md b/README.md index 8eddf89..2f48e4f 100644 --- a/README.md +++ b/README.md @@ -13,16 +13,16 @@ ![架构图](./doc/jgt.png) + ## CI/CD 自动化集群部署 -![cicd](./doc/cicd.png) +![cicd](./doc/newci.png) ## 开发日记 - [x] 基于DDD理念改造 - [x] 拆分领域模块为联邦模块,实现微前端 - [x] 基于 Vue3+OOP+JSX 改造项目代码 -- [ ] 开发Nacos的config-service实现代理访问Nacos服务 - [x] 基于 Nacos 开发 nacos-federation 插件,实现各模块的服务注册&发现,统一管理远程地址 - [x] 修改 nacos-federation 插件实现其成为vite的插件,进一步简化代码! - [x] 修改 nacos-federation 插件,实现 接口请求基地址从 配置中心获取,并注入到环境变量中 @@ -32,7 +32,7 @@ - [x] 将vite.config.ts中的base 改到插件 nacos-federation中实现,简化代码 - [x] 增加控制台日志,方便访问各种服务 - [x] pnpm 统一管理集中项目依赖,运行&构建等 -- [ ] 领域模块实现 docker 自动化构建部署上线 +- [x] 领域模块实现 docker 自动化构建部署上线 - [ ] Deno集成GraphQL - [ ] .... - [ ] 爬快手api,实现一个完整项目,测试脚手架不足 @@ -254,4 +254,4 @@ export default class Header extends TSX()(Vue) implements Props { **前端工作:** -详细请看 **front-end/xxx/README.md** 内的帮助文档!!! +详细请看 [app-product的README.md](./front-end/app-product/README.md) 内的帮助文档!!! diff --git a/doc/cicd.png b/doc/cicd.png deleted file mode 100644 index 0940588..0000000 Binary files a/doc/cicd.png and /dev/null differ diff --git a/doc/newci.png b/doc/newci.png new file mode 100644 index 0000000..fc97fa9 Binary files /dev/null and b/doc/newci.png differ diff --git a/doc/临时命令.md b/doc/临时命令.md new file mode 100644 index 0000000..3e9c040 --- /dev/null +++ b/doc/临时命令.md @@ -0,0 +1,20 @@ +# 包含 [skip actions] 的提交会跳过工作流 +git commit -m "修复样式问题 [skip actions]" + + +```bash +# 运行自动化集群部署脚本 +./docker/deploy-swarm.sh + +# --- 其他命令 --- + +# 删除之前的部署(可选) +docker stack rm app-product + +# 查看 app-product 集群运行情况 +docker stack ps app-product + +# 持续观察服务副本数是否达到预期 +watch docker stack services app-product +``` + diff --git a/front-end/app-product/.gitea/workflows/build.yml b/front-end/app-product/.gitea/workflows/build.yml new file mode 100644 index 0000000..567ba82 --- /dev/null +++ b/front-end/app-product/.gitea/workflows/build.yml @@ -0,0 +1,75 @@ +name: build and push + +# 当代码推送到 main 分支时触发 +on: + push: + branches: [ main ] + +jobs: + build-and-push: + runs-on: ubuntu-latest + + steps: + - name: 拉取最新代码 + uses: actions/checkout@v4 + + - name: 设置 Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: 登录到自己的 Docker 仓库 + uses: docker/login-action@v3 + with: + registry: registry.bmycode.help + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + + - name: 构建并推送镜像 + uses: docker/build-push-action@v5 + with: + context: . + push: true + tags: | + registry.bmycode.help/app-product:latest + registry.bmycode.help/app-product:${{ github.sha }} + + + - name: 替换镜像标签为 github.sha + run: | + sed -i "s|{{IMAGE_TAG}}|${{ github.sha }}|g" app-product.yml + + - name: 上传 app-product.yml 到前端集群管理机 + uses: appleboy/scp-action@v1 + with: + host: ${{ vars.SSH_MANAGE }} + username: ${{ secrets.USERNAME }} + password: ${{ secrets.PASSWORD }} + port: ${{ secrets.PORT }} + source: "app-product.yml" + target: "/home/bmy/" + + - name: 登录前端集群,拉镜像 + uses: appleboy/ssh-action@v1 + with: + # 统一登录三台前端集群的linux,统一拉取刚推到仓库的最新镜像 + # 解决 Swarm 无法控制 工作机拉取镜像的问题! + host: ${{ vars.SSH_HOST_LIST }} + sync: true + username: ${{ secrets.USERNAME }} + password: ${{ secrets.PASSWORD }} + port: ${{ secrets.PORT }} + script: | + # 拉取刚打包的最新镜像 + docker pull registry.bmycode.help/app-product:${{ github.sha }} + + - name: 管理节点部署到 Swarm + uses: appleboy/ssh-action@v1 + with: + host: ${{ vars.SSH_MANAGE }} + sync: true + username: ${{ secrets.USERNAME }} + password: ${{ secrets.PASSWORD }} + port: ${{ secrets.PORT }} + script: | + # 切换到管理员,要不然没权限在服务器执行 docker 命令,部署到 Swarm 集群 + sudo docker stack deploy -c /home/bmy/app-product.yml app-product diff --git a/front-end/app-product/docker/Dockerfile b/front-end/app-product/Dockerfile similarity index 95% rename from front-end/app-product/docker/Dockerfile rename to front-end/app-product/Dockerfile index 41d0bab..56b3f97 100644 --- a/front-end/app-product/docker/Dockerfile +++ b/front-end/app-product/Dockerfile @@ -14,6 +14,7 @@ RUN npx vite build --base=/app-product/ FROM nginx:alpine # 构建产物放到 /usr/share/nginx/html/app-product +# nginx.conf 也需要修改 COPY --from=builder /app/dist /usr/share/nginx/html/app-product # 覆盖 Nginx 配置,支持 SPA 子路径 COPY docker/nginx.conf /etc/nginx/conf.d/default.conf diff --git a/front-end/app-product/README.md b/front-end/app-product/README.md index e7f99a1..9c5e811 100644 --- a/front-end/app-product/README.md +++ b/front-end/app-product/README.md @@ -10,7 +10,9 @@ ## 运行 -下面文档分为**开发**和**上线**两部分进行说明! +下面文档分为**开发**和**上线**两部分进行说明!**默认前端已经在电脑上安装过 Docker 环境!!** + +> 想要【开发阶段运行】,必须 先参考下面 【上线】-【任务1】配置好两个前端自己的环境变量文件!很简单! ### 开发 @@ -30,34 +32,125 @@ npm run dep ### 上线 -**docker/ 文件夹说明** -- `app-product.yml` - Dcoker Swarm 集群部署配置 -- `deploy-swarm.sh` - 自动化部署脚本 -- `docker-compose.yml` - 开发阶段容器编排 -- `Dockerfile` - 打包构建前端代码为镜像 -- `nginx.conf` - 镜像内前端被访问的Nginx配置 +代码 到 仓库的 **main 分支** 后会触发 全程自动化,实现自动打包前端代码,构建镜像,自动部署到公司内网的Linux服务器集群中! +提交到其他分支不触发自动化操作!具体什么规则,以 技术负责人 说的为准!请遵守规则! + + +**根目录核心文件说明** + +- `app-product.yml` - Dcoker Swarm 集群部署配置【不准动】 +- `docker-compose.yml` - 开发阶段容器编排【可选,不要就删除】 +- `Dockerfile` - 打包构建前端代码为镜像【根据需求改动】 +- `nginx.conf` - 镜像内前端被访问的Nginx配置【根据需求改动】 +- `act-runner.yml` - gitea action 的 runner【根据需求改动】 前端工作: -- 1: 编辑 前端 .env.development 和 .env.production 环境变量(只需修改一次) -- 2: 确认或编辑 docker/Dockerfile,docker/nginx.conf -- 3: 编辑 docker/deploy-swarm.sh +前期大致工作内容如下,改好后,以后就不用再动了,很简单: -还有很多细节未展开,后面再详细说,大致确认无误后。 -在前端集群的管理机上进入项目根目录,执行下面命令部署: +- 任务1: 编辑 前端 .env.development 和 .env.production 环境变量(只需修改一次) +- 任务2: 确认或编辑 Dockerfile,nginx.conf +- 任务3: 编辑 act-runner.yml + +--- + +详细展开说明: + +**任务1:** + +主要修改两个环境变量文件 `.env.development`,`.env.production` 中的: ```bash -# 运行自动化集群部署脚本 -./docker/deploy-swarm.sh -# --- 其他命令 --- +# 找技术负责人要 +# 情况1: 【内网模块】填写 Nacos 内网 ip 或 域名 即可 +# 情况2: 【外网模块】填写 traefik 公网 ip 或 域名 即可 +# .env.development, .env.production 中 可以不一样! +VITE_NACOS_ADDRESS=???? -# 删除之前的部署(可选) -docker stack rm app-product -# 查看 app-product 集群运行情况 -docker stack ps app-product +# 这个参数很重要,前端可以自定义填写,填写后不允许再改,填完给 技术负责人 即可 +# 微前端应用的名称,遵守 app-xxxxx +# .env.development, .env.production 中 必须一样! +VITE_SERVER_NAME=app-??? + +#【ps】其他参数看环境变量内说明 +``` + +--- + +**任务2:** + +主要修改两个 `Dockerfile`,`nginx.conf`,改起来也很简单: + + +Dockerfile 修改教程: + +```bash + + +# 将 VITE_SERVER_NAME 替换为 上一步设置的 VITE_SERVER_NAME 的 数值 即可 +RUN npx vite build --base=/VITE_SERVER_NAME/ + +# 将 VITE_SERVER_NAME 替换为 上一步设置的 VITE_SERVER_NAME 的 数值 即可 +COPY --from=builder /app/dist /usr/share/nginx/html/VITE_SERVER_NAME +``` + + +nginx.conf 修改教程: + +```bash +# 看仔细了,有三处 VITE_SERVER_NAME 需要替换成 值!! +location /VITE_SERVER_NAME/ { + alias /usr/share/nginx/html/VITE_SERVER_NAME/; + try_files $uri $uri/ /VITE_SERVER_NAME/index.html; + add_header 'Access-Control-Allow-Origin' '*'; + add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; + add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range'; + add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range'; +} +``` + +--- + +**任务3:** + +act-runner.yml 是 Gitea Action 的核心,Gitea会将Job委托给Runner来运行,**所以我们前端本地必须要先运行 act-runner.yml 文件**,这样在我们提交代码的时候 Gitea Action 的自动构建才会运行!! + +但是,运行 act-runner.yml 之前,需要先对 act-runner.yml 文件进行简单的配置: + +```bash + +# 核心 需要改动的配置 +# 可以直接让 仓库 的管理员 给你把下面参数之间配置好,当然你也可以自己配 + +# GITEA_INSTANCE_URL=这个前端项目模块的 git仓库地址 +# 格式:协议://域名 即可,例如:https://git.bmycode.help 或 https://gitee.com 等 + +# 项目仓库首页-设置-Actions-Runner 右上角可复制令牌 +# GITEA_RUNNER_REGISTRATION_TOKEN=注册令牌,来源三选一:实例,组织,全存储库 +environment: + - GITEA_INSTANCE_URL=https://git.bmycode.help + - GITEA_RUNNER_REGISTRATION_TOKEN=WFiO5JDwz7CHnk7fMGJYMcSITU81CLXuI7Ofg10e + +``` + +改好后,在**项目文件夹根目录**打开终端,通过下面命令运行 act-runner.yml 文件: + +```bash +docker-compose -f act-runner.yml up -d + +# 运行后,如果 在 docker desktop 的容器中找到 名字叫:gitea-act-runner 的容器,查看日志: + +# 有下面这行,则表示 runner 成功启动!!docker desktop 可以关闭了或者放后台,不用管了! +# level=debug msg="Successfully pinged the Gitea instance server" + +# 如果出问题了,找 技术负责人! +``` + +--- + + +**到这一步,上线 配置已经搞完,很简单吧!剩下的,你提交代码到仓库就行,项目会自动构建,自动打包发布到公司内网集群中部署和运行,不用你管了!!** + -# 持续观察服务副本数是否达到预期 -watch docker stack services app-product -``` \ No newline at end of file diff --git a/front-end/app-product/act-runner.yml b/front-end/app-product/act-runner.yml new file mode 100644 index 0000000..72febb6 --- /dev/null +++ b/front-end/app-product/act-runner.yml @@ -0,0 +1,17 @@ +version: '3.8' + +services: + gitea-actions-runner: + image: gitea/act_runner:latest + container_name: gitea-act-runner + restart: unless-stopped + volumes: + - runner-data:/data + - /var/run/docker.sock:/var/run/docker.sock + environment: + - GITEA_INSTANCE_URL=https://git.bmycode.help + - GITEA_RUNNER_REGISTRATION_TOKEN=WFiO5JDwz7CHnk7fMGJYMcSITU81CLXuI7Ofg10e + - GITEA_RUNNER_LABELS=ubuntu-latest:docker://docker.gitea.com/runner-images:ubuntu-latest + +volumes: + runner-data: diff --git a/front-end/app-product/docker/app-product.yml b/front-end/app-product/app-product.yml similarity index 96% rename from front-end/app-product/docker/app-product.yml rename to front-end/app-product/app-product.yml index 8c721ef..97e0705 100644 --- a/front-end/app-product/docker/app-product.yml +++ b/front-end/app-product/app-product.yml @@ -2,7 +2,7 @@ version: "3.8" # Docker Compose 文件版本,3.8 支持 Swarm 模式的所有 services: app-product: - image: app-product:latest + image: registry.bmycode.help/app-product:{{IMAGE_TAG}} ports: - target: 80 # 容器内部端口 published: 1301 # 宿主机对外暴露端口 diff --git a/front-end/app-product/docker/docker-compose.yml b/front-end/app-product/docker-compose.yml similarity index 79% rename from front-end/app-product/docker/docker-compose.yml rename to front-end/app-product/docker-compose.yml index e7a4191..3425db9 100644 --- a/front-end/app-product/docker/docker-compose.yml +++ b/front-end/app-product/docker-compose.yml @@ -6,7 +6,7 @@ services: context: .. dockerfile: docker/Dockerfile - image: app-product:1.0.0 + image: registry.bmycode.help/app-product:latest container_name: app-product ports: - "1301:80" diff --git a/front-end/app-product/docker/deploy-swarm.sh b/front-end/app-product/docker/deploy-swarm.sh deleted file mode 100755 index 6758c5a..0000000 --- a/front-end/app-product/docker/deploy-swarm.sh +++ /dev/null @@ -1,100 +0,0 @@ -#!/bin/bash -# deploy-swarm.sh - -set -e - -# 仓库用户名 -USER_NAME="bmy" -# 仓库密码 -USER_PASSWORD="lb714500." -# 仓库地址 -REGISTRY="registry.bmycode.help" -# 镜像名称 -IMAGE_NAME="${REGISTRY}/app-product" -# tag 标签 -TAG="v$(date +%Y%m%d-%H%M%S)" -# 完整路径 -FULL_IMAGE="${IMAGE_NAME}:${TAG}" -# 工作服务器列表(多个服务器) -WORKER_HOSTS=("192.168.139.120" "192.168.139.242") -WORKER_USER="root" -WORKER_PASSWORD="lb714500." - -echo "=== 1 登录私有镜像仓库 ===" -if ! echo "${USER_PASSWORD}" | docker login ${REGISTRY} -u ${USER_NAME} --password-stdin; then - echo "错误: 无法登录到私有仓库 ${REGISTRY}" - exit 1 -fi - -echo "=== 2 构建 app-product 镜像 ===" -docker build \ - -f docker/Dockerfile \ - -t ${FULL_IMAGE} \ - -t ${IMAGE_NAME}:latest \ - . - -echo "=== 3 推送镜像到私有仓库 ===" -docker push ${FULL_IMAGE} -docker push ${IMAGE_NAME}:latest - -echo "=== 4 在工作服务器上拉取最新镜像 ===" -for WORKER_HOST in "${WORKER_HOSTS[@]}"; do - echo "" - echo "正在连接到工作服务器: ${WORKER_HOST}" - - if sshpass -p "${WORKER_PASSWORD}" ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null ${WORKER_USER}@${WORKER_HOST} " - echo '在工作服务器 ${WORKER_HOST} 上登录私有仓库...' - if echo '${USER_PASSWORD}' | docker login ${REGISTRY} -u ${USER_NAME} --password-stdin; then - echo '拉取最新镜像...' - docker pull ${FULL_IMAGE} - docker pull ${IMAGE_NAME}:latest - echo '镜像拉取完成' - - - echo '清理旧的 app-product 镜像...' - # 删除除了本次 FULL_IMAGE 和 latest 之外的所有 app-product 镜像 - docker images ${IMAGE_NAME} --format 'table {{.Repository}}:{{.Tag}}' | \ - grep -v '${FULL_IMAGE}' | \ - grep -v '${IMAGE_NAME}:latest' | \ - grep '${IMAGE_NAME}' | \ - xargs -r docker rmi -f || true - - else - echo '错误: 无法在工作服务器上登录私有仓库' - exit 1 - fi - "; then - echo "✓ 服务器 ${WORKER_HOST} 镜像拉取成功" - else - echo "✗ 服务器 ${WORKER_HOST} 镜像拉取失败" - exit 1 - fi -done - -echo "=== 5 更新 docker-compose 文件中的镜像标签 ===" -sed "s|image: app-product:latest|image: ${FULL_IMAGE}|g" docker/app-product.yml > docker/app-product-deploy.yml - -echo "=== 6 部署到 Swarm 集群 ===" -docker stack deploy -c docker/app-product-deploy.yml app-product - -echo "=== 7 恢复原始配置文件 ===" -rm -f docker/app-product-deploy.yml - -echo "=== 8 清理本地多余镜像 ===" -# 清理本地:删除除了本次 FULL_IMAGE 和 latest 之外的所有 app-product 镜像 -echo "清理本地旧的 app-product 镜像..." -docker images ${IMAGE_NAME} --format 'table {{.Repository}}:{{.Tag}}' | \ -grep -v "${FULL_IMAGE}" | \ -grep -v "${IMAGE_NAME}:latest" | \ -grep "${IMAGE_NAME}" | \ -xargs -r docker rmi -f || true - -# 清理悬空镜像 -docker image prune -f - - - -echo "=== 9 验证部署状态 ===" -docker stack ps app-product - -echo "=== 部署完成 ===" \ No newline at end of file diff --git a/front-end/app-product/docker/nginx.conf b/front-end/app-product/nginx.conf similarity index 99% rename from front-end/app-product/docker/nginx.conf rename to front-end/app-product/nginx.conf index 2cf8e7a..bd5a27d 100644 --- a/front-end/app-product/docker/nginx.conf +++ b/front-end/app-product/nginx.conf @@ -2,6 +2,7 @@ server { listen 80; server_name *.ddd.com; + location /app-product/ { alias /usr/share/nginx/html/app-product/; try_files $uri $uri/ /app-product/index.html;