
GiteaJenkinsDocker 搭建 Node 项目 CI/CD 自动部署完整教程整体架构前置条件把4个文件上传到Gitea仓库根目录确认Jenkins前置条件Jenkins容器必须挂载docker.sockJenkins 安装插件配置 Jenkins 凭证创建Jenkins流水线任务创建流水线流水线配置触发器配置自动触发构建Gitea Webhook配置介绍CI Continuous Integration持续集成。频繁把多个人写的代码合并到同一个仓库自动做校验仓库收到代码提交自动执行拉代码 → 安装依赖 → 单元测试 → 构建镜像。CD : Continuous Deployment持续部署.CI 做完构建出镜像之后自动部署到服务器启动容器对外提供服务;部署容器自动停止旧容器、删除旧容器、启动新版本容器.总结CI代码提交 → 自动构建 自动测试验证代码能不能用CD测试通过 → 自动打包部署上线把新版本服务跑起来整体架构开发者 push 代码↓Gitea 仓库代码托管↓ Webhook 推送JenkinsCI/CD 流水线调度├─ 1. 拉取代码├─ 2. 构建 Docker 镜像├─ 3. 推送镜像到 Harbor或本地保留└─ 4. SSH 登录部署服务器 / 本机 docker-compose 部署↓目标服务器运行容器↓访问 http://服务器IP:3001前置条件DockerDokcer部署及使用GiteaGitea部署及使用JenkinsJenkins部署及使用把4个文件上传到Gitea仓库根目录.dockerignorenode_modules .gitapp.jsconst expressrequire(express);const appexpress();const port3000;// 版本号后续改这里即可 const versionv1.2;app.get(/,(req, res){// 返回HTML页面 res.send(!DOCTYPE htmlhtmllangzh-CNheadmetacharsetUTF-8titleCI/CD 演示页面/titlestyle*{margin:0;padding:0;box-sizing: border-box;font-family:Microsoft Yahei, sans-serif;}body{background-color:#f0f4f8;display: flex;align-items: center;justify-content: center;height: 100vh;}.card{background:#ffffff;padding: 40px 60px;border-radius: 16px;box-shadow:08px 24px rgba(0,0,0,0.1);text-align: center;}.title{font-size: 32px;color:#2c3e50;margin-bottom: 16px;}.version{font-size: 20px;color:#3498db;font-weight: bold;}.tip{margin-top: 24px;font-size:14px;color:#7f8c8d;}/style/headbodydivclasscarddivclasstitleHello CI/CD!/divdivclassversion当前版本${version}/divdivclasstip✅ Jenkins Gitea 自动发布流水线测试成功/div/div/body/html);});app.listen(port,0.0.0.0,(){console.log(服务启动成功监听端口 ${port});});DockerfileFROM node:18-alpine WORKDIR /app COPY package*.json ./ RUNnpminstall--productionCOPY..EXPOSE3000CMD[node,app.js]Jenkinsfilepipeline{agent any stages{stage(拉取代码){steps{checkout scm}}stage(单元测试){steps{shdockerrun--rm-v$PWD:/app-w/app node:18-alpinesh-cnpm install npm run test}}stage(构建镜像){steps{shdocker build -t demo-app:${BUILD_NUMBER}.}}stage(部署容器){steps{shdockerstop demo-app||truedockerrmdemo-app||truedockerrun-d--namedemo-app-p3001:3000 demo-app:${BUILD_NUMBER}sleep3dockerps|grepdemo-app}}}post{always{echo流水线执行完成构建号${BUILD_NUMBER}}success{echo✅ CI/CD发布成功访问地址http://192.168.88.132:3001}failure{echo❌ 流水线失败请查看日志排查问题}}}package.json{name:cicd-demo,version:1.0.0,dependencies:{express:^4.18.2},scripts:{start:node app.js,test:echo\单元测试通过\}}确认Jenkins前置条件Jenkins容器必须挂载docker.sock先停掉旧 jenkins重新启动带 docker 挂载# 停止并删除旧jenkins容器dockerstop jenkinsdockerrmjenkins重新启动 jenkins 容器增加挂载-v /var/run/docker.sock:/var/run/docker.sockdockerrun-d\--namejenkins\-p8080:8080\-p50000:50000\-v/var/jenkins_home:/var/jenkins_home\-v/var/run/docker.sock:/var/run/docker.sock\-uroot\jenkins/jenkins:lts-jdk17进入 Jenkins 容器安装 docker 客户端只装客户端不装完整 docker 引擎# 进入jenkins容器dockerexec-itjenkinsbash# 容器内执行安装docker客户端aptupdateaptinstall-ydocker.io# 退出容器exit4. 虚拟机防火墙放开3001端口# centos/rhel 执行firewall-cmd --add-port3001/tcp--permanentfirewall-cmd--reload在虚拟机里面查看容器是否正常启动能看到名字叫demo-app的容器就代表部署成功。在虚拟机终端执行 curl直接在服务器内部访问可输出html内容则访问成功curlhttp://127.0.0.1:3001Jenkins 安装插件进入 Manage Jenkins → Plugins → Available plugins搜索并安装插件名作用Pipeline流水线核心通常默认已装GitGit 拉取代码Docker Pipeline在流水线中构建/管理 Docker 镜像GiteaGitea 插件支持 Webhook 触发Credentials Plugin凭证管理通常默认已装安装完成后重启 Jenkins。【注】如果安装时提示「Plugin is missing: workflow-api」之类的依赖缺失点红色提示旁边的 「纠正」 按钮Jenkins 会自动补全依赖。配置 Jenkins 凭证如果 Gitea 仓库是私有的需要配置凭证(公开仓库可以跳过这一步)点击链接进入找到【凭证配置】凭证配置教程创建Jenkins流水线任务创建流水线流水线配置获取Gitea仓库的http格式的url地址里面的Gitea仓库的url:脚本路径这的文件名Jenkinsfile触发器配置手动测试构建构建成功自动触发构建Gitea Webhook配置目标url格式Jenkins访问地址/job/gitea_pipeline/build?tokenjenkins触发器配置的tokenjenkins的访问地址jenkins触发器配置的token钩子名称随便取其他选项默认点击【添加钩子】测试push自动构建修改Gitea仓库里的app.js的版本号信息为v1.3,并提交查看jenkins任务里是否进行自动构建先刷新页面滑到最下面访问该项目地址CI/CD到此结束ヾ(•ω•)o