1. 项目结构的介绍
1.1 后端项目
其中MyBlog文件夹是博客后端项目的主文件夹,admin文件夹是博客后端项目后台代码,blog文件夹是博客后端项目前台代码,common文件夹是博客后端项目前后台的公共代码。MyBlog所有代码共享一个git仓库。
1.2 前端项目
前端项目分为了前端项目前台代码和前端项目后台代码,如下图,其中前端文件夹是前端项目前台代码,前端后台是前端项目后台代码,两个文件夹分别各占一个git仓库。
2. 虚拟机相关环境配置
2.1 更新虚拟机相关软件依赖包
yum -y update # 更新软件包版本
yum -y remove docker docker-common docker-selinux docker-engine # 卸载旧版本
yum install -y yum-utils # 安装软件依赖包
# yum-utils: 提供了一系列的YUM工具,用于执行各种管理和维护任务,比如清理旧的软件包、查找依赖关系等
sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo # 装阿里镜像源
2.2 配置docker,jenkins,redis,mysql,nodejs
2.2.1 安装docker
yum install docker-ce -y # 安装 docker
docker -v # 查看 docker版本
systemctl enable docker # 设置 docker开机自启动
systemctl start docker # 启动 docker
2.2.2 创建jenkins_home目录
mkdir /usr/local/jenkins_home
2.2.3 下载docker-compose
安装docker-compose
sudo curl -L https://github.com/docker/compose/releases/download/v2.21.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
赋予docker-compose执行权限
chmod +x /usr/local/bin/docker-compose
查看docker-compose版本,出现版本则没有问题
docker-compose -v
2.2.4 配置jenkins,mysql,redis
进入上面创建好的jenkins_home目录
cd /usr/local/jenkins_home
编写docker-compose.yml文件,内容如下
version: '3' # 指定 docker-compose.yml 文件的写法格式
services: # 服务列表,用于定义要在容器中运行的服务。
jenkins: # 服务名称
user: root # 指定容器内部的用户为root用户,确保容器内部的操作有足够的权限。
restart: always # 设置容器退出后总是重新启动。
image: jenkins/jenkins # 指定要运行的镜像
container_name: jenkins # 容器名称
ports: # 对外暴露的端口
- '8080:8080'
- '50000:50000'
volumes: # 卷挂载路径
- /usr/local/jenkins_home/:/var/jenkins_home/ # 这是我们一开始创建的目录挂载到容器内的jenkins_home目录
- /var/run/docker.sock:/var/run/docker.sock
- /usr/bin/docker:/usr/bin/docker # 这是为了我们可以在容器内使用docker命令
mysql:
image: mysql:8.0.15
container_name: mysql
restart: always
ports:
- '3306:3306'
privileged: true
environment:
TZ: Asia/Shanghai
MYSQL_ROOT_PASSWORD: xiaoqian666
command:
--default-authentication-plugin=mysql_native_password
--character-set-server=utf8mb4
--collation-server=utf8mb4_general_ci
--explicit_defaults_for_timestamp=true
--lower_case_table_names=1
volumes:
- /usr/local/mysql/data/db:/var/lib/mysql #数据文件挂载
- /usr/local/mysql/data/conf:/etc/mysql/conf.d #配置文件挂载
- /usr/local/mysql/log:/var/log/mysql #日志文件挂载
redis:
image: redis:7
container_name: redis
restart: always
command: redis-server --requirepass xiaoqian666 --appendonly yes
volumes:
- /usr/local/redis/data:/data #数据文件挂载
- /etc/localtime:/etc/localtime
ports:
- '6379:6379'
2.2.5 下载jenkins相关插件
首先登录jenkins密码,不记得密码通过sudo cat /var/lib/jenkins/secrets/initialAdminPassword查看密码。到下图所示位置安装三个插件
Maven Integration:Maven 构建工具Git ParameterPublish Over SSH:整个工具,将来把 Jenkins 打包好的 jar 上传到应用服务器上。
2.3 配置JDK
到https://www.openlogic.com/openjdk-downloads?page=1下安装tar-gz结尾的压缩包文件,上传到Linux下的/opt目录。通过tar zxvf openlogic-openjdk-8u402-b06-linux-x64.tar.gz 将压缩包解压到当前目录,再通过mv openlogic-openjdk-8u402-b06-linux-x64 jdk8给目录重命名为jdk8。配置jenkins的jdk环境
切换到jenkins数据卷挂载的目录 cd /usr/local/jenkins_home
将jdk8复制到jenkins数据卷挂载的目录,由于jdk8是目录,所以需要-r参数 cp -r /opt/jdk8 ./
此时可以进入jenkins容器内部查看jdk8是否移入jenkins容器内 docker exec -it jenkins bash
cd ~
cd /var/jenkins_home # 注意这是容器内的目录,不知道在哪的话去查看docker-compose.yml文件数据卷挂载部分
ls
jenkins进入下图 再到如下位置配置jdk
2.4 配置Maven
到https://archive.apache.org/dist/maven/maven-3/3.6.3/binaries/下安装tar-gz结尾的压缩包文件,上传到Linux下的/opt目录。通过tar -zxvf apache-maven-3.6.3-bin.tar.gz将压缩包解压到当前目录,再通过mv apache-maven-3.6.3 maven给目录重命名为maven。通过命令cd maven/conf进入到maven的配置文件目录内,再通过vim settings.xml进入如下位置进行编辑配置maven下载的镜像源。
设置maven编译的jdk版本
输入esc然后输入:wq保存并退出。配置jenkins的maven环境
切换到jenkins数据卷挂载的目录 cd /usr/local/jenkins_home
将maven复制到jenkins数据卷挂载的目录,由于maven是目录,所以需要-r参数 cp -r /opt/maven ./
此时可以进入jenkins容器内部查看maven是否移入jenkins容器内 docker exec -it jenkins bash
cd ~
cd /var/jenkins_home # 注意这是容器内的目录,不知道在哪的话去查看docker-compose.yml文件数据卷挂载部分
ls
jenkins进入下图 再到如下位置配置Maven
2.5 配置nodejs
下载nodejs插件 到https://nodejs.org/dist/v16.12.0/下安装tar-gz结尾的压缩包文件,上传到Linux下的/opt目录。解压tar zxvf node-v16.12.0-linux-x64.tar.gz 到当前目录,可以通过mv node-v16.12.0-linux-x64.tar.gz nodejs给目录重命名为nodejs。配置jenkins的node环境
切换到jenkins数据卷挂载的目录 cd /usr/local/jenkins_home
将nodejs复制到jenkins数据卷挂载的目录,由于nodejs是目录,所以需要-r参数 cp -r /opt/nodejs ./
进入jenkins容器内部查看nodejs是否移入jenkins容器内 docker exec -it jenkins bash
cd ~
cd /var/jenkins_home # 注意这是容器内的目录,不知道在哪的话去查看docker- compose.yml文件数据卷挂载部分
ls
jenkins进入下图 再到如下位置配置nodejs
3. 后端项目部署
3.1 创建jenkins任务(构建前)
用于测试是否成功可以拉取对应git或者github上的代码,前提是推送了代码至git或者github。
创建任务 配置git仓库,指定源码位置,当项目构建时,jenkins便会从该url下拉取代码到jenkins本地进行项目编译。 配置git分支 点击立即构建测试拉取代码是否成功,并且可以查看控制台输出。 通过以下指令进入jenkins容器内部查看workspace,里面有从git仓库拉取下来的代码
docker exec -it jenkins bash
cd ~
cd /var/jenkins_home # 注意这是容器内的目录,不知道在哪的话去查看docker-compose.yml文件数据卷挂载部分
ls
cd workspace
ls
3.2 设置推送远程服务器地址(构建前)
上面可以成功拉取代码以后,我们需要开始去指定位置来执行拉取下来的代码中的docker目录下的指令,构建镜像,执行以下指令创建目录,用于告诉服务器要在哪个目录下执行传送过来的脚本以及文件。
cd /usr/local
mkdir blog
进入系统配置 配置远程服务器信息(使用用户名密码连接),我这里是虚拟机
3.3 利用maven构建jar包(构建时)
进入创建的任务,点击配置 找到构建步骤,选择调用顶层Maven目标
clean package -DskipT
(推送代码后)再次点击立即构建(此时构建时间会比较长,因为要下载对应依赖的jar包等),出现下图即为成功。 编译成功后可以再次进入jenkins容器内部查看workspace查看打包好的jar包(即target目录下的jar包)
docker exec -it jenkins bash
cd ~
cd /var/jenkins_home # 注意这是容器内的目录,不知道在哪的话去查看docker-compose.yml文件数据卷挂载部分
ls
cd workspace
ls
cd MyBlog
ls
3.4 推送jar包到服务器(构建后)
jenkins将项目代码编译打包完成之后需要将打包好的jar包推送至远程服务器,用于构建镜像并且创建运行容器
进入配置 设置构建后的操作,点击Send build artifacts over SSH后会自动回显刚刚配置好的远程服务器地址 选择要打包的文件格式 立即点击立即构建,等待编译成功 再到刚刚在3.2步下配置好的远程服务器目录下的target目录下查看jar包是否生成成功。
cd /usr/local/blog
3.5 生成自定义镜像并通过镜像运行容器
项目下创建docker目录,并创建docker-compose.yml文件以及两个Dockerfile文件,编写内容如下,完成后推送代码并在jenkins中点击立即构建。
docker-compose.yml
version: '3.1'
services:
blog:
build:
context: ./ # 指定当前目录下的 dockerfile
dockerfile: Dockerfile_blog # dockerfile名称
user: root
image: blog:v1.0.0
container_name: blog
ports:
- "7777:7777"
restart: always
admin:
build:
context: ./ # 指定当前目录下的 dockerfile
dockerfile: Dockerfile_admin # dockerfile名称
user: root
image: admin:v1.0.0
container_name: admin
ports:
- "7778:7778"
restart: always
Dockerfile_blog
# 基础镜像
FROM daocloud.io/library/java:8u40-jdk
COPY ./blog-1.0-SNAPSHOT.jar /tmp/app2.jar
EXPOSE 8081
ENTRYPOINT java -jar /tmp/app2.jar
Dockerfile_admin
# 基础镜像
FROM daocloud.io/library/java:8u40-jdk
COPY ./admin-1.0-SNAPSHOT.jar /tmp/app1.jar
EXPOSE 8082
ENTRYPOINT java -jar /tmp/app1.jar
推送代码至git或者github后,点击立即构建,构建完成后进入jenkins容器内部查看workspace查看刚刚创建好的docker目录。
docker exec -it jenkins bash
cd ~
cd /var/jenkins_home # 注意这是容器内的目录,不知道在哪的话去查看docker-compose.yml文件数据卷挂载部分
ls
cd workspace
ls
cd MyBlog
ls
通过jenkins创建执行脚本实现当点击立即构建且完成后,jenkins会将项目编译打包,并生成自定义镜像且运行在docker中。
cd /usr/local/blog/docker # 远程服务器工作目录下的docker目录
mv ../*/target/*.jar ./ # 将所有jar包移至当前目录(docker目录)
docker-compose down # 停止并删除之前启动的容器、网络、数据卷等相关资源。
docker-compose up -d --build # 启动DockerCompose文件中定义的服务容器,并且在后台运行
docker image prune -f # 删除未被使用的镜像
配置完成后再次点击立即构建进行测试。
4. 前端前台项目部署
4.1 配置前端前台项目
在项目下添加Docker文件夹,配置后项目目录结构如下 文件内容分别如下
Dockerfile
# 拉取nginx基础镜像
FROM nginx:1.21.1
# 维护者信息
MAINTAINER xiaoqian
# 将dist文件中的内容复制到 `/usr/share/nginx/html/` 这个目录下面
COPY dist/ /usr/share/nginx/html/
# 用本地配置文件来替换nginx镜像里的默认配置
COPY nginx/nginx.conf /etc/nginx/nginx.conf
# 对外暴露的端口号
# [注:EXPOSE指令只是声明容器运行时提供的服务端口,给读者看有哪些端口,在运行时只会开启程序自身的端口!!]
EXPOSE 80
# 启动nginx容器
CMD ["nginx", "-g", "daemon off;"]
nginx目录下的nginx.conf
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
keepalive_timeout 65;
server {
listen 80; # 对应nginx暴露的端口
server_name localhost;
location / {
root /usr/share/nginx/html; # 对应 Dockerfile中将 dist文件夹复制到的目录
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
}
}
.dockerignore
node_modules
.DS_Store
# node-waf configuration
.lock-wscript
# Compiled binary addons
build/Release
.dockerignore
Dockerfile
*docker-compose*
# Logs
logs
*.log
# Runtime data
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw*
pids
*.pid
*.seed
.git
.hg
.svn
4.2 创建jenkins任务
创建任务 配置git仓库,指定源码位置,当项目构建时,jenkins便会从该url下拉取代码到jenkins本地进行项目编译。 配置git分支 添加刚刚下载好并配置好的nodejs环境 添加shell脚本,实现自动化构建镜像并运行容器。
npm cache verify # 清除缓存
npm config set registry https://registry.npmmirror.com # 设置镜像
npm config set strict-ssl false # 取消ssl证书
npm config set proxy false # 取消代理
npm install # 安装依赖
npm run build # 打包项目
cp -r dist/ Docker/ # 将打包好的 dist文件夹复制到 Docker目录下
cd Docker # 切换到 Docker目录
docker build -f Dockerfile -t blog_ui_1th . --no-cache # 指定通过Dockerfile构建镜像
# 删除旧的容器,否则无法运行新容器
docker ps -a | grep blog_ui_1th | awk '{print $1}' | xargs -i docker stop {} | xargs -i docker rm {}
docker image prune -f # 删除未被使用的镜像
docker run -d -p 8081:80 --restart=always --name blog_ui_1th blog_ui_1th # 根据镜像运行容器
点击应用后立即构建任务,等待完成前端项目的打包完成以及镜像的构建和容器的运行,出现下图即为成功。
5. 前端后台项目部署
第一步与配置前端前台项目步骤一致,但是需要更改nginx以及Dockerfile的配置文件
Dockerfile
FROM nginx:1.21.1
MAINTAINER xiaoqian
COPY dist/ /usr/share/nginx/html/blog_ui_2th # 修改路径到 /html下的 blog_ui_2th目录
COPY nginx/nginx.conf /etc/nginx/nginx.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
nginx.conf
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
keepalive_timeout 65;
server {
listen 80; # # 对应nginx暴露的端口
server_name localhost;
location / {
root /usr/share/nginx/html/blog_ui_2th; # 对应 Dockerfile中将 dist文件夹复制到的目录
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
}
}
更新前端后台jenkins任务的shell脚本
npm cache verify
npm config set registry https://registry.npmmirror.com
npm config set strict-ssl false
npm config set proxy false
npm install
npm run build:prod
cp -r dist/ Docker/
cd Docker
docker build -f Dockerfile -t blog_ui_2nd . --no-cache
docker ps -a | grep blog_ui_2nd | awk '{print $1}' | xargs -i docker stop {} | xargs -i docker rm {}
docker image prune -f # 删除未被使用的镜像
docker run -d -p 8082:80 --restart=always --name blog_ui_2nd blog_ui_2nd # 根据镜像运行容器
参考链接
发表评论