Gitea+Jenkins+Docker 搭建 Node 项目 CI/CD 自动部署完整教程
- 整体架构
- 前置条件
-
- 把4个文件上传到Gitea仓库根目录
- 确认Jenkins前置条件
-
- Jenkins容器必须挂载docker.sock
- [Jenkins 安装插件](#Jenkins 安装插件)
- [配置 Jenkins 凭证](#配置 Jenkins 凭证)
- 创建Jenkins流水线任务
- 自动触发构建
-
- [Gitea Webhook配置](#Gitea Webhook配置)
介绍:
CI : Continuous Integration,持续集成。频繁把多个人写的代码合并到同一个仓库,自动做校验;仓库收到代码提交,自动执行:拉代码 → 安装依赖 → 单元测试 → 构建镜像。
CD : Continuous Deployment,持续部署.CI 做完构建出镜像之后,自动部署到服务器,启动容器,对外提供服务 ;
部署容器,自动停止旧容器、删除旧容器、启动新版本容器.
总结:CI:代码提交 → 自动构建 + 自动测试(验证代码能不能用)CD:测试通过 → 自动打包部署上线(把新版本服务跑起来)
整体架构
开发者 push 代码
↓
Gitea 仓库(代码托管)
↓ Webhook 推送
Jenkins(CI/CD 流水线调度)
├─ 1. 拉取代码
├─ 2. 构建 Docker 镜像
├─ 3. 推送镜像到 Harbor(或本地保留)
└─ 4. SSH 登录部署服务器 / 本机 docker-compose 部署
↓
目标服务器(运行容器)
↓
前置条件
Docker:Dokcer部署及使用
Gitea:Gitea部署及使用
Jenkins:Jenkins部署及使用
把4个文件上传到Gitea仓库根目录

- .dockerignore
bash
node_modules
.git
- app.js
bash
const express = require('express');
const app = express();
const port = 3000;
// 版本号,后续改这里即可
const version = "v1.2";
app.get('/', (req, res) => {
// 返回HTML页面
res.send(`
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>CI/CD 演示页面</title>
<style>
* {
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: 0 8px 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>
</head>
<body>
<div class="card">
<div class="title">Hello CI/CD!</div>
<div class="version">当前版本:${version}</div>
<div class="tip">✅ Jenkins + Gitea 自动发布流水线测试成功</div>
</div>
</body>
</html>
`);
});
app.listen(port, '0.0.0.0', () => {
console.log(`服务启动成功,监听端口 ${port}`);
});
- Dockerfile
bash
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install --production
COPY . .
EXPOSE 3000
CMD ["node", "app.js"]
- Jenkinsfile
bash
pipeline {
agent any
stages {
stage('拉取代码') {
steps {
checkout scm
}
}
stage('单元测试') {
steps {
sh '''
docker run --rm -v $PWD:/app -w /app node:18-alpine sh -c "npm install && npm run test"
'''
}
}
stage('构建镜像') {
steps {
sh "docker build -t demo-app:${BUILD_NUMBER} ."
}
}
stage('部署容器') {
steps {
sh """
docker stop demo-app || true
docker rm demo-app || true
docker run -d --name demo-app -p 3001:3000 demo-app:${BUILD_NUMBER}
sleep 3
docker ps | grep demo-app
"""
}
}
}
post {
always {
echo "流水线执行完成,构建号:${BUILD_NUMBER}"
}
success {
echo "✅ CI/CD发布成功!访问地址:http://192.168.88.132:3001"
}
failure {
echo "❌ 流水线失败,请查看日志排查问题"
}
}
}
- package.json
bash
{
"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 挂载)
bash
# 停止并删除旧jenkins容器
docker stop jenkins
docker rm jenkins
- 重新启动 jenkins 容器,增加挂载
-v /var/run/docker.sock:/var/run/docker.sock
bash
docker run -d \
--name jenkins \
-p 8080:8080 \
-p 50000:50000 \
-v /var/jenkins_home:/var/jenkins_home \
-v /var/run/docker.sock:/var/run/docker.sock \
-u root \
jenkins/jenkins:lts-jdk17
- 进入 Jenkins 容器,安装 docker 客户端(只装客户端,不装完整 docker 引擎)
bash
# 进入jenkins容器
docker exec -it jenkins bash
# 容器内执行安装docker客户端
apt update
apt install -y docker.io
# 退出容器
exit



- 虚拟机防火墙放开3001端口
bash
# centos/rhel 执行
firewall-cmd --add-port=3001/tcp --permanent
firewall-cmd --reload


在虚拟机里面查看容器是否正常启动,能看到名字叫 demo-app 的容器就代表部署成功。

在虚拟机终端执行 curl,直接在服务器内部访问,可输出html内容,则访问成功:
bash
curl http://127.0.0.1:3001

Jenkins 安装插件
进入 Manage Jenkins → Plugins → Available plugins,搜索并安装:
| 插件名 | 作用 |
|---|---|
| Pipeline | 流水线核心(通常默认已装) |
| Git | Git 拉取代码 |
| Docker Pipeline | 在流水线中构建/管理 Docker 镜像 |
| Gitea | Gitea 插件,支持 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?token=jenkins触发器配置的token

jenkins的访问地址:

jenkins触发器配置的token:

钩子名称:随便取

其他选项默认,点击【添加钩子】

测试push自动构建:
修改Gitea仓库里的app.js的版本号信息为v1.3,并提交



查看jenkins任务里是否进行自动构建,先刷新页面


滑到最下面:

访问该项目地址:

CI/CD到此结束ヾ(•ω•`)o