从前端到全栈:Jenkins 自动化部署 Node.js后端+ Vue.js 前端

引言

  • 前情提要:上一篇文章介绍了如何用Docker运行一个Node.js + MySQL 后端和两个 Vue.js 前端项目。但是项目上传到服务器还是使用原始的文件上传。
  • 选择Jenkins:比较知名的CI/CD方案有Jenkins和GitLab CI/CD、GitHub Actions,我们先选择用Jenkins,后续再尝试GitLab CI/CD等方案。

方案设计

1,创建Jenkins容器,Jenkins容器可以控制宿主机docker。

2,创建3个构建任务。分别是cms-web-vue任务、cms-front-vue任务、cms-server-node任务。

3,3个构建任务构建5个容器,如下图展示。

4,容器启动后协同工作。工作方式如下所示。

Jenkins 安装与配置

  • 安装 Jenkins
javascript 复制代码
// 拉取jenkins镜像
sudo docker pull jenkins/jenkins:lts

// 创建卷目录,这会是jenkins的工作目录
sudo mkdir -p /var/jenkins_home // 创建卷目录
sudo chmod 755 /var/jenkins_home // 更改目录权限

// 创建 Jenkins 容器
sudo docker run -d \
  -p 8080:8080 \
  -p 50000:50000 \
  --name jenkins \
  -v /var/jenkins_home:/var/jenkins_home \
  -v /var/run/docker.sock:/var/run/docker.sock \    
  jenkins/jenkins:lts

// 获取初始管理员密码
sudo docker exec jenkins cat /var/jenkins_home/secrets/initialAdminPassword

// 可以通过服务器ip:8080访问到jenkins,输入初始管理员密码,就可以看到jenkins管理页面了

解释创建 Jenkins 容器命令:

  • docker run -d:以守护进程模式(后台)运行容器。
  • -p 8080:8080:将主机的 8080 端口映射到容器的 8080 端口,这是 Jenkins Web 界面的默认端口。
  • -p 50000:50000:将主机的 50000 端口映射到容器的 50000 端口,用于连接 Jenkins 从节点(如果你配置了分布式构建)。
  • --name jenkins:为容器指定一个名称 "jenkins"。
  • -v /var/jenkins_home:/var/jenkins_home:将主机的/var/jenkins_home目录挂载到容器的/var/jenkins_home目录,确保 Jenkins 的数据持久化,即使容器被删除或重启,数据仍然保留。
  • -v /var/run/docker.sock:/var/run/docker.sock:将主机的 Docker 套接字文件挂载到容器中,这允许 Jenkins 容器内的 Jenkins 实例直接与 Docker 引擎通信。这通常用于在 Jenkins 中运行 Docker 命令,例如构建 Docker 镜像或启动 Docker 容器。
  • jenkins/jenkins:lts:指定要运行的 Jenkins 镜像和版本。

创建Jenkins构建任务

  • 在 Jenkins 的主页上,点击左侧菜单中的"新建任务"或"New Item"。
  • 在弹出的窗口中,输入任务名称,比如 cms-web-vue
  • 选择"Pipeline"作为项目类型,然后点击"确定"按钮。
  • 滚动到页面底部,找到"Pipeline"选项卡。
  • 在"Definition"下拉菜单中选择"Pipeline script"。
  • 将你提供的 Pipeline 脚本粘贴到"Script"文本框中。

下面是我的三个任务的Pipeline 脚本。

cms-web-vue任务:任务会执行pipeline脚本,脚本执行了三个阶段,拉取代码、构建镜像、启动容器。

typescript 复制代码
pipeline {
    agent any

    stages {
        stage('Checkout') {
            steps {
                git branch: 'main', url: 'https://gitee.com/DaBuChen/cms-web-vue.git'
            }
        }
        
        stage('Build Docker Image') {
            steps {
                script {
                    // 构建 Docker 镜像
                    def imageName = 'cms-server-node-frontend-web:latest' // 替换为您的镜像名称
                    sh "docker build -t ${imageName} ."
                }
            }
        }
        
        stage('Run Docker Container') {
            steps {
                script {
                    // 停止并删除旧容器(如果存在)
                    try {
                        sh "docker stop cms-server-node-frontend-web" // 替换为您的容器名称
                        sh "docker rm cms-server-node-frontend-web"
                    } catch (Exception e) {
                        echo "No existing container to stop or remove."
                    }
                    
                    // 运行新的 Docker 容器
                    sh "docker run -d --name cms-server-node-frontend-web --network my-custom-network cms-server-node-frontend-web:latest" // 替换为您的镜像名称
                }
            }
        }
    }

    post {
        always {
            // 可选:清理工作区
            cleanWs()
        }
    }
}

提示:我的项目原先托管再github,但是服务器访问外网经常访问不到,所以将项目托管到了gitee。

cms-front-vue任务:与cms-web-vue任务类似。

typescript 复制代码
pipeline {
    agent any

    stages {
        stage('Checkout') {
            steps {
                git branch: 'main', url: 'https://gitee.com/DaBuChen/cms-front-vue.git'
            }
        }
        
        stage('Build Docker Image') {
            steps {
                script {
                    // 构建 Docker 镜像
                    def imageName = 'cms-server-node-frontend-manage:latest' // 替换为您的镜像名称
                    sh "docker build -t ${imageName} ."
                }
            }
        }
        
        stage('Run Docker Container') {
            steps {
                script {
                    // 停止并删除旧容器(如果存在)
                    try {
                        sh "docker stop cms-server-node-frontend-manage" // 替换为您的容器名称
                        sh "docker rm cms-server-node-frontend-manage"
                    } catch (Exception e) {
                        echo "No existing container to stop or remove."
                    }
                    
                    // 运行新的 Docker 容器
                    sh "docker run -d --name cms-server-node-frontend-manage --network my-custom-network cms-server-node-frontend-manage:latest" // 替换为您的镜像名称
                }
            }
        }
    }

    post {
        always {
            // 可选:清理工作区
            cleanWs()
        }
    }
}

cms-server-node任务:除了启动nodejs服务外,还需要启动mysql和nginx容器。

python 复制代码
pipeline {
    agent any

    stages {
        stage('Checkout') {
            steps {
                git branch: 'main', url: 'https://gitee.com/DaBuChen/cms-server-node.git'
            }
        }
        
        stage('Build and Run Nginx') {
            steps {
                script {
                    // 检查是否存在名为 my-nginx 的容器,如果存在则停止并删除
                    sh """
                    if [ $(docker ps -a -q -f name=my-nginx) ]; then
                        docker stop my-nginx
                        docker rm my-nginx
                    fi
                    """
        
                    // 构建并运行 Nginx 容器,挂载 nginx.conf
                    sh """
                    docker run -d --name my-nginx \
                    -p 80:80 \
                    -v /var/lib/docker/volumes/jenkins_home/_data/workspace/cms-server-node/nginx.conf:/etc/nginx/nginx.conf:ro \
                    --network my-custom-network \
                    nginx:latest
                    """
                }
            }
        }
        
        stage('Build and Run MySQL') {
            steps {
                script {
                    // 检查是否存在名为 my-mysql 的容器,如果存在则停止并删除
                    sh """
                    if [ $(docker ps -a -q -f name=my-mysql) ]; then
                        docker stop my-mysql
                        docker rm my-mysql
                    fi
                    """
                    
                    // 构建并运行 MySQL 容器,初始化数据库
                    sh """
                    docker run -d --name my-mysql \
                    -p 3306:3306 \
                    -e MYSQL_ROOT_PASSWORD=12345678 \
                    -e MYSQL_DATABASE=cms \
                    -e MYSQL_USER=admin \
                    -e MYSQL_PASSWORD=12345678 \
                    -v mysql-data:/var/lib/mysql \
                    -v /var/lib/docker/volumes/jenkins_home/_data/workspace/cms-server-node/db/backup.sql:/docker-entrypoint-initdb.d/backup.sql:ro \
                    --network my-custom-network \
                    mysql:8.0
                    """
                }
            }
        }
        
        stage('Build Docker Image') {
            steps {
                script {
                    // 构建 Docker 镜像
                    def imageName = 'cms-server-node-backend:latest' // 替换为您的镜像名称
                    sh "docker build -t ${imageName} ."
                }
            }
        }
        
        stage('Run Docker Container') {
            steps {
                script {
                    // 停止并删除旧容器(如果存在)
                    try {
                        sh "docker stop cms-server-node-backend" // 替换为您的容器名称
                        sh "docker rm cms-server-node-backend"
                    } catch (Exception e) {
                        echo "No existing container to stop or remove."
                    }
                    
                    // 运行新的 Docker 容器
                    sh "docker run -d --name cms-server-node-backend --network my-custom-network cms-server-node-backend:latest" // 替换为您的镜像名称
                }
            }
        }
        
    }

    post {
        always {
            // 可选:清理工作区
            cleanWs()
        }
    }
}

三个任务如下展示:

配置Jenkins Webhook

配置Webhook可以让我们在提交代码时触发Jenkins进行部署。我以 cms-web-vue 项目为例配置。

1. 在 Jenkins 中配置 Gitee 插件

首先,确保您的 Jenkins 安装了 Gitee 相关的插件,例如 "Generic Webhook Trigger" 插件。您可以通过以下步骤安装插件:

  • 在 Jenkins 的管理界面中,点击 "Manage Jenkins"。
  • 选择 "Manage Plugins"。
  • 在 "Available" 标签页中搜索 "Generic Webhook Trigger" 并安装它。

2. 配置 Jenkins Job 以响应 Webhook

  • 在配置页面,找到 "Build Triggers" 部分,勾选 "Generic Webhook Trigger"。
  • 设置token。这里我设置为cms-web-vue。

3. 配置 Webhook URL

在 Jenkins Job 中,您需要配置一个 Webhook URL。通常这个 URL 格式如下:

ini 复制代码
http://<your-jenkins-server>:<port>/generic-webhook-trigger/invoke?token=cms-web-vue

请确保您的 Jenkins 服务器可以通过公网访问,或者您可以使用工具如 ngrok 来创建一个临时的公网 URL。

4. 在 Gitee 上设置 Webhook

  1. 登录到您的 Gitee 帐户并导航到您的项目。
  2. 点击 "管理"。
  3. 在左侧菜单中选择 "Webhook"。
  4. 点击 "添加 Webhook"。
  5. 在 "请求地址" 中输入 Jenkins 的 Webhook URL。
  6. 选择触发事件,例如 "Push events" 或 "Tag push events"。
  7. 保存 Webhook。

5. 测试 Webhook

在 Gitee 中进行一次代码推送或其他触发事件,查看 Jenkins 是否正确响应并开始构建。

总结

这篇文章中我们介绍了用Jenkins方案来实现我们全栈项目的CI/CD。但是我的方案应该和公司正规方案还有区别。Jenkins应该会独立的在一个服务器,将镜像打包好后在传输到生产服务器上。同样我的这次实践页足够的简陋,后续希望自己能不断的完善自己的部署方案。同时尝试其他的CI/CD方案。

相关推荐
希望奇迹很安静1 小时前
CTFSHOW-WEB入门-命令执行29-32
前端·web安全·ctf
钢铁男儿1 小时前
列表(列表是什么)
服务器·前端·数据库
Ronin-Lotus3 小时前
程序代码篇---Python随机数
前端·python·学习·随机数
Y编程小白4 小时前
ECMAScript--promise的使用
开发语言·前端·ecmascript
Bigger5 小时前
Tauri(十)—— 生产环境调试指南
前端·rust·electron
朦胧之6 小时前
Expo 框架开发移动应用
前端·react native
浪遏6 小时前
NestJs👈 | 前端spring🤔| 项目创建与项目结构解析
前端·javascript·后端
我命由我123457 小时前
前端性能优化指标 - DCL(触发时机、脚本对 DCL 的影响、CSS 对 DCL 的影响)
开发语言·前端·javascript·css·性能优化·html·js
轻口味7 小时前
Vue.js 什么是 Vuex?
前端·javascript·vue.js