前言 🚀 需提前安装环境及知识点:
1、Docker搭建及基础操作
2、DockerFile文件描述
3、Jenkins搭建及基础点
🚀 目的:
将我们的前端项目打包成一个镜像容器并自动发布部署,可供随时pull访问,动态修改Api
一、手动部署镜像及容器 1、在当前项目的根目录创建Dockerfile文件并写入如下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 FROM node:14.19 .0 AS builder WORKDIR /visualizationCOPY . . RUN npm install -g cnpm --registry =https://registry.npm.taobao.org RUN cnpm install && npm run build FROM nginxCOPY docker/nginx.conf /etc/nginx/conf.d/default.confCOPY docker/docker-entrypoint .sh /docker-entrypoint .sh WORKDIR /home/visualizationCOPY --from =builder /visualization/dist . RUN chmod +x /docker-entrypoint .sh
代码片段详细描述:
注意: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/nginx.conf /etc/nginx/conf.d/default.conf 2、COPY docker/docker-entrypoint.sh /docker-entrypoint.sh 将docker文件夹下的 Nginx 配置文件、sh文件复制到对应的位置中 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文件,忽略文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 node_modules .DS_Store dist .lock-wscript build/Release .dockerignore Dockerfile *docker-compose * logs *.log .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中的代理请求地址
nginx.conf内容
~根据项目情况做出修改,gzip配置前端无则可删除
~ /dev是前端代理跨域的基准地址,要保持统一,代理到后端的地址,做代理的目的是后面可以根据容器run动态改变proxy_pass地址
~如果项目无https则可删除443监听
~有https则需要配置证书ssl_certificate、ssl_certificate_key,此文件的路径为后面 运行容器时(run) -v将宿主机的目录映射至容器,就是容器的目录
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 server { listen 80 ; listen [::]:80 ; server_name localhost; gzip on; gzip_min_length 1 k; 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 { 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 30 m; proxy_read_timeout 30 m; client_max_body_size 500 m; 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 on; gzip_min_length 1 k; 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_certificate /etc/nginx/cert/certbook_bundle.pem; ssl_certificate_key /etc/nginx/cert/certbook.key; ssl_session_timeout 5 m; 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; location / { root /home/visualization; index index.html index.htm; } location /dev { 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 30 m; proxy_read_timeout 30 m; client_max_body_size 500 m; 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行替换成某个值
3、CERT表示:变量存在时会将https注释,以免找不到https证书报错,主要用于本地run的时候需要
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 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 certOr="#" if [ -n "$CERT " ]; then sed -i '45c ' "$certOr " '' /etc/nginx/conf.d/default.conf sed -i '46c ' "$certOr " '' /etc/nginx/conf.d/default.conf sed -i '59c ' "$certOr " '' /etc/nginx/conf.d/default.conf sed -i '60c ' "$certOr " '' /etc/nginx/conf.d/default.conf fi nginx -g "daemon off;"
整体文件目录如下:
4、打包镜像、运行容器
如果本地没有Docker环境,以下操作则在服务器执行:
1、将项目上传至云服务器,并建立项目文件夹(项目的dist以及node_modules文件夹不需要上传)
2、在远程服务器端cd到项目根目录中
3、构建 Docker 镜像
1 2 3 // hello是指的镜像名称 // 1.0 .0 是镜像的版本 docker build . -t hello:1.0 .0
运行容器
-v /data/nginx/cert:/etc/nginx/cert 是指将宿主机的data/nginx/cert映射到容器的etc/nginx/cert文件夹,上面的nginx.conf证书路径需要,若不需要https则忽略
-e “CERT=no” 表示无https证书的情况下,会默认注释nginx.conf里面443监听,有证书则配置上面-v就行了,本地运行一定要加 1 2 3 4 5 6 7 8 9 //方式一: // contanier_hello为容器名称 // -p 9090 :80 将容器里面的80 端口映射到宿主机的8080 端口,80 端口就是nginx里面配置,多个端口多个配置,必须确保服务器已经开了此端口 docker run -d --name contanier_hello -p 8080 :80 -v /data /nginx/cert:/etc/nginx/cert hello:1.0 .0 //方式二: // 运行容器的时候改变nginx代理地址 // -e API_BASE_PATH就是上面sh文件中定义的变量 把nginx的后端接口地址改为http://www.baidu.com docker run -d --name contanier_hello -p 8080 :80 -v /data /nginx/cert:/etc/nginx/cert -e "API_BASE_PATH=http://www.baidu.com" hello:1.0 .0
4、这样我们就已经可以运行访问啦
5**、[扩展] 发布本地镜像到私服镜像库**
前提需要去搭建阿里云或者腾讯云的registry
1、输入网址https://cr.console.aliyun.com/cn-hangzhou/repositories
2、注册账号
3、创建命名空间
4、创建镜像仓库
5、选择刚创建的命名空间,输入仓库信息
1 2 docker login --username =xxxxx registry.cn-hangzhou .aliyuncs.com docker push 镜像名称:版本
二、通过Jenkins自动构建 此步骤是基于第一步中的(1、2、3),再进行如下操作
前提:服务器已经搭建好了Jenkins
特别注意:在运行Jenkins容器的时候一定要把宿主机的Docker进行映射,因为会在Jenkins容器里面使用dokcer命令,不然会找不到,怎么查看自己有没有进行映射?进入jenkins容器里面输入docker -v看是否有版本信息,如果没有则需要删除容器重新run,例如:
1 2 3 4 5 6 7 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执行脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 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} .if docker images --filter 'dangling=true' -q --no-trunc ; then docker rmi $ (docker images --filter 'dangling=true' -q --no-trunc ) fi docker run -d --name $CONTAINER -p $PORT:80 -p 9091 :443 -v /data /nginx/cert:/etc/nginx/cert --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、别人若想使用你的镜像,则可以拉取运行:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 docker pull 远程镜像名称:[镜像版本号] 运行容器: // -e "CERT=no" 无证书需要加上,会隐藏nginx配置文件中的443 //方式一: // 1 、contanier_hello为容器名称 // 2 、-p 9090 :80 将容器里面的80 端口映射到宿主机的8080 端口,80 端口就是nginx里面配置,多个端口多个配置,必须确保服务器已经开了此端口 docker run -d --name contanier_hello -p 8080 :80 -e "CERT=no" hello:1.0 .0 //方式二: // 1 、运行容器的时候改变nginx代理地址,后端想使用前端代码本地运行请求自己的本地ip时可以采用这种方式 // 2 、-e API_BASE_PATH就是上面sh文件中定义的变量 把nginx的后端接口地址改为http://www.baidu.com // 3 、** API_BASE_PATH一定要写正确,别乱写格式,nginx会识别不出来 docker run -d --name contanier_hello -p 8080 :80 -e "API_BASE_PATH=http://www.baidu.com" -e "CERT=no" hello:1.0 .0
🚀 🚀 🚀 🚀 ----- 大功告成----- 🚀 🚀 🚀 🚀