赞
踩
通过docker-maven-plugin插件实现springboot项目自动构建镜像并将镜像推送到公司docker仓库,以及通过shell脚本从docker仓库拉取项目最新镜像后启动项目,完成springboot项目的部署
构建docker镜像可以使用两种方式
注意:但是如果使用 VOLUME 或其他 Dockerfile 中的命令的时候,只能使用第二种方式,并需要在 POM 中配置 dockerDirectory 来指定Dockerfile路径
- <!-- 设置编码及版本号 -->
- <properties>
- <!-- 根据测试验证Mac OS无法使用 1.2.0版本,为了统一便于发布现决定使用1.1.1版本 -->
- <docker.maven.plugin.version>1.1.1</docker.maven.plugin.version>
-
- <!-- docker registry 私有仓库地址-->
- <docker.registry>xx.xxx.xx.xx:5000</docker.registry>
- </properties>
-
- <build>
- <pluginManagement>
- <plugins>
-
- <!--maven-docker 镜像生成以及自动推送到私有仓库 -->
- <plugin>
- <groupId>com.spotify</groupId>
- <artifactId>docker-maven-plugin</artifactId>
- <version>${docker.maven.plugin.version}</version>
- <configuration>
- <!-- Dockerfile所在目录,默认值为target/classes,即项目构建输出的目录 -->
- <dockerDirectory>${project.build.outputDirectory}
- </dockerDirectory>
-
- <!-- 最终生成的镜像名称,名称规则:私有服务器IP:端口/项目名:版本 -->
- <imageName>${docker.registry}/${project.artifactId}:${project.version}
- </imageName>
-
- <!-- 项目版本 -->
- <imageTags>
- <imageTag>${project.version}</imageTag>
- </imageTags>
-
- <!-- 这里是项目构建完成生成的jar包资源所在位置-->
- <resources>
- <resource>
- <targetPath>/</targetPath>
-
- <!-- 项目构建输出目录,默认为target/ ,即项目最终jar包所在位置-->
- <directory>${project.build.directory}</directory>
-
- <!-- ${project.build.finalName}表示输出项目jar包名称; 缺省时值为${project.artifactId}-${project.version}
- ${project.artifactId}: 当前项目的artifactId
- -
- ${project.version}: 当前项目的 version
- -->
- <include>${project.build.finalName}.jar</include>
-
- </resource>
- </resources>
-
- <!-- Docker registry 私有仓库地址 -->
- <registryUrl>${docker.registry}</registryUrl>
- <!-- 是否自動推送到Registry Server,true表示自动push到远程仓库,建議手動推送 -->
- <pushImage>true</pushImage>
- <!-- 对应本地maven setting xml文件 中server节点下server id为docker registry-->
- <serverId>docker-registry</serverId>
- </configuration>
- </plugin>
-
- </plugins>
- </pluginManagement>
-
- <!-- resource配置会导致font呈现乱码 -->
- <!-- <resources>
- <resource>
- <directory>src/main/resources</directory> <filtering>true</filtering>
- </resource>
- </resources>
- -->
- </build>
- <server>
- <id>docker-registry</id>
- <username>demo</username>
- <password>demo</password>
- <configuration>
- <email>xxx@mail.163.com</email>
- </configuration>
- </server>
注意: pom中对应的<serverId>对应的值也需要在maven的setting.xml中配置私有仓库认证信息
# 基于jdk镜像 # jdk 版本=> anapsix/alpine-java:8_jdk_unlimited FROM anapsix/alpine-java:8_server-jre_unlimited # 将本地文件夹挂载到当前容器 VOLUME /tmp # 配置主机和Docker服务时区和时间同步 ENV TZ=Asia/Shanghai RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone # 维护人 MAINTAINER jqy <xxx.xxx@mail.163.com> # 设置语言 # 查看Docker支持的語言: locale -a, C.UTF-8可以支持中文。 ENV LANG C.UTF-8 # 开放端口 EXPOSE 67000 # 设置Java堆栈环境变量值(默认为空,建议由启动的shell脚本设置对应参数值) ENV JAVA_OPTS "" # 设置JVM Server环境变量值(默认为空,建议由启动的shell脚本设置对应参数值) ENV JVM_SERVER_OPTS="" # 拷贝文件到容器,也可以直接写成ADD # 注意:如果使用*匹配文件,則在每次打包動作中都包含一次Clean動作,以保存文件的唯一性。 # 将项目构建生成的xxx-*.jar包复制到docker容器且名称为app.jar #ADD xxx-1.0.0-RELEASE.jar /app.jar ADD xxx-*.jar /app.jar # 配置容器启动后执行的命令 #ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"] ENTRYPOINT exec java $JAVA_OPTS $JVM_SERVER_OPTS -Djava.security.egd=file:/dev/./urandom -jar /app.jar
Run Configurations -> Goals:mvn clean package docker:build
注意:由于pom文件已配置自动推送,构建完镜像后自动推送到私有仓库,所以命令不需要显示执行docker push命令
企业实际开发中,通常会采用shell脚本命令执行docker命令,包括创建删除容器镜像等
- #/bin/bash
- # author: sb
- # Description: Use docker shell to start micro-server.
- # 注意:
- # 此脚本必须预先执行如下指令:
- # 1. $PROJECTNAME_VERSION
- # 2. 服务器确保存在/data/gc/log文件夾
-
- # JVM 默認常量
- # JAVA_OPTS
- JAVA_OPTS_6G="JAVA_OPTS=-Xmx1344M -Xms1344M -Xmn448M -XX:MaxMetaspaceSize=192M -XX:MetaspaceSize=192M"
- # JVM_SERVER_OPTS
- JVM_SERVER_OPTS="JVM_SERVER_OPTS=-server -XX:+DisableExplicitGC -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=70 -XX:+ExplicitGCInvokesConcurrentAndUnloadsClasses -XX:+CMSClassUnloadingEnabled -XX:+ParallelRefProcEnabled -XX:+CMSScavengeBeforeRemark -XX:+HeapDumpOnOutOfMemoryError -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintHeapAtGC -XX:+PrintGCApplicationStoppedTime -XX:+PrintGCDateStamps -XX:ErrorFile=/var/app/gc/hs_err_pid%p.log -XX:HeapDumpPath=/var/app/gc -Xloggc:/var/app/gc/gc%t.log";
-
- # 判断是否设置镜像版本以及日志文件
- if [ ! -n "$PROJECTNAME_VERSION" ]; then
- echo "Please set PROJECTNAME_VERSION at first"
- exit -1
- fi
-
- if [ ! -d "/data/gc/log/" ];then
- mkdir /data/gc/log
- echo 'the directory /data/gc/log is created.'
- else
- echo 'the directory /data/gc/log is existed.'
- fi
-
- # 启动所有服务
- function start_all()
- {
- start_demo_web
- start_demo_report
- }
-
- #docker run 命令参数说明
- # #docker run
- # -p 77770:77770 #将容器的端口映射到主机(服务器)端口,即我们可以通过主机端口进行访问应用
- # -dit # -d 后台模式,-it 交互对话模式,结合使用则保证容器不会退出,一直在后台运行
- # -e "SPRING_PROFILES_ACTIVE=test2" #-e 设置使用的config配置文件;
- # -e "$JAVA_OPTS_6G" #-e 设置环境变量;
- # -e "$JVM_SERVER_OPTS" #-e 设置环境变量;
- # -v /data/gc/log:/var/app/gc # 将宿主机的目录挂载到容器里,语法为“docker run -v /宿主机目录:/容器目录”
- # --name=demo-web #--name 为容器指定一个名称
- # -h "demo-web" #--h 设置一个主机名称
- # --add-host peer1:10.112.112.112 #添加自定义主机到IP的映射(host:ip)
- # --add-host peer2:10.112.112.112
- # -v /data/cdp-logs/demo:/logs #绑定挂载卷
- # 仓库ip:5000/demo-web:$PROJECTNAME_VERSION #镜像名
-
-
- # 啟動 Demo_web
- # 必須指定: $PROJECTNAME_VERSION
- # 60290
- function start_demo_web ()
- {
- echo 'starting Demo_web'
-
- echo `docker run -p 77770:77770 -dit -e "SPRING_PROFILES_ACTIVE=test2" -e "$JAVA_OPTS_6G" -e "$JVM_SERVER_OPTS" -v /data/gc/log:/var/app/gc --name=demo-web -h "demo-web" --add-host peer1:10.112.112.112 --add-host peer2:10.112.112.112 -v /data/cdp-logs/demo:/logs 仓库ip:5000/demo-web:$PROJECTNAME_VERSION`
-
- echo 'Demo_web started'
- }
-
- # 啟動 Demo_ report
- # 必須指定: $PROJECTNAME_VERSION
- # 端口: 60295
- function start_demo_report ()
- {
- echo 'starting Demo_ report'
-
- echo `docker run -p 77770:77770 -dit -e "SPRING_PROFILES_ACTIVE=test2" -e "$JAVA_OPTS_6G" -e "$JVM_SERVER_OPTS" -v /data/gc/log:/var/app/gc --name=demo-report -h "demo-report" --add-host peer1:10.112.112.112 --add-host peer2:10.112.112.112 -v /data/cdp-logs/demo:/logs 仓库ip:5000/demo-web:$PROJECTNAME_VERSION`
-
- echo 'Demo_ report started'
- }
-
- # 刪除 Demo web 容器
- function remove_container_demo_web ()
- {
- echo 'starting remove container Demo_web'
- # stop and rm
- docker stop demo-web && docker rm -f demo-web
- echo 'contianer Demo_web removed'
- }
-
- # 刪除 Demo web 鏡像
- function remove_image_demo_web ()
- {
- echo 'starting remove image Demo_web'
- docker rmi 私有仓库ip:5000/demo-web:$PROJECTNAME_VERSION
- echo 'image Demo_web removed'
- }
-
- # 刪除 Demo_ report 容器
- function remove_container_demo_report ()
- {
- echo 'starting remove container Demo_ report'
- docker rm -f demo-report
- echo 'contianer Demo_ report removed'
- }
-
- # 刪除 Demo_ report 鏡像
- function remove_image_demo_report ()
- {
- echo 'starting remove image Demo_ report'
- docker rmi 私有仓库ip:5000/demo-report:$PROJECTNAME_VERSION
- echo 'image Demo_ report removed'
- }
-
- # 啟動入口
- case "$1" in
- all)
- # 啟動所有 Demo 應用
- start_all
- ;;
- web)
- # 僅啟動 Demo Web
- start_demo_web
- ;;
- report)
- # 僅啟動 report
- start_demo_report
- ;;
-
- remove_container_web)
- # 移除 Demo web 容器
- start_demo_web
- start_demo_report
- ;;
- remove_all_containers)
- # 移除所有
- remove_container_Demo_web
- remove_container_Demo_report
- ;;
- remove_image_web)
- # 移除 web 鏡像
- remove_container_Demo_web
- remove_image_Demo_web
- ;;
- remove_image_report)
- # 移除 report 鏡像
- remove_container_Demo_report
- remove_image_Demo_report
- ;;
-
- remove_all_images)
- # 移除所有鏡像
- remove_container_Demo_web
- remove_image_Demo_web
-
- remove_container_Demo_report
- remove_image_Demo_report
-
- ;;
- *)
- echo "please input start key, all|web|remove_container_web|report|remove_container_report|remove_all_containers|remove_image_web|remove_image_report|remove_all_images"
- exit -2
- ;;
- esac
注意:仓库ip:5000/demo-web:$PROJECTNAME_VERSION表示的是发布在私有仓库中的最新docker镜像,如果存在,则直接执行docker run启动;若不存在,则会默认通过docker pull拉取镜像再执行docker run命令
- # JVM 默認常量
- # JAVA_OPTS
- JAVA_OPTS_6G="
- JAVA_OPTS= #JAVA_OPTS用来设置JVM相关运行参数的变量
- -Xmx1344M #java Heap堆最大内存
- -Xms1344M #java 初始Heap 堆内存大小
- -Xmn448M #young Generation的堆内存大小,一般设置为Xmx的三分之一或者四分之一
- -XX:MaxMetaspaceSize=192M #设置元空间最大大小,java8后永久代称为元空间,相比永久代元空间不受制于堆内存而是基于操作系统内存,但仍需要设置上限
- -XX:MetaspaceSize=192M" #设置元空间大小
-
- # JVM_SERVER_OPTS
- JVM_SERVER_OPTS=
- "JVM_SERVER_OPTS=
- -server #指示JVM以服务器模式启动,用于优化长时间运行的服务器应用程序
- -XX:+DisableExplicitGC #禁止显式执行GC,不允许调用System.gc()的方法,否则并发度高的情况下STW的短暂停顿效果就被强化成了长时间停顿甚至对外展示效果就是服务不响应
- -XX:+UseParNewGC #设置年轻代为多线程收集。可与CMS收集同时使用。在serial基础上实现的多线程收集器。
- -XX:+UseConcMarkSweepGC #基于标记清除算法实现的多线程老年代垃圾回收器。CMS为响应时间优先的垃圾回收器,适用于注重服务响应时间的应用
- -XX:+UseCMSInitiatingOccupancyOnly #在使用CMS收集器的情况下,指定老年代被使用的内存空间的阈值,达到该阈值则触发Full GC,参数CMSInitiatingOccupancyFraction才会生效
- -XX:CMSInitiatingOccupancyFraction=70 #回收阈值
- -XX:+ExplicitGCInvokesConcurrentAndUnloadsClasses #触发Full GC时,并发清理阶段的效率比较高,与CMS收集器一起使用
- -XX:+CMSClassUnloadingEnabled #在CMS收集器中,默认不对永久代进行垃圾回收。如果希望对永久代进行垃圾回收,需要开启该选项
- -XX:+ParallelRefProcEnabled #开启尽可能并行处理Reference对象,建议开启
- -XX:+CMSScavengeBeforeRemark #在CMS的重新标记阶段之前执行年轻代(Young GC)垃圾回收,减少需要标记的对象数量,降低CMS重新标记的时间开销。建议开启。
- -XX:+HeapDumpOnOutOfMemoryError #当发生 OOM时,自动转储堆内存快照Dump文件,缺省情况未指定目录时,JVM 会创建一个名称为 java_pidPID.hprof 的堆 dump 文件在 JVM 的工作目录下
- -XX:+PrintGCDetails #打印详细的GC日志
- -XX:+PrintGCTimeStamps
- -XX:+PrintHeapAtGC #在GC前后打印GC日志
- -XX:+PrintGCApplicationStoppedTime #打印应用暂停时间
- -XX:+PrintGCDateStamps #GC日志打印时间戳信息
- -XX:ErrorFile=/var/app/gc/hs_err_pid%p.log
- -XX:HeapDumpPath=/var/app/gc #指定OOM时堆内存转储快照位置
- -Xloggc:/var/app/gc/gc%t.log" #指定GC日志文件的路径和名称,其中%t表示当前时间。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。