Dockerfile镜像制作教程
本文以实际应用发版为例,详细表述docker镜像的制作过程,其中包括如何实现动态控制应用程序的启动
目录结构介绍
起始目录
package目录
target目录
sh目录
init.sh脚本
作用:创建网络、启动镜像、挂载目录
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 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 | #!/bin/bash # 开始 echo "Info: init start" ## --------------------------------------------------------------------------------- # 容器名称 containerName=online_ccs # 网络名称 networkName=network_test001 # 映射端口(宿主机端口) # Ass-WEB服务端口 port1=8087 # Ass-WEB服务socket端口 port2=9901 # Ass-WECHAT服务端口 port3=8090 # Ccs-WEB服务端口 port4=8089 # Ccs-WECHAT服务端口 port5=8091 # Weixin3rd服务端口 port6=9015 # 挂载根目录(宿主机目录) dir =$( dirname "$PWD" ) # docker服务启动时,自启容器 #rst=${1:-"always"} # docker服务启动时,不启动容器 rst=${1:- "no" } ## --------------------------------------------------------------------------------- # 镜像文件 imageFile= "$dir" /images/img_online_ccs . tar .gz # 镜像名称 imageName=online_ccs:1.4.1.20241113_release # 工作目录(容器目录) workDir= /app ###创建网络的作用,文章后边会补充 # 检查docker的网络名称是否存在network_test001,不存在则创建 res=$(docker network ls -- format '{{.Name}}' | grep $networkName) if [ ! "$res" == "$networkName" ]; then echo "Info: create network [$networkName]" res=$(docker network create --subnet=172.21.0.0 /16 $networkName) if [ ! -n "$res" ]; then echo "Error: create network [$networkName] fail" exit 1 fi fi # 检查docker镜像是否存在 if [ ! -f "$imageFile" ]; then echo "Error: $imageFile file not found" exit 1 fi # 导入docker镜像 echo "Info: import image [$imageFile]" res=$(docker load -i "$imageFile" ) echo "$res" # 运行docker镜像 ###-v的都是挂载的目录,这里主要挂载的是前后端的配置文件、日志文件,实现公共读写的功能 echo "Info: The image [$imageFile] is running" res=$(docker run --name $containerName --restart=$rst --network=$networkName --ip=172.21.0.6 \ -p $port1:8087 \ -p $port2:9901 \ -p $port3:8090 \ -p $port4:8089 \ -p $port5:8091 \ -p $port6:9015 \ - v $ dir /config :$workDir /config \ - v $ dir /java/FS_WEB_ASS/appId .properties:$workDir /tomcat8-ass-cloud-web-8087/webapps/FS_WEB_ASS/WEB-INF/classes/appId .properties \ - v $ dir /java/FS_WEB_ASS/application .properties:$workDir /tomcat8-ass-cloud-web-8087/webapps/FS_WEB_ASS/WEB-INF/classes/application .properties \ - v $ dir /java/FS_WEB_ASS/asr .properties:$workDir /tomcat8-ass-cloud-web-8087/webapps/FS_WEB_ASS/WEB-INF/classes/asr .properties \ - v $ dir /java/FS_WEB_ASS/config .properties:$workDir /tomcat8-ass-cloud-web-8087/webapps/FS_WEB_ASS/WEB-INF/classes/config .properties \ - v $ dir /java/FS_WEB_ASS/logback-spring .xml:$workDir /tomcat8-ass-cloud-web-8087/webapps/FS_WEB_ASS/WEB-INF/classes/logback-spring .xml \ - v $ dir /java/FS_WEB_ASS/mybatis-config .xml:$workDir /tomcat8-ass-cloud-web-8087/webapps/FS_WEB_ASS/WEB-INF/classes/mybatis-config .xml \ - v $ dir /java/FS_WEB_ASS/rocketmq .properties:$workDir /tomcat8-ass-cloud-web-8087/webapps/FS_WEB_ASS/WEB-INF/classes/rocketmq .properties \ - v $ dir /java/FS_WEB_ASS/shardingDataSource .properties:$workDir /tomcat8-ass-cloud-web-8087/webapps/FS_WEB_ASS/WEB-INF/classes/shardingDataSource .properties \ - v $ dir /java/FS_WEB_ASS/spring .properties:$workDir /tomcat8-ass-cloud-web-8087/webapps/FS_WEB_ASS/WEB-INF/classes/spring .properties \ - v $ dir /java/FS_WECHAT_ASS/appId .properties:$workDir /tomcat8-ass-cloud-wechat-8090/webapps/FS_WECHAT_ASS/WEB-INF/classes/appId .properties \ - v $ dir /java/FS_WECHAT_ASS/application .properties:$workDir /tomcat8-ass-cloud-wechat-8090/webapps/FS_WECHAT_ASS/WEB-INF/classes/application .properties \ - v $ dir /java/FS_WECHAT_ASS/asr .properties:$workDir /tomcat8-ass-cloud-wechat-8090/webapps/FS_WECHAT_ASS/WEB-INF/classes/asr .properties \ - v $ dir /java/FS_WECHAT_ASS/config .properties:$workDir /tomcat8-ass-cloud-wechat-8090/webapps/FS_WECHAT_ASS/WEB-INF/classes/config .properties \ - v $ dir /java/FS_WECHAT_ASS/logback-spring .xml:$workDir /tomcat8-ass-cloud-wechat-8090/webapps/FS_WECHAT_ASS/WEB-INF/classes/logback-spring .xml \ - v $ dir /java/FS_WECHAT_ASS/mybatis-config .xml:$workDir /tomcat8-ass-cloud-wechat-8090/webapps/FS_WECHAT_ASS/WEB-INF/classes/mybatis-config .xml \ - v $ dir /java/FS_WECHAT_ASS/rocketmq .properties:$workDir /tomcat8-ass-cloud-wechat-8090/webapps/FS_WECHAT_ASS/WEB-INF/classes/rocketmq .properties \ - v $ dir /java/FS_WECHAT_ASS/shardingDataSource .properties:$workDir /tomcat8-ass-cloud-wechat-8090/webapps/FS_WECHAT_ASS/WEB-INF/classes/shardingDataSource .properties \ - v $ dir /java/FS_WECHAT_ASS/spring .properties:$workDir /tomcat8-ass-cloud-wechat-8090/webapps/FS_WECHAT_ASS/WEB-INF/classes/spring .properties \ - v $ dir /java/FS_WEB_CCS/appId .properties:$workDir /tomcat8-ccs-cloud-web-8089/webapps/FS_WEB_CCS/WEB-INF/classes/appId .properties \ - v $ dir /java/FS_WEB_CCS/application .properties:$workDir /tomcat8-ccs-cloud-web-8089/webapps/FS_WEB_CCS/WEB-INF/classes/application .properties \ - v $ dir /java/FS_WEB_CCS/config .properties:$workDir /tomcat8-ccs-cloud-web-8089/webapps/FS_WEB_CCS/WEB-INF/classes/config .properties \ - v $ dir /java/FS_WEB_CCS/logback .xml:$workDir /tomcat8-ccs-cloud-web-8089/webapps/FS_WEB_CCS/WEB-INF/classes/logback .xml \ - v $ dir /java/FS_WEB_CCS/mybatis-config .xml:$workDir /tomcat8-ccs-cloud-web-8089/webapps/FS_WEB_CCS/WEB-INF/classes/mybatis-config .xml \ - v $ dir /java/FS_WEB_CCS/nacos .properties:$workDir /tomcat8-ccs-cloud-web-8089/webapps/FS_WEB_CCS/WEB-INF/classes/nacos .properties \ - v $ dir /java/FS_WEB_CCS/rocketmq .properties:$workDir /tomcat8-ccs-cloud-web-8089/webapps/FS_WEB_CCS/WEB-INF/classes/rocketmq .properties \ - v $ dir /java/FS_WEB_CCS/shardingDataSource .properties:$workDir /tomcat8-ccs-cloud-web-8089/webapps/FS_WEB_CCS/WEB-INF/classes/shardingDataSource .properties \ - v $ dir /java/FS_WEB_CCS/snowflake .yml:$workDir /tomcat8-ccs-cloud-web-8089/webapps/FS_WEB_CCS/WEB-INF/classes/snowflake .yml \ - v $ dir /java/FS_WEB_CCS/spring .properties:$workDir /tomcat8-ccs-cloud-web-8089/webapps/FS_WEB_CCS/WEB-INF/classes/spring .properties \ - v $ dir /java/FS_WECHAT_CCS/appId .properties:$workDir /tomcat8-ccs-cloud-wechat-8091/webapps/FS_WECHAT_CCS/WEB-INF/classes/appId .properties \ - v $ dir /java/FS_WECHAT_CCS/application .properties:$workDir /tomcat8-ccs-cloud-wechat-8091/webapps/FS_WECHAT_CCS/WEB-INF/classes/application .properties \ - v $ dir /java/FS_WECHAT_CCS/config .properties:$workDir /tomcat8-ccs-cloud-wechat-8091/webapps/FS_WECHAT_CCS/WEB-INF/classes/config .properties \ - v $ dir /java/FS_WECHAT_CCS/logback .xml:$workDir /tomcat8-ccs-cloud-wechat-8091/webapps/FS_WECHAT_CCS/WEB-INF/classes/logback .xml \ - v $ dir /java/FS_WECHAT_CCS/mybatis-config .xml:$workDir /tomcat8-ccs-cloud-wechat-8091/webapps/FS_WECHAT_CCS/WEB-INF/classes/mybatis-config .xml \ - v $ dir /java/FS_WECHAT_CCS/nacos .properties:$workDir /tomcat8-ccs-cloud-wechat-8091/webapps/FS_WECHAT_CCS/WEB-INF/classes/nacos .properties \ - v $ dir /java/FS_WECHAT_CCS/rocketmq .properties:$workDir /tomcat8-ccs-cloud-wechat-8091/webapps/FS_WECHAT_CCS/WEB-INF/classes/rocketmq .properties \ - v $ dir /java/FS_WECHAT_CCS/shardingDataSource .properties:$workDir /tomcat8-ccs-cloud-wechat-8091/webapps/FS_WECHAT_CCS/WEB-INF/classes/shardingDataSource .properties \ - v $ dir /java/FS_WECHAT_CCS/snowflake .yml:$workDir /tomcat8-ccs-cloud-wechat-8091/webapps/FS_WECHAT_CCS/WEB-INF/classes/snowflake .yml \ - v $ dir /java/FS_WECHAT_CCS/spring .properties:$workDir /tomcat8-ccs-cloud-wechat-8091/webapps/FS_WECHAT_CCS/WEB-INF/classes/spring .properties \ - v $ dir /java/weixin3rd_boot_cloud/application .yml:$workDir /tomcat9_weixin3rd_9015/webapps/weixin3rd_boot_cloud/WEB-INF/classes/application .yml \ - v $ dir /java/weixin3rd_boot_cloud/application-sharding .yml:$workDir /tomcat9_weixin3rd_9015/webapps/weixin3rd_boot_cloud/WEB-INF/classes/application-sharding .yml \ - v $ dir /java/weixin3rd_boot_cloud/config .properties:$workDir /tomcat9_weixin3rd_9015/webapps/weixin3rd_boot_cloud/WEB-INF/classes/config .properties \ - v $ dir /java/weixin3rd_boot_cloud/logback .xml:$workDir /tomcat9_weixin3rd_9015/webapps/weixin3rd_boot_cloud/WEB-INF/classes/logback .xml \ - v $ dir /html/FS_WEB_CCS/config .js:$workDir /html/FS_WEB_CCS/static/config .js \ - v $ dir /html/FS_WEB_CCS/images :$workDir /html/FS_WEB_CCS/static/images \ - v $ dir /logs/tomcat8-ass-cloud-web-8087 :$workDir /tomcat8-ass-cloud-web-8087/logs \ - v $ dir /logs/tomcat8-ass-cloud-wechat-8090 :$workDir /tomcat8-ass-cloud-wechat-8090/logs \ - v $ dir /logs/tomcat8-ccs-cloud-web-8089 :$workDir /tomcat8-ccs-cloud-web-8089/logs \ - v $ dir /logs/tomcat8-ccs-cloud-wechat-8091 :$workDir /tomcat8-ccs-cloud-wechat-8091/logs \ - v $ dir /logs/tomcat9_weixin3rd_9015 :$workDir /tomcat9_weixin3rd_9015/logs \ -d $imageName) echo "$res" # 结束 echo "Info: init finish" |
start.sh脚本
作用:启动容器
1 | docker start online_ccs |
stop.sh脚本
作用:停止容器
1 | docker stop online_ccs |
restart.sh脚本
作用:重启容器
1 | docker restart online_ccs |
config目录
把需要启动的应用程序配置到server.config,容器启动时,配合script.sh可以实现应用程序的动态启动
步骤
1、编写dockerfile
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 | # 使用官方的OpenJDK镜像作为基础镜像 FROM centos:7.9_jdk As build # 配置环境变量 ENV LANG en_US.utf8 ENV LANGUAGE en_US.utf8 ENV LC_ALL en_US.utf8 ENV TZ=Asia /Shanghai # 设置工作目录 WORKDIR /app # 将本地的tomcat应用程序的文件复制到容器内(这里不会把package目录也复制进去) COPY . /package . # 给Tomcat设置权限 RUN chmod +x ./* /bin/ *.sh \ && rm -rf ./* /logs/ * # 二阶段构建,以减小镜像体积 FROM centos:7.9_jdk # 配置环境变量 ENV LANG en_US.utf8 ENV LANGUAGE en_US.utf8 ENV LC_ALL en_US.utf8 ENV TZ=Asia /Shanghai # 设置工作目录 WORKDIR /app COPY --from=build /app . # 设置时区 RUN ln -snf /usr/share/zoneinfo/ $TZ /etc/localtime && echo $TZ > /etc/timezone # 挂载点 VOLUME [ "/app/config" ] # 当Docker容器启动时执行script.sh脚本 CMD [ "/app/script.sh" , "/app/config/server.config" , "/app" ] |
注:script.sh脚本已经在centos:7.9_jdk镜像里边了,该镜像是私有镜像,因此,实际使用的时候,需要把script.sh复制到容器的app目录下(在package目录补上script.sh脚本
)
script.sh脚本
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 | #!/bin/bash # 检查文件是否存在 if [ ! -f "$1" ]; then echo "$(date +" %Y-%m-%d %H:%M:%S ") Error: $1 file not found." exit 1 fi # 逐行读取文件内容 while IFS= read -r line || [[ -n "$line" ]] do # 去除前面的空格 line= "${line#" ${line%%[![:space:]]*} "}" # 去除后面的空格 line= "${line%" ${line ##*[![:space:]]}"}" # 跳过空行、或者以#开头 if [[ ! -z "$line" ]] && [[ ! "$line" == \ #* ]]; then echo "$(date +" %Y-%m-%d %H:%M:%S ") Exec: $2/$line/bin/startup.sh run" # 执行命令 (catalina.sh run方式启动,catalina.out不会输出) sh -c "cd $2/$line/bin && ./startup.sh" fi done < "$1" # 结束 echo "$(date +" %Y-%m-%d %H:%M:%S ") All commands executed." # 目的维持容器运行 tail -f /dev/null |
2、构件镜像
docker build . -t 镜像名称:标签
3、保存镜像到本地服务器
docker save 镜像名称:标签 -o 文件名称
4、复制镜像文件到指定目录
并执行init.sh脚本
注:init.sh脚本只在第一次运行的时候执行,后续启动与关闭通过start.sh、stop.sh、restart.sh脚本控制
5、查看挂载的日志目录
查看tomcat日志,看程序是否正常启动
里边确实有tomcat启动的日志,这里忘记截图了
6、访问测试
这里只访问镜像中其中一个tomcat的接口
7、容器配置IP的作用
Docker容器的IP地址在容器网络中扮演着至关重要的角色,主要体现在以下几个方面:
网络通信:每个Docker容器都有一个唯一的内部IP地址,这个IP地址是Docker内部网络中的地址,用于容器之间的通信。容器可以通过这个内部IP地址与其他容器进行通信,就像在同一个局域网中一样。
网络配置:在Docker中设置静态IP可以确保容器始终具有相同的IP地址,从而稳定地进行网络通信。这有助于提高网络通信的稳定性和可靠性,并且使得管理和监控变得更加容易。
负载均衡:虚拟IP(VIP)可以使容器以简化的方式进行通信,而不需要直接使用宿主机的IP地址。在负载均衡场景中,外部请求通过虚拟IP被路由到不同的容器,从而实现了请求的分散处理。
隔离与安全:Docker网络启用虚拟IP后,可以将不同的网络隔离开,增强安全性。这意味着容器只与同一网络中的其他容器通信,从而提高了容器的安全性。
动态IP管理:Docker会自动处理容器IP的分配和回收,开发者无需关心容器的IP地址变化,这简化了容器的部署和管理过程。
总的来说,Docker容器的IP地址在网络通信、负载均衡、隔离与安全以及动态IP管理等方面都发挥着重要作用,确保了容器的稳定运行和高效管理。
总结
如果以本例的目录结构为模板,构件新的镜像,只需要调整的文件如下
1、将需要打包的文件放到package(记得补上script.sh脚本)
2、调整init.sh脚本
3、如果觉得target目录结构太复杂,完全可以省去,将镜像打包成功就算结束,容器的启动与创建直接通过sh脚本控制