关于Dockerfile镜像制作完整实例

 更新时间:2024年11月16日 15:59:10   作者:天黑请​闭眼  
本文详细介绍了如何使用Docker制作镜像,并通过实际应用发版展示了制作过程,主要内容包括创建和启动Docker容器的脚本(init.sh、start.sh、stop.sh、restart.sh),以及配置目录,文章还讨论了Docker容器IP地址的作用,并总结了制作新镜像的基本步骤

本文以实际应用发版为例,详细表述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脚本控制

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • docker容器中切换用户,提示权限不足的解决

    docker容器中切换用户,提示权限不足的解决

    这篇文章主要介绍了docker容器中切换用户,提示权限不足的解决,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-11-11
  • 详解如何在 docker 容器中捕获信号

    详解如何在 docker 容器中捕获信号

    本篇文章主要介绍了如何在 docker 容器中捕获信号,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-09-09
  • 宿主机无法访问docker容器中nginx服务的问题解决

    宿主机无法访问docker容器中nginx服务的问题解决

    在虚拟机中部署Docker并安装Nginx后,宿主机无法访问容器内的Nginx服务,通过检查端口映射、防火墙状态、进入容器内部启动Nginx以及检查/修改内核的IP转发设置,解决了该问题,感兴趣的可以了解一下
    2024-11-11
  • CentOS7.6系统下Docker安装部署教程

    CentOS7.6系统下Docker安装部署教程

    这篇文章主要为大家介绍了CentOS7.6系统下Docker的安装部署教程,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步早日升职加薪
    2022-04-04
  • Docker 网络工作原理详解

    Docker 网络工作原理详解

    这篇文章主要介绍了Docker 网络工作原理的相关资料,这里对Docker的网络工作进行了详细介绍,需要的朋友可以参考下
    2016-11-11
  • Docker安装方法与Docker四种网络模式详解

    Docker安装方法与Docker四种网络模式详解

    今天小编就为大家分享一篇关于Docker安装方法与Docker四种网络模式的详解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2018-09-09
  • Docker使用自定义网桥

    Docker使用自定义网桥

    这篇文章主要为大家详细介绍了Docker使用自定义网桥的相关资料 ,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-10-10
  • Docker部署SQL Server 2019 Always On集群的实现

    Docker部署SQL Server 2019 Always On集群的实现

    这篇文章主要介绍了Docker部署SQL Server 2019 Always On集群的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-04-04
  • Docker版的MySQL5.7升级到MySQL8.0.13,数据迁移

    Docker版的MySQL5.7升级到MySQL8.0.13,数据迁移

    这篇文章主要介绍了Docker版的MySQL5.7升级到MySQL8.0.13,数据迁移,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-09-09
  • Docker 部署 vue 项目的详细流程

    Docker 部署 vue 项目的详细流程

    使用Docker配合Nginx部署Vue3项目涉及多个步骤:首先安装Nginx,然后创建挂载目录及配置文件;接着打包Vue项目并上传至服务器;最后创建Dockerfile,构建镜像并启动容器,部署完成后,通过IP访问应用以验证是否成功
    2024-09-09

最新评论