Jenkins+GitLab+Docker搭建前端自动化构建镜像容器部署

前言

🚀 需提前安装环境及知识点:
1、Docker搭建及基础操作
2、DockerFile文件描述
3、Jenkins搭建及基础点

🚀 目的:
将我们的前端项目打包成一个镜像容器并自动发布部署,可供随时pull访问

一、手动部署镜像及容器

1、在当前项目的根目录创建Dockerfile文件并写入如下代码:

# 第一阶段:构建前端产出物
FROM node:14.19.0 AS builder

WORKDIR /visualization
COPY . .
RUN npm install -g cnpm --registry=https://registry.npm.taobao.org
RUN cnpm install && npm run build


# 第二阶段:生成最终容器映像
FROM nginx

COPY docker/certbook.key /etc/nginx/cert/certbook.key
COPY docker/certbook_bundle.pem /etc/nginx/cert/certbook_bundle.pem
COPY docker/nginx.conf /etc/nginx/conf.d/default.conf
COPY docker/docker-entrypoint.sh /docker-entrypoint.sh


WORKDIR /home/visualization
COPY --from=builder /visualization/dist .

RUN chmod +x /docker-entrypoint.sh

代码片段详细描述:
注意:如果项目不需要https访问,则可忽略certbook.key、certbook_bundle.pem的操作
/visualization为工作区名称,可更换

片段描述
FROM node:14.19.0 AS builder选择使用 Node.js 14.19.0 作为基础镜像,并命名该步骤为 “builder”
WORKDIR /visualization. COPY . .将工作目录设置为 “/visualization”,并将当前目录(代码仓库根目录)中的所有文件和目录复制到 “/visualization” 目录中
1、RUN npm install -g cnpm --registry=https://registry.npm.taobao.org. 2、RUN cnpm install && npm run build安装 cnpm 包管理器并使用其安装项目依赖项,接着在执行 npm run build 命令进行构建操作,构建后的前端产出物保存至 “/visualization/dist” 目录中
FROM nginx选择使用 Nginx 作为基础镜像,并命名该步骤为默认名称 “builder”
1、COPY docker/certbook.key /etc/nginx/cert/certbook.key。 2、COPY docker/certbook_bundle.pem /etc/nginx/cert/certbook_bundle.pem 3、COPY docker/nginx.conf /etc/nginx/conf.d/default.conf 4、COPY docker/docker-entrypoint.sh /docker-entrypoint.sh将docker文件夹下的 Nginx 配置文件和证书密钥文件都复制到对应的位置中
1、WORKDIR /home/visualization 2、COPY --from=builder /visualization/dist .将工作目录设置为 “/home/visualization”,并将来自 “builder” 阶段的前端产出物复制到当前目录中。
RUN chmod +x /docker-entrypoint.sh对 “/docker-entrypoint.sh” 执行 chmod +x 命令,添加可执行权限。

2、项目根目录新建.dockerignore文件,忽略文件

# Dependency directory  
# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git  
node_modules  
.DS_Store  
dist  
  
# node-waf configuration  
.lock-wscript  
  
# Compiled binary addons (http://nodejs.org/api/addons.html)  
build/Release  
.dockerignore  
Dockerfile  
*docker-compose*  
  
# Logs  
logs  
*.log  
  
# Runtime data  
.idea  
.vscode  
*.suo  
*.ntvs*  
*.njsproj  
*.sln  
*.sw*  
pids  
*.pid  
*.seed  
.git  
.hg  
.svn

3、当前项目根目录下创建docker文件夹

1、新建nginx.conf文件,用于配置前端项目访问nginx配置文件
2、新建docker-entrypoint.sh文件,执行脚本动态修改nginx.conf中的代理请求地址
3、如果项目需要https,则把证书xxx.key、xxx.pem放入docker文件夹中,需要与上面DockerFile中COPY的证书名称保持一致

nginx.conf内容
~根据项目情况做出修改,gzip配置前端无则可删除
~ /dev是前端代理跨域的基准地址,要保持统一,代理到后端的地址,做代理的目的是后面可以根据容器run动态改变proxy_pass地址
~如果项目无https则可删除443监听

server {
    listen 80;
    listen [::]:80;
    server_name  localhost;
    
    # gzip config
    gzip on;
    gzip_min_length 1k;
    gzip_comp_level 9;
    gzip_types text/plain text/css text/javascript application/json application/javascript application/x-javascript application/xml;
    gzip_vary on;
    gzip_disable "MSIE [1-6]\.";
    #
    
    location / {
        root   /home/visualization;
        index  index.html index.htm;
    }
     
    location /dev {
        # 前端/dev请求代理到后端https://xxx.xxx/
        proxy_pass https://xxx.xxx/;
        
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP  $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_connect_timeout   1;
        proxy_buffering off;
        chunked_transfer_encoding off;
        proxy_cache off;
        proxy_send_timeout      30m;
        proxy_read_timeout      30m;
        client_max_body_size    500m;

        access_log /var/log/nginx/dev_access.log;
        error_log /var/log/nginx/dev_error.log;
    }
}

server {
    listen 443 ssl;
    listen [::]:443;
    # 配置域名访问项目
    server_name  xx.xx.xx.com;

    # gzip config
    gzip on;
    gzip_min_length 1k;
    gzip_comp_level 9;
    gzip_types text/plain text/css text/javascript application/json application/javascript application/x-javascript application/xml;
    gzip_vary on;
    gzip_disable "MSIE [1-6]\.";
    #
    
    # ssl证书配置开始
    ssl_certificate   /etc/nginx/cert/certbook_bundle.pem;
    ssl_certificate_key  /etc/nginx/cert/certbook.key;
    ssl_session_timeout 5m;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_prefer_server_ciphers on;
    # ssl证书配置结束 

    location / {
        root   /home/visualization;
        index  index.html index.htm;
    }

    location /dev {
        # 前端/dev请求代理到后端https://xxx.xxx/
        proxy_pass https://xxx.xxx/;
        
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP  $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_connect_timeout   1;
        proxy_buffering off;
        chunked_transfer_encoding off;
        proxy_cache off;
        proxy_send_timeout      30m;
        proxy_read_timeout      30m;
        client_max_body_size    500m;

        access_log /var/log/nginx/dev_access.log;
        error_log /var/log/nginx/dev_error.log;
    }
}

docker-entrypoint.sh内容
文件目的:动态改变nginx配置文件的代理地址,具体到改某一行
1、https://xxx.xxx/为后端接口地址,默认地址
2、sed -i ‘21c ‘“$apiUrl”’’ /etc/nginx/conf.d/default.conf
例如:将nginx.conf配置文件中的21行替换成某个值

#!/usr/bin/env bash

API_BASE_PATH=$API_BASE_PATH;
if [ -z "$API_BASE_PATH" ]; then
    API_BASE_PATH="https://xxx.xxx/";
fi

apiUrl="proxy_pass  $API_BASE_PATH;"
sed -i '21c '"$apiUrl"'' /etc/nginx/conf.d/default.conf
sed -i '73c '"$apiUrl"'' /etc/nginx/conf.d/default.conf

nginx -g "daemon off;"

整体文件目录如下:

在这里插入图片描述

4、打包镜像、运行容器

如果本地没有Docker环境,以下操作则在服务器执行:
1、将项目上传至云服务器,并建立项目文件夹(项目的dist以及node_modules文件夹不需要上传)
2、在远程服务器端cd到项目根目录中
3、构建 Docker 镜像

// hello是指的镜像名称
// 1.0.0是镜像的版本
docker build . -t hello:1.0.0

4、运行容器

//方式一:
// contanier_hello为容器名称
// -p 9090:80  将容器里面的80端口映射到宿主机的8080端口,80端口就是nginx里面配置,多个端口多个配置,必须确保服务器已经开了此端口
docker run -d --name contanier_hello -p 8080:80 hello:1.0.0

//方式二:
// 运行容器的时候改变nginx代理地址
// -e API_BASE_PATH就是上面sh文件中定义的变量 把nginx的后端接口地址改为http://www.baidu.com,这个地址一定不要乱写格式
docker run -d --name contanier_hello -p 8080:80 -e "API_BASE_PATH=http://www.baidu.com" hello:1.0.0

5、这样我们就已经可以运行访问啦

在这里插入图片描述

6、[扩展] 发布本地镜像到私服镜像库
*** 前提需要去搭建阿里云或者腾讯云的registry
1、输入网址https://cr.console.aliyun.com/cn-hangzhou/repositories
2、注册账号
3、创建命名空间
4、创建镜像仓库
5、选择刚创建的命名空间,输入仓库信息

在这里插入图片描述

docker login --username=xxxxx registry.cn-hangzhou.aliyuncs.com
docker push 镜像名称:版本

二、通过Jenkins自动构建

此步骤是基于第一步中的(1、2、3),再进行如下操作
前提:服务器已经搭建好了Jenkins
特别注意:在运行Jenkins容器的时候一定要把宿主机的Docker进行映射,因为会在Jenkins容器里面使用dokcer命令,不然会找不到,怎么查看自己有没有进行映射?进入jenkins容器里面输入docker -v看是否有版本信息,如果没有则需要删除容器重新run,例如:

docker run -d -uroot -p 10000:8080 -p 50000:50000 --name jenkins \
-v /home/jenkins_home:/var/jenkins_home \
-v /home:/home \
-v /etc/localtime:/etc/localtime \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /usr/bin/docker:/usr/bin/docker \
jenkins/jenkins:lts

-v /var/run/docker.sock:/var/run/docker.sock
-v /usr/bin/docker:/usr/bin/docker
以上2句就是把Dcoker映射进容器里面

1、创建Jenkins任务

在这里插入图片描述
2、配置General
在这里插入图片描述
3、配置Shell变量
在这里插入图片描述
4、配置git源码(项目地址的git)
在这里插入图片描述
5、配置构建环境
在这里插入图片描述
6、配置Shell执行脚本

#!/bin/bash  
docker -v

CONTAINER=${container_name}  
PORT=${port}  

# 检查同名容器是否存在并删除
if docker ps -a --filter "name=$CONTAINER" --format '{{.ID}}' | xargs docker inspect --format='{{json .State.Running}}' | grep -qEe true; then
  docker stop $CONTAINER && docker rm -f $CONTAINER
fi

# 删除之前构建的镜像
docker images | grep "${image_name}" | awk '{print $3}' | xargs docker rmi -f

# 构建镜像并添加标签
docker build --no-cache -t ${image_name}:${tag} .

# 移除「依赖 none 镜像」
if docker images --filter 'dangling=true' -q --no-trunc; then
  docker rmi $(docker images --filter 'dangling=true' -q --no-trunc)
fi

# run docker image  
docker run -d --name $CONTAINER -p $PORT:80 -p 9091:443 --restart always  ${image_name}:${tag}

echo '================开始推送镜像================'
# 具体登录到哪个私服,看你们创建是哪个平台阿里云、腾讯云等
docker login --username=账号 --password=密码 registry.cn-hangzhou.aliyuncs.com
docker push ${image_name}:${tag} 
echo '================结束推送镜像================'

7、注意:在运行容器时,端口一定不要与其他容器映射出来的端口一样,会被占用

如上面的-p 9091:443是将容器的443端口映射到宿主机的9091,那么宿主机中的容器一定不能有9091端口,唯一的,再映射端口时也要注意服务器要开通此端口

8、以上都配置完成之后便可以点击构建啦,会自动执行拉取代码、项目打包、构建镜像、运行容器、发布镜像

9、别人若想使用你的镜像,则可以拉取运行:

docker pull 远程镜像名称:[镜像版本号]
运行容器:
//方式一:
// contanier_hello为容器名称
// -p 9090:80  将容器里面的80端口映射到宿主机的8080端口,80端口就是nginx里面配置,多个端口多个配置,必须确保服务器已经开了此端口
docker run -d --name contanier_hello -p 8080:80 hello:1.0.0

//方式二:
// 运行容器的时候改变nginx代理地址,后端想使用前端代码本地运行请求自己的本地ip时可以采用这种方式
// -e API_BASE_PATH就是上面sh文件中定义的变量 把nginx的后端接口地址改为http://www.baidu.com,这个地址一定不要乱写格式,否则nginx会解析不出来,导致报错
docker run -d --name contanier_hello -p 8080:80 -e "API_BASE_PATH=http://www.baidu.com" hello:1.0.0

【博文:版本二,无需本地存储证书,进行容器映射】

🚀 🚀 🚀 🚀 ----- 大功告成----- 🚀 🚀 🚀 🚀

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/26090.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

校园高校共享单车管理系统nodejs+vue+express

设计的管理员的详细功能见下图,管理员登录进入本人后台之后,管理单车和区域,审核租赁订单和还车订单,收取租赁费用,查看单车租赁统计信息。 vue的文件结构其实就是一个index.html 中间的内容,用的是vue&am…

同步阻塞与异步非阻塞

同步阻塞消息处理 假如有这样一个系统功能,客户端提交Event至服务器,服务器接收到客户请求之后开辟线程处理客户请求,经过比较复杂的业务计算后将结果返回给客户端 以上设计存在几个显著的缺陷,具体如下。同步Event提交&#xf…

Python学习36:文本分析与加密

类型:字符串‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬ 描述‪‬‪…

Vue.js 中的路由是什么?如何使用路由?

Vue.js 中的路由是什么?如何使用路由? 在 Vue.js 中,路由是指为不同的 URL 地址提供不同的页面内容或视图的机制。Vue.js 中的路由可以使用 Vue Router 库来实现,它是 Vue.js 官方提供的路由管理库。 Vue Router 简介 Vue Route…

海绵城市智慧监测系统功能、适用范围有哪些?

一、海绵城市在线监测系统拓扑图 海绵城市在线监测系统是通过RTU使用3G/4G信号进行无线传输等方式,将温度、水位、风速、风向、雨量、色度、浊度等数据传输到在线监测平台。经过软件平台的系统性处理后再通过LED显示屏直观、快捷的展现给用户。用户也可以通过电脑、…

如何使用Node.js REPL

目录 1、Nodejs REPL 2、_特殊变量 3、向上箭头键 4、点命令 5、从JavaScript文件运行REPL 1、Nodejs REPL REPL代表Read-Evaluate-Print-Loop,是交互式解释器。 node命令是我们用来运行Node.js脚本的命令: node script.js 如果我们运行node命令…

Unity WebGL打包配置本地服务器

第一步打包 1)、先对Player Setting进行设置 2)、设置打包的窗口大小 3)、遇到异常以及压缩格式 第一个启用异常,指用户指定在运行时意外的代码行为(通常被认为错误)如何被处理,有三个选项…

3.java高级之GUI编程

1.gui (graphical user interface) awt sun公司最早的gui,不美观,不兼容各平台swing : awt升级2.顶层容器(只有一个)(其他的只能放这里)Jframe Jdialog对话框 Jwindow(x) //在main方法写fnew Jframe(); f.setSize(300,300); //设置大小f.setTitle("hello"); //设置…

【linux】web基础与HTTP协议

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 web基础与HTTP协议 一、DNS/HTML1.域名的概述2.域名注册3.网页的概念4.HTML概述5.网页基本标签 二、web基础1.web概述2.静态网页3.静态网页特点4.动态网页5.动态网页的特点 三…

redis数据持久化

Redis是基于内存的,如果不想办法将数据保存在硬盘上,一旦Redis重启(退出/故障),内存的数据将会全部丢失。(业务库中缓存的数据 , 存储的一些重要的标签, 状态数据) 我们肯定不想Redis里头的数据由于某些故障全部丢失(导致所有请求都走MySQL)&…

python基础----05-----函数的多返回值、函数的多种参数使用形式、函数作为参数传递、lambda匿名函数

一 函数的多返回值 if __name__ __main__:# 演示使用多个变量,接收多个返回值def test_return ():return 1,hello,Truex,y,z test_return()print(x)print(y)print(z)1helloTrue二 函数的多种参数使用形式 分为以下四种。 2.1 位置参数 位置参数调用函数时根据…

大数据分析案例-基于决策树算法构建世界杯比赛预测模型

🤵‍♂️ 个人主页:艾派森的个人主页 ✍🏻作者简介:Python学习者 🐋 希望大家多多支持,我们一起进步!😄 如果文章对你有帮助的话, 欢迎评论 💬点赞&#x1f4…

【计算机网络详解】——应用层(学习笔记)

📖 前言:应用层是计算机网络体系结构的最顶层,是设计和建立计算机网络的最终目的,也是计算机网络中发展最快的部分。在本文中,我们以一些经典的网络应用为例来学习有关网络应用的原理、协议和实现方面的知识。 目录 &a…

12.数据结构之AVL树

前言 提到平衡二叉查找树,不得不提二叉查找树。二叉查找树,说简单点,其实就是将我们的数据节点,有序的维护为一个树形结构。这样我们查的时候,那么我们查找某个节点在不在集合中的时间复杂度实际上就是树的高度。如果…

HNU-操作系统OS-实验Lab7

OS_Lab7_Experimental report 湖南大学信息科学与工程学院 计科 210X wolf (学号 202108010XXX) 实验目的 理解操作系统的同步互斥的设计实现;理解底层支撑技术:禁用中断、定时器、等待队列;在ucore中理解信号量(semaphore)机制的具体实现;理解管程机制,在ucore内…

在linux服务器中对R语言中for循环设置多核运行

1 问题 在R中构建了for循环,由于循环过多,运行速度过慢,且不同循环之间是并行关系,拟通过多核运行可以解决此问题。 2 代码设置 2.1 shell脚本中的设置 b.sh export OPENBLAS_NUM_THREADS8Rscript ./..._1.R \2.2 R代码中的设…

python数据可视化-matplotlib学习总结

目录 (一)常见的图形 1、趋势图(直线图):plot() 2、散点图:scatter(): (二)统计图形 1、柱状图:bar( 2、条形图:barh() 3、直方图&#xff…

【ZLM】ZLM源码阅读一

目录 初始化 RTP RTSP RTMP TCPServer的初始化 参考文档 初始化 RTP RTSP RTMP TCPServer的初始化 参考文档 本文参考: (17条消息) 《ZLToolKit源码学习笔记》(20)网络模块之TcpServer_秦时小的博客-CSDN博客 RTP https://blog.csdn.…

探秘 | 如何分辨内网和外网?

目录 💡 什么是外网IP、内网IP? 💡 对于自有路由器上网的用户,可以这样理解外网IP、内网IP 💡 几个大家经常会问的问题 什么是外网IP、内网IP?很多用户都有一个疑惑,如果不使用路由器拨号上网…

Redis实现分布式锁的原理:常见问题解析及解决方案、源码解析Redisson的使用

0、引言:分布式锁的引出 锁常常用于多线程并发的场景下保证数据的一致性,例如防止超卖、一人一单等场景需求 。通过加锁可以解决在单机情况下安全问题,但是在集群模式下就不行了。集群模式,即部署了多个服务器、并配置了负载均衡后…