当前位置:   article > 正文

Docker(五):Docker 企业实战之部署SpringBoot项目_docker部署springboot

docker部署springboot

最终目标

通过docker-maven-plugin插件实现springboot项目自动构建镜像并将镜像推送到公司docker仓库,以及通过shell脚本从docker仓库拉取项目最新镜像后启动项目,完成springboot项目的部署

构建镜像文件

构建docker镜像可以使用两种方式

  • 第一种是将构建信息指定到 POM 中,支持FROM, ENTRYPOINT, CMD, MAINTAINER 以及 ADD等dockerfile指令
  • 第二种是使用Dockerfile 构建,支持所有dockerfile命令(常用方式!!!)

注意:但是如果使用 VOLUME 或其他 Dockerfile 中的命令的时候,只能使用第二种方式,并需要在 POM 中配置 dockerDirectory 来指定Dockerfile路径

POM文件

  1. <!-- 设置编码及版本号 -->
  2. <properties>
  3. <!-- 根据测试验证Mac OS无法使用 1.2.0版本,为了统一便于发布现决定使用1.1.1版本 -->
  4. <docker.maven.plugin.version>1.1.1</docker.maven.plugin.version>
  5. <!-- docker registry 私有仓库地址-->
  6. <docker.registry>xx.xxx.xx.xx:5000</docker.registry>
  7. </properties>
  8. <build>
  9. <pluginManagement>
  10. <plugins>
  11. <!--maven-docker 镜像生成以及自动推送到私有仓库 -->
  12. <plugin>
  13. <groupId>com.spotify</groupId>
  14. <artifactId>docker-maven-plugin</artifactId>
  15. <version>${docker.maven.plugin.version}</version>
  16. <configuration>
  17. <!-- Dockerfile所在目录,默认值为target/classes,即项目构建输出的目录 -->
  18. <dockerDirectory>${project.build.outputDirectory}
  19. </dockerDirectory>
  20. <!-- 最终生成的镜像名称,名称规则:私有服务器IP:端口/项目名:版本 -->
  21. <imageName>${docker.registry}/${project.artifactId}:${project.version}
  22. </imageName>
  23. <!-- 项目版本 -->
  24. <imageTags>
  25. <imageTag>${project.version}</imageTag>
  26. </imageTags>
  27. <!-- 这里是项目构建完成生成的jar包资源所在位置-->
  28. <resources>
  29. <resource>
  30. <targetPath>/</targetPath>
  31. <!-- 项目构建输出目录,默认为target/ ,即项目最终jar包所在位置-->
  32. <directory>${project.build.directory}</directory>
  33. <!-- ${project.build.finalName}表示输出项目jar包名称; 缺省时值为${project.artifactId}-${project.version}
  34. ${project.artifactId}: 当前项目的artifactId
  35. -
  36. ${project.version}: 当前项目的 version
  37. -->
  38. <include>${project.build.finalName}.jar</include>
  39. </resource>
  40. </resources>
  41. <!-- Docker registry 私有仓库地址 -->
  42. <registryUrl>${docker.registry}</registryUrl>
  43. <!-- 是否自動推送到Registry Server,true表示自动push到远程仓库,建議手動推送 -->
  44. <pushImage>true</pushImage>
  45. <!-- 对应本地maven setting xml文件 中server节点下server id为docker registry-->
  46. <serverId>docker-registry</serverId>
  47. </configuration>
  48. </plugin>
  49. </plugins>
  50. </pluginManagement>
  51. <!-- resource配置会导致font呈现乱码 -->
  52. <!-- <resources>
  53. <resource>
  54. <directory>src/main/resources</directory> <filtering>true</filtering>
  55. </resource>
  56. </resources>
  57. -->
  58. </build>
  1. <server>
  2. <id>docker-registry</id>
  3. <username>demo</username>
  4. <password>demo</password>
  5. <configuration>
  6. <email>xxx@mail.163.com</email>
  7. </configuration>
  8. </server>

 注意: pom中对应的<serverId>对应的值也需要在maven的setting.xml中配置私有仓库认证信息 

Dokerfile文件

  1. # 基于jdk镜像
  2. # jdk 版本=> anapsix/alpine-java:8_jdk_unlimited
  3. FROM anapsix/alpine-java:8_server-jre_unlimited
  4. # 将本地文件夹挂载到当前容器
  5. VOLUME /tmp
  6. # 配置主机和Docker服务时区和时间同步
  7. ENV TZ=Asia/Shanghai
  8. RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
  9. # 维护人
  10. MAINTAINER jqy <xxx.xxx@mail.163.com>
  11. # 设置语言
  12. # 查看Docker支持的語言: locale -a, C.UTF-8可以支持中文。
  13. ENV LANG C.UTF-8
  14. # 开放端口
  15. EXPOSE 67000
  16. # 设置Java堆栈环境变量值(默认为空,建议由启动的shell脚本设置对应参数值)
  17. ENV JAVA_OPTS ""
  18. # 设置JVM Server环境变量值(默认为空,建议由启动的shell脚本设置对应参数值)
  19. ENV JVM_SERVER_OPTS=""
  20. # 拷贝文件到容器,也可以直接写成ADD
  21. # 注意:如果使用*匹配文件,則在每次打包動作中都包含一次Clean動作,以保存文件的唯一性。
  22. # 将项目构建生成的xxx-*.jar包复制到docker容器且名称为app.jar
  23. #ADD xxx-1.0.0-RELEASE.jar /app.jar
  24. ADD xxx-*.jar /app.jar
  25. # 配置容器启动后执行的命令
  26. #ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
  27. ENTRYPOINT exec java $JAVA_OPTS $JVM_SERVER_OPTS -Djava.security.egd=file:/dev/./urandom -jar /app.jar

Idea配置Maven打包以及构建镜像命令

Run Configurations -> Goals:mvn clean package docker:build

注意:由于pom文件已配置自动推送,构建完镜像后自动推送到私有仓库,所以命令不需要显示执行docker push命令

  • mvn clean package docker:build :直接将本地项目打包构建到docker镜像(若为maven聚合工程,则必须通过父项目打包构建,若单独在子项目构建,可能存在其他module下代码没有及时更新,如mapper)
  • mvn clean deploy docker:build :直接将本地项目经过clean、compile、test、package、install、depoy后构建docker镜像(并且推送到maven仓库)
  • 注意
  • 增加clean是确保项目从一个干净的状态开始构建,并消除可能存在的旧的构建产物和临时文件;
  • mvn package/deploy 这样的命令,可能会忽略掉清理步骤并生成缓存的构建产物,在特定情况下可能会导致构建结果不一致或不可预测。
  • 对于自身项目直接在父项目中直接package不用推送maven远程仓库(因为自己项目不会被别人引用),但对于公共项目需要deploy

启动

企业实际开发中,通常会采用shell脚本命令执行docker命令,包括创建删除容器镜像等

  1. #/bin/bash
  2. # author: sb
  3. # Description: Use docker shell to start micro-server.
  4. # 注意:
  5. # 此脚本必须预先执行如下指令:
  6. # 1. $PROJECTNAME_VERSION
  7. # 2. 服务器确保存在/data/gc/log文件夾
  8. # JVM 默認常量
  9. # JAVA_OPTS
  10. JAVA_OPTS_6G="JAVA_OPTS=-Xmx1344M -Xms1344M -Xmn448M -XX:MaxMetaspaceSize=192M -XX:MetaspaceSize=192M"
  11. # JVM_SERVER_OPTS
  12. 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";
  13. # 判断是否设置镜像版本以及日志文件
  14. if [ ! -n "$PROJECTNAME_VERSION" ]; then
  15. echo "Please set PROJECTNAME_VERSION at first"
  16. exit -1
  17. fi
  18. if [ ! -d "/data/gc/log/" ];then
  19. mkdir /data/gc/log
  20. echo 'the directory /data/gc/log is created.'
  21. else
  22. echo 'the directory /data/gc/log is existed.'
  23. fi
  24. # 启动所有服务
  25. function start_all()
  26. {
  27. start_demo_web
  28. start_demo_report
  29. }
  30. #docker run 命令参数说明
  31. # #docker run
  32. # -p 77770:77770 #将容器的端口映射到主机(服务器)端口,即我们可以通过主机端口进行访问应用
  33. # -dit # -d 后台模式,-it 交互对话模式,结合使用则保证容器不会退出,一直在后台运行
  34. # -e "SPRING_PROFILES_ACTIVE=test2" #-e 设置使用的config配置文件;
  35. # -e "$JAVA_OPTS_6G" #-e 设置环境变量;
  36. # -e "$JVM_SERVER_OPTS" #-e 设置环境变量;
  37. # -v /data/gc/log:/var/app/gc # 将宿主机的目录挂载到容器里,语法为“docker run -v /宿主机目录:/容器目录”
  38. # --name=demo-web #--name 为容器指定一个名称
  39. # -h "demo-web" #--h 设置一个主机名称
  40. # --add-host peer1:10.112.112.112 #添加自定义主机到IP的映射(host:ip)
  41. # --add-host peer2:10.112.112.112
  42. # -v /data/cdp-logs/demo:/logs #绑定挂载卷
  43. # 仓库ip:5000/demo-web:$PROJECTNAME_VERSION #镜像名
  44. # 啟動 Demo_web
  45. # 必須指定: $PROJECTNAME_VERSION
  46. # 60290
  47. function start_demo_web ()
  48. {
  49. echo 'starting Demo_web'
  50. 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`
  51. echo 'Demo_web started'
  52. }
  53. # 啟動 Demo_ report
  54. # 必須指定: $PROJECTNAME_VERSION
  55. # 端口: 60295
  56. function start_demo_report ()
  57. {
  58. echo 'starting Demo_ report'
  59. 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`
  60. echo 'Demo_ report started'
  61. }
  62. # 刪除 Demo web 容器
  63. function remove_container_demo_web ()
  64. {
  65. echo 'starting remove container Demo_web'
  66. # stop and rm
  67. docker stop demo-web && docker rm -f demo-web
  68. echo 'contianer Demo_web removed'
  69. }
  70. # 刪除 Demo web 鏡像
  71. function remove_image_demo_web ()
  72. {
  73. echo 'starting remove image Demo_web'
  74. docker rmi 私有仓库ip:5000/demo-web:$PROJECTNAME_VERSION
  75. echo 'image Demo_web removed'
  76. }
  77. # 刪除 Demo_ report 容器
  78. function remove_container_demo_report ()
  79. {
  80. echo 'starting remove container Demo_ report'
  81. docker rm -f demo-report
  82. echo 'contianer Demo_ report removed'
  83. }
  84. # 刪除 Demo_ report 鏡像
  85. function remove_image_demo_report ()
  86. {
  87. echo 'starting remove image Demo_ report'
  88. docker rmi 私有仓库ip:5000/demo-report:$PROJECTNAME_VERSION
  89. echo 'image Demo_ report removed'
  90. }
  91. # 啟動入口
  92. case "$1" in
  93. all)
  94. # 啟動所有 Demo 應用
  95. start_all
  96. ;;
  97. web)
  98. # 僅啟動 Demo Web
  99. start_demo_web
  100. ;;
  101. report)
  102. # 僅啟動 report
  103. start_demo_report
  104. ;;
  105. remove_container_web)
  106. # 移除 Demo web 容器
  107. start_demo_web
  108. start_demo_report
  109. ;;
  110. remove_all_containers)
  111. # 移除所有
  112. remove_container_Demo_web
  113. remove_container_Demo_report
  114. ;;
  115. remove_image_web)
  116. # 移除 web 鏡像
  117. remove_container_Demo_web
  118. remove_image_Demo_web
  119. ;;
  120. remove_image_report)
  121. # 移除 report 鏡像
  122. remove_container_Demo_report
  123. remove_image_Demo_report
  124. ;;
  125. remove_all_images)
  126. # 移除所有鏡像
  127. remove_container_Demo_web
  128. remove_image_Demo_web
  129. remove_container_Demo_report
  130. remove_image_Demo_report
  131. ;;
  132. *)
  133. 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"
  134. exit -2
  135. ;;
  136. esac

注意:仓库ip:5000/demo-web:$PROJECTNAME_VERSION表示的是发布在私有仓库中的最新docker镜像,如果存在,则直接执行docker run启动;若不存在,则会默认通过docker pull拉取镜像再执行docker run命令

其中shell启动脚本命令中关于JVM参数设置说明

  1. # JVM 默認常量
  2. # JAVA_OPTS
  3. JAVA_OPTS_6G="
  4. JAVA_OPTS= #JAVA_OPTS用来设置JVM相关运行参数的变量
  5. -Xmx1344M #java Heap堆最大内存
  6. -Xms1344M #java 初始Heap 堆内存大小
  7. -Xmn448M #young Generation的堆内存大小,一般设置为Xmx的三分之一或者四分之一
  8. -XX:MaxMetaspaceSize=192M #设置元空间最大大小,java8后永久代称为元空间,相比永久代元空间不受制于堆内存而是基于操作系统内存,但仍需要设置上限
  9. -XX:MetaspaceSize=192M" #设置元空间大小
  10. # JVM_SERVER_OPTS
  11. JVM_SERVER_OPTS=
  12. "JVM_SERVER_OPTS=
  13. -server #指示JVM以服务器模式启动,用于优化长时间运行的服务器应用程序
  14. -XX:+DisableExplicitGC #禁止显式执行GC,不允许调用System.gc()的方法,否则并发度高的情况下STW的短暂停顿效果就被强化成了长时间停顿甚至对外展示效果就是服务不响应
  15. -XX:+UseParNewGC #设置年轻代为多线程收集。可与CMS收集同时使用。在serial基础上实现的多线程收集器。
  16. -XX:+UseConcMarkSweepGC #基于标记清除算法实现的多线程老年代垃圾回收器。CMS为响应时间优先的垃圾回收器,适用于注重服务响应时间的应用
  17. -XX:+UseCMSInitiatingOccupancyOnly #在使用CMS收集器的情况下,指定老年代被使用的内存空间的阈值,达到该阈值则触发Full GC,参数CMSInitiatingOccupancyFraction才会生效
  18. -XX:CMSInitiatingOccupancyFraction=70 #回收阈值
  19. -XX:+ExplicitGCInvokesConcurrentAndUnloadsClasses #触发Full GC时,并发清理阶段的效率比较高,与CMS收集器一起使用
  20. -XX:+CMSClassUnloadingEnabled #在CMS收集器中,默认不对永久代进行垃圾回收。如果希望对永久代进行垃圾回收,需要开启该选项
  21. -XX:+ParallelRefProcEnabled #开启尽可能并行处理Reference对象,建议开启
  22. -XX:+CMSScavengeBeforeRemark #在CMS的重新标记阶段之前执行年轻代(Young GC)垃圾回收,减少需要标记的对象数量,降低CMS重新标记的时间开销。建议开启。
  23. -XX:+HeapDumpOnOutOfMemoryError #当发生 OOM时,自动转储堆内存快照Dump文件,缺省情况未指定目录时,JVM 会创建一个名称为 java_pidPID.hprof 的堆 dump 文件在 JVM 的工作目录下
  24. -XX:+PrintGCDetails #打印详细的GC日志
  25. -XX:+PrintGCTimeStamps
  26. -XX:+PrintHeapAtGC #在GC前后打印GC日志
  27. -XX:+PrintGCApplicationStoppedTime #打印应用暂停时间
  28. -XX:+PrintGCDateStamps #GC日志打印时间戳信息
  29. -XX:ErrorFile=/var/app/gc/hs_err_pid%p.log
  30. -XX:HeapDumpPath=/var/app/gc #指定OOM时堆内存转储快照位置
  31. -Xloggc:/var/app/gc/gc%t.log" #指定GC日志文件的路径和名称,其中%t表示当前时间。
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/681629
推荐阅读
相关标签
  

闽ICP备14008679号