
Unbuntu配置jenkins实现前端自动化部署
本文最后更新于 2025-03-09,文章内容可能已经过时。
自动化部署
,就是开发人员
,将开发代码
推送到远程仓库
,通过jenkins
配置自动化脚本
,从远程仓库
进行代码拉取
,然后将代码打包
,并推送到,部署目录
下的一套流程!在此,需要准备的,一台云服务器(这里用的
unbuntu云服务器
),其它的准备如下:
nodejs:
在服务器内部可以安装nvm(Node Version Manager)版本控制器
,来灵活下载Nodejs!
docker:
需要在服务器内部安装docker
,剩下的jenkins
以及nginx
等都需要在docker
中安装!
安装Node
这里可以
选择性的安装NodeJS
,因为Jenkins内部插件对Nodejs
有了一个支持,可以直接通过Docker来安装Jenkins和Nginx即可
!
安装Docker
docker
是一个linux复刻版的虚拟机
,可以安装很多应用,我们平时开发
和部署
,通常都是在linux
系统下直接安装
和使用
比如(java nginx node
)等,这样在小型应用
下使用是没有问题的,若是大型应用
,若是一个应用程序出现了问题
,则会导致linux系统服务整个崩溃
,会影响到其它服务的运行
,有了docker
,且每个应用之间是相互隔离
的,保证在一个程序出现问题
时,而不会影响到其它应用程序的运行!
首先
切换
用户到root
,避免在操作时,出现不必要的权限问题
!
su - root
# or
sudo -i
更新apt
索引
apt 和 yum 一样,是一个软件包管理工具,可以帮我们下载安装需要的依赖插件!
sudo apt-get update
安装依赖包
sudo apt-get install apt-transport-https ca-certificates curl software-properties-common -y
添加Docker
官方GPG
密钥
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
添加Docker
仓库
echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
安装Docker
引擎
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io -y
验证安装
sudo docker --version
设置开机启动
sudo systemctl enable docker && sudo systemctl start docker
设置Docker
加速镜像
docker
镜像默认是国外
的,在国内通过镜像下载包资源会超时
问题,所以我们需要配置加速镜像
,如阿里云,网易云,腾讯云
等!
加速器名称 | 镜像地址 |
---|---|
阿里云 |
https://<your-accelerator-id>.mirror.aliyuncs.com |
网易云 |
https://hub-mirror.c.163.com |
腾讯云 |
https://mirror.ccs.tencentyun.com |
DaoCloud |
http://f1361db2.m.daocloud.io |
华为云 |
https://mirrors.myhuaweicloud.com/dockerhub |
以上是
国内
比较常用的镜像地址,接下里我们需要配置docker
中的daemon.json
文件,并重新启动docker
即可!
sudo nano /etc/docker/daemon.json
修改一下内容
{
"registry-mirrors": [
"https://docker.hpcloud.cloud",
"https://docker.m.daocloud.io",
"https://docker.unsee.tech",
"https://docker.1panel.live",
"http://mirrors.ustc.edu.cn",
"https://docker.chenby.cn",
"http://mirror.azure.cn",
"https://dockerpull.org",
"https://dockerhub.icu",
"https://hub.rat.dev"
]
}
重启
daemon
配置和docker
!
systemctl daemon-reload
systemctl restart docker
查看是否
配置生效
docker info
在输出中查找
Registry Mirrors
,确认已列出配置的镜像加速地址
。
docker info | grep "Registry Mirrors" -A 2
列出以下内容,便配置成功!
Registry Mirrors:
https://<你的ID>.mirror.aliyuncs.com/
https://docker.mirrors.ustc.edu.cn/
Docker常用命令
安装Jenkins
使用
Docker
容器来安装对应的Jenkins!
创建jenkins_home
文件夹
下载依赖并启动容器
docker run \
-u root \
-d -p 8080:8080 \
-p 50000:50000 \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /usr/bin/docker:/usr/bin/docker \
-e TZ=Asia/Shanghai \ # 设置时区
--name jenkins \
jenkins/jenkins:lts
避坑提示
,通过Docker
安装Jenkins
时,需要Jenkins内部脚本
提供对docker命令
的支持,也就是说,若构建镜像
时,需要使用docker build
相关命令来执行,则必须保证docker命令
需要在Jenkins任务环境
下能够使用
才行,避免出现commond not found!
以下命令,
-v /var/run/docker.sock:/var/run/docker.sock \ -v /usr/bin/docker:/usr/bin/docker \
查看内置密码
需要
获取内置密码
后,才能继续安装!
因为
jenkins
通过docker安装
,且jenkins
为docker
其中的一个容器
,我们需要通过进入到容器
里才能找到jenkins
并获取对应的内置密码
!
docker exec -it <容器id> /bin/bash
sudo cat /opt/jenkins_home/secrets/initialAdminPassword
访问Jenkins
# 浏览器打开 http://服务器IP:8080 输入初始密码
/var/jenkins_home/secrets/initialAdminPassword
需要把/var
改为/opt
-v /opt/jenkins_home:/var/jenkins_home \
根据docker run -d
去安装jenkins
目录去定义
登录Jenkins
根据上述,获取密码之后,进行
登录
和初始化
,期间会让选择安装插件
,此处推荐跳过
,否则安装插件
还是比较耗时
的!
重置密码
Jenkins安装时,在
initialAdminPassword
文件内有一个内置随机初始密码
,我们需要将密码进行重置
,避免,下次登录时出现问题
!
安装问题
若遇到
启动jenkins失败
时,根据logs日志
情况来查看问题!
docker 启动容器时,提示 Error response from daemon: container d55bb44bb71d85933b62a093d692d0334025b523ff4b001238a387495484499f is not running
获取未启动的
容器ID
:docker ps -a
- 查看容器的
运行状态
- 获取一行为对应的
ImageName
为jenkins/jenkins:lts
第一列CONTAINER ID
下的Id
- 查看容器的
查看
容器的日志
,确定容器未启动
或退出
的原因:docker logs <容器的ID>
如果
日志
中显示错误(如依赖缺失、配置文件错误、权限问题
等),根据提示修复
。 如果日志
无报错,可能是容器
任务执行完毕后自动退出
(如仅运行一个临时脚本
)查看
容器的状态
:`docker ps -a` # 查看所有容器(包括已退出的) `docker inspect <容器ID>` # 查看容器详细信息
关注
State
字段中的ExitCode
,非0值
表示异常退出
。 检查Config.Cmd
或Config.Entrypoint
是否配置了前台持久进程
。经日志查看,发现是
目录权限
写入有问题:docker 安装 Jenkins时 INSTALL WARNING: User: missing rw permissions on JENKINS_HOME: /var/jenkins_home
最后确认,是在下载和运行jenkins时,目录写成了相对路径
docker run -d \ --name jenkins \ -p 8080:8080 \ -p 50000:50000 \ -v ./jenkins_home:/var/jenkins_home \ -v /var/run/docker.sock:/var/run/docker.sock \ jenkins/jenkins:lts-jdk11
./jenkins_home
改为/opt
删除容器,重新运行docker run
命令即可!删除容器,重新安装
docker rm <容器ID或名称> # 删除容器 docker run -d \ --name jenkins \ -p 8080:8080 \ -v /opt/jenkins_home:/var/jenkins_home \ jenkins/jenkins:lts
Jenkins使用
安装插件
在
Jenkins
首页左侧菜单栏
中,找到系统设置
,然后再右侧功能选项
中找到Plugins
插件管理,在这里可以搜索我们想要安装的插件
!
需要安装的插件:
chinese中文翻译包、其次就是gitee 、git plugins、publish over ssh、nodejs、nvm-wrapper、extensible-choice-parameter!
选中
安装插件
后,等待安装完成,然后界面会有重启Jenkins
等待一会,刷新页面,这时Jenkins的服务已经退出并停掉
了,需要手动重新启动
!
docker ps -a
查看容器的运行状态,并获取
container id
!
docker start <容器ID>
并
重新启动
即可!
修改Jenkins下载源
Jenkins
本身下载源
,下载插件会比较慢
,可以更换默认
的下载源
,来提升下载插件
的速度!
https://updates.jenkins.io/update-center.json
以上链接是
Jenkins默认
的下载源
,接下来我们来将它替换掉新的下载源
!
https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json
sed -i 's/https:\/\/updates.jenkins.io\/download/https:\/\/mirrors.tuna.tsinghua.edu.cn\/jenkins/g' /root/.jenkins/updates/default.json && sed -i 's/http:\/\/www.google.com/https:\/\/www.baidu.com/g' /root/.jenkins/updates/default.json
也可以通过
命令
的方式设置镜像源
在页面上导入插件
/manage/pluginManager/advanced
在这个地址页面上,去选择本地插件安装
,需要是以.hpi为后缀
的文件,可以在以上地址,找到对应的插件下载
到本地,进行选择
和安装
!
在服务器上进行插件迁移
下载插件到服务器上
,然后将插件移动到/opt/jenkins_home/plugins/
即可!
配置gitee
需要再
gitee
中生成令牌
生成令牌
个人设置
->安全设置
->私人令牌
->生成令牌
配置Jenkins
添加凭证
添加gitee
令牌
Jenkins首页
->系统设置
->凭据管理
->点击全局
在右侧蓝色按钮点击
添加凭据 add credentials
添加gitee
用户
用于创建
Jenkins Job
任务时,选择git,需要选择gitee 用户
来认证!
系统管理 -> 凭证管理 -> 添加凭证
这次
类型
选择username & password
Jenkins
集成Nvm
nvm
是一个node 版本控制器
,可以灵活切换node版本
,jenkins
集成nvm
插件,可以在插件列表里搜索nvm-wrapper
安装即可,随后在新建Jenkins Job
任务时,勾选nvm
选项,并且选择对应的node版本
即可!
https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh
以上是
nvm
下载地址
Jenkins
任务执行
创建任务
在首页
左侧菜单
下,选择新建任务
,进入新建任务界面
!
进入任务配置
丢弃旧的构建
丢弃旧的构建
,可以配置每次构建新的
时候,将之前的构建进行清除
操作,可配置旧的构建保存天数
,以及清除的个数
!
可选保存天数5天
,清除其中5个构建项目
!
参数化构建过程
参数化构建
过程,可以添加参数
,以便在构建
时,动态选择性
的去构建
,例如git分支
包含(master、dev、test
),不可能每次去构建
的时候,都需要手动去改默认分支
吧,通过Extensible Choice
插件,将分支选项配置
好后,我们可以在构建之前
,选择性去构建对应的分支
!
需要安装的插件
Extensible Choice Parameter plugin
,可以在插件管理
搜索此插件并安装
!
源码管理
源码管理
,就是配置我们项目的一个git仓库地址
,以及git仓库认证
和授权信息
!
环境配置
用于
配置代码
的构建方式
,例如node
与npm
的文件路径
,以及nvm
的相关配置,nvm
需要插件支持
,nvm-wrapper,
这里我选择了以nvm
的方式来管理node版本
,如果你不考虑内网
的情况下,可以使用!
当然,我们这里需要把
NVM安装位置URL
改一下,默认的是github地址
,可能会下载失败
!
https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh
可以改成如上地址!
这里我们只需要,选择
输入NodeJS版本
,以及修改NVM_URL安装路径
即可,其它会默认生成
!
构建步骤
构建步骤
,就是在执行构建
时,以什么样的方式去选择构建
,例如输入nodejs脚本
,以及shell脚本
等相关命令!
#!/bin/bash
echo "============安装依赖============="
npm install --registry="https://registry.npmmirror.com/"
echo "============安装完成============="
echo "============打包构建============="
npm run build
echo "============构建完成============="
echo "============开始推送============="
#! cp -r ./dist/* /usr/share/nginx/html
echo "============发布完成============="
流水线任务
流水线任务
,就是通过本地代码
根目录创建Jenkinsfile脚本
文件,将构建步骤
通过脚本的形式
来描述!
通过此链接,可以
获取pipeline脚本
具体构建过程的写法
!
import java.text.SimpleDateFormat
pipeline {
agent any
options {
timestamps()
}
parameters {
choice(name: 'Run',choices: ['build', 'copy', ],description: '部署类型 (copy:直接复制上次部署的文件, build:重新构建)')
booleanParam(name: 'Base', defaultValue: true, description: '部署基础模块')
booleanParam(name: 'Install', defaultValue: false, description: '下载新的依赖')
choice(name: 'Env',choices: ['dev', 'test', ],description: '部署环境')
}
stages {
stage('构建基础模块代码') {
when { expression { return params.Base } }
steps {
echo "=========================构建基础模块代码========================="
script{
if ("${params.Run}" == "copy") {
echo "copy"
}else{
echo "Build"
if("${params.Install}" == "true") {
sh "rm -rf node_modules"
sh "npm install --registry=https://registry.npmmirror.com"
}
sh "rm -rf dist"
sh "npm run build:${params.Env}"
sh "cp -r ./dist/* /usr/share/nginx/html"
}
}
}
}
stage('构建镜像') {
steps {
echo "=========================构建镜像========================="
//script{
//sh "docker build -t 127.0.0.1:8082/base-system/nginx:dev -f ./Dockerfile ."
//}
}
}
stage('推送镜像') {
steps {
echo "=========================推送镜像========================="
//script{
//sh "docker login https://127.0.0.1:8082 -u admin -p QWEasd123"
//sh "docker push 127.0.0.1:8082/base-system/nginx:${params.Env}"
//}
}
}
stage(" dev环境部署"){
when { expression { return params.Env == "dev" } }
steps {
echo "部署dev镜像"
}
}
stage(" test环境部署"){
when { expression { return params.Base == "test" } }
steps {
echo "部署test镜像"
}
}
}
}
安装Nginx
我们通过
docker
来安装Nginx web
服务器,来部署
我们前端
的打包的静态资源文件
!
拉取镜像
docker pull nginx:latest
运行Nginx
容器
在
后台启动nginx
且容器名为my-nginx
在80端口
可访问!
docker run -d --name my-nginx -p 80:80 nginx:latest
-d
: 后台运行容器
。--name my-nginx
: 为容器命名(可自定义)。-p 80:80
: 将宿主机
的80端口
映射到容器的80端口
。
验证是否运行成功
浏览器
打开http://ip
,看到"Welcome to nginx!"
即表示成功
。
进入docker
容器
docker
容器像是linux
的一个复刻版的虚拟机
,类似于linux的目录
,进入到容器
后,我们所安装的应用都在虚拟机内
!
docker exec -it my-nginx /bin/bash
my-nginx
是nginx容器
的名称
Dockerfile构建镜像
Dockerfile
是一个用于定义
和构建 Docker 镜像
的文本文件
。它包含了一系列指令
(Instructions
),这些指令会按照顺序执行
,最终生成一个可重复、可移植的 Docker 镜像
。镜像
可以看作是一个轻量级的“模板”
,用于快速创建容器
。
Dockerfile
的核心作用
自动化构建镜像:通过编写
Dockerfile
,你可以精确控制镜像的构建过程
(例如安装软件、配置环境、复制文件
等)。版本化管理:
Dockerfile
可以和代码一起存入版本控制系统(如 Git)
,方便追踪镜像的变更历史
。标准化环境:
确保开发、测试、生产环境
的一致性,避免“在我机器上能运行
”的问题。
Dockerfile
的核心指令
指令 |
作用 |
---|---|
FROM |
指定基础镜像 (例如 FROM ubuntu:20.04 或 FROM nginx:latest )。 |
RUN |
在镜像构建过程中执行命令 (如安装软件包、修改文件)。 |
COPY / ADD |
将本地文件复制到镜像中 (例如复制代码或配置文件)。 |
WORKDIR s |
设置后续指令的工作目录 (相当于 cd 命令)。 |
EXPOSE |
声明容器运行时监听的端口 (例如 EXPOSE 80)。 |
ENV |
设置环境变量 (例如 ENV NODE_ENV=production )。 |
CMD / ENTRYPOINT |
指定容器启动时运行的默认命令 (例如启动服务)。 |
VOLUME |
定义挂载点 (用于持久化数据 )。 |
Dockerfile
基础使用
在主机
~/根目录
中创建两个文件:Dockerfile
:FROM nginx:latest # COPY demo.nginx.conf /etc/nginx/conf.d/ COPY dist /usr/share/nginx/html CMD ["nginx", "-g", "daemon:off;"]
index.html
<html> <head> <meta charset="utf-8"> <title>docker file</title> </head> <body> <center>docker file test html!</center> </body> </html>
修改
COPY dist /usr/share/nginx/html
把dist
替换掉./index.html
COPY ./index.html /usr/share/nginx/html
生成
Docker
镜像
docker build -t demo:dev -f ./Dockerfile .
demo:dev
demo
为镜像的名称
,而dev
则为镜像的tag标签
!查看镜像
是否创建成功
!docker images
结果如下,会生成
demo:dev
的一个镜像!root@VM-24-5-ubuntu:~# docker images REPOSITORY TAG IMAGE ID CREATED SIZE demo dev c4f118fb5b07 10 minutes ago 192MB nginx latest b52e0b094bc0 4 weeks ago 192MB jenkins/jenkins lts 82a2134e1742 4 weeks ago 468MB
启动创建好的镜像
docker run -d -p 9003:80 --name demo-dev demo:dev
demo-dev
是启动镜像
后的一个name
,这个name可以随便写!demo:dev
则是你要在docker images
镜像列表中选择启动的镜像名称
,这个是在生成镜像的时候就定义好的
!
查看镜像的运行状态:
docker ps -a
在地址栏中输入
ip:9003
端口,便可看到创建的index.html
文件已经部署到nginx/html
中!
Dockerfile
在项目中使用
需要
前端项目
中的目录下创建Dockerfile
文件,以nginx.conf
配置文件
Dockerfile
文件内容如下
dockerfile
负责通过指令
来创建出一个服务镜像
,如下拉取nginx服务
,可将本地拉取的项目
中根据nginx.conf
配置文件复制
到nginx/conf.d/
配置文件夹内!
FROM nginx:latest
# 复制nginx配置文件到nginx的conf目录下
COPY nginx.conf /etc/nginx/conf.d/default.conf
# 复制打包后的dist文件夹到nginx的html目录下
COPY dist /usr/share/nginx/html/front-system/
# 启动nginx服务(容器主进程)
CMD ["nginx", "-g", "daemon off;"]
nginx.conf
配置文件内容如下
# 仅保留server配置块(删除所有全局配置)
server {
listen 9003;
server_name localhost;
location /front-system/ {
root /usr/share/nginx/html;
try_files $uri $uri/ /front-system/index.html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
需要注意的是,这里的
nginx.conf配置文件
, 是作为子模块配置文件
使用,如果文件内部,配置了http
以及全局的一些相关配置,比如events
,或者user
等,作为配置文件
,存放在conf.d/目录
下,会与主配置文件有冲突
,而导致不必要的错误!
nginx: [emerg] "user" directive is not allowed here in /etc/nginx/conf.d/nginx.conf
例如以上问题,问题原因说明:
1.
原配置全局参数user/worker_processes等)写入conf.d子配置文件
2.
Nginx主配已包含全局参数conf.d目录下的文只能包含http/server级别配置
3.
通过拆分配置文件保留主配置的默认参数,自定义配置仅包含server块
jenkins
添加任务
这里
只描述
下,构建的步骤和脚本
,其它相关配置,可以查看当前文章目录下的jenkins任务执行
,里面包含了相关配置
操作!
项目构建
包含
npm
镜像地址
设置,以及install 依赖
安装,打包构建
等相关脚本!
#!/bin/bash
echo "============npm 版本============="
node -v
npm -v
echo "============npm set config============="
npm config set registry https://registry.npmmirror.com/
npm config list
echo "============安装 依赖============="
# 优先使用本地缓存
npm install --prefer-offline'
echo "============安装 完成============="
echo "============打包 构建============="
npm run ${Env}
echo "============构建 结束============="
# echo "============开始 推送============="
# cp -r ./dist/* /usr/share/nginx/html
# echo "============发布完成============="
这里
npm install
依赖安装,平时如果没有新的依赖
要更新的话,只需要安装一次
即可,不需要每次构建
时都要去安装依赖
!
根据情况,
判定是否新增依赖
,来手动去配置 npm install
此次是否安装,若不需要,则注释
即可!可以
参数的形式增加一个boolean 布尔值
,需要安装
时,勾选即
可,不需要安装时取消勾选即
可,该参数
可在shell脚本
中使用!
pipeline { agent any parameters { booleanParam(name: 'SKIP_NPM_INSTALL', defaultValue: false, description: '是否跳过 npm install?') } stages { stage('Install Dependencies') { when { expression { return !params.SKIP_NPM_INSTALL } } steps { sh 'npm install' } } stage('Build') { steps { sh 'npm run build' } } } }
镜像逻辑删除
由于
构建完项目
之后,我们需要执行Dockerfile文件
,执行完毕后会生成一个镜像
和容器
, 此时我们在下一次构建之前
,需要把之前构建的镜像
和容器
做一个清除操作
,来保证镜像构建的唯一性
!
若每次
构建镜像
在不清除
之前镜像
的情况下,且镜像名
与标签
,在每次构建
时都一样
,可能会生成name<none> tag<none>
镜像缓存
!
#!/bin/bash
# 定义镜像名称和标签
IMAGE_NAME="vmf"
# 当使用相同的镜像名称重复构建时,旧镜像会失去标签变成 <none> IMAGE_TAG 改为动态标签
TAG=${Env}
FULL_IMAGE="$IMAGE_NAME:$TAG"
# 检查镜像是否存在
echo "=============检查镜像是否存在=============="
if docker image inspect "$FULL_IMAGE" &> /dev/null; then
echo "发现镜像 $FULL_IMAGE,正在删除..."
# 停止并删除所有关联容器
docker ps -a --filter "ancestor=$FULL_IMAGE" --format "{{.ID}}" | xargs -r docker rm -f
# 删除镜像(可选:添加 || true 忽略错误)
echo "删除旧镜像..."
docker rmi -f "$FULL_IMAGE" 2>/dev/null || true
docker rmi "nginx:latest"
echo "删除完成"
else
echo "镜像 $FULL_IMAGE 不存在"
fi
构建镜像
通过
Dockerfile
文件进行镜像构建
,然后运行即可
!
${Env}
是通过参数选项配置,比如你构建的dev
或者是test环境
!
#!/bin/bash
echo = "============开始构建镜像============="
docker build -t vmf:${Env} -f ./Dockerfile .
echo = "============启动镜像============="
docker run -d --name vmf-${Env} -p 9003:9003 vmf:${Env}