本文以实际应用发版为例,详细表述docker镜像的制作过程,其中包括如何实现动态控制应用程序的启动
目录结构介绍
起始目录
package目录
target目录
sh目录
init.sh脚本
作用:创建网络、启动镜像、挂载目录
#!/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脚本
作用:启动容器
docker start online_ccs
stop.sh脚本
作用:停止容器
docker stop online_ccs
restart.sh脚本
作用:重启容器
docker restart online_ccs
config目录
把需要启动的应用程序配置到server.config,容器启动时,配合script.sh可以实现应用程序的动态启动
步骤
1、编写dockerfile
# 使用官方的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脚本
#!/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脚本控制
以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。
发表评论