關(guān)于Dockerfile鏡像制作完整實(shí)例
本文以實(shí)際應(yīng)用發(fā)版為例,詳細(xì)表述docker鏡像的制作過程,其中包括如何實(shí)現(xiàn)動態(tài)控制應(yīng)用程序的啟動
目錄結(jié)構(gòu)介紹
起始目錄

package目錄

target目錄

sh目錄

init.sh腳本
作用:創(chuàng)建網(wǎng)絡(luò)、啟動鏡像、掛載目錄
#!/bin/bash
# 開始
echo "Info: init start"
## ---------------------------------------------------------------------------------
# 容器名稱
containerName=online_ccs
# 網(wǎng)絡(luò)名稱
networkName=network_test001
# 映射端口(宿主機(jī)端口)
# Ass-WEB服務(wù)端口
port1=8087
# Ass-WEB服務(wù)socket端口
port2=9901
# Ass-WECHAT服務(wù)端口
port3=8090
# Ccs-WEB服務(wù)端口
port4=8089
# Ccs-WECHAT服務(wù)端口
port5=8091
# Weixin3rd服務(wù)端口
port6=9015
# 掛載根目錄(宿主機(jī)目錄)
dir=$(dirname "$PWD")
# docker服務(wù)啟動時,自啟容器
#rst=${1:-"always"}
# docker服務(wù)啟動時,不啟動容器
rst=${1:-"no"}
## ---------------------------------------------------------------------------------
# 鏡像文件
imageFile="$dir"/images/img_online_ccs.tar.gz
# 鏡像名稱
imageName=online_ccs:1.4.1.20241113_release
# 工作目錄(容器目錄)
workDir=/app
###創(chuàng)建網(wǎng)絡(luò)的作用,文章后邊會補(bǔ)充
# 檢查docker的網(wǎng)絡(luò)名稱是否存在network_test001,不存在則創(chuàng)建
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
# 導(dǎo)入docker鏡像
echo "Info: import image [$imageFile]"
res=$(docker load -i "$imageFile")
echo "$res"
# 運(yùn)行docker鏡像
###-v的都是掛載的目錄,這里主要掛載的是前后端的配置文件、日志文件,實(shí)現(xiàn)公共讀寫的功能
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"
# 結(jié)束
echo "Info: init finish"
start.sh腳本
作用:啟動容器
docker start online_ccs
stop.sh腳本
作用:停止容器
docker stop online_ccs
restart.sh腳本
作用:重啟容器
docker restart online_ccs
config目錄


把需要啟動的應(yīng)用程序配置到server.config,容器啟動時,配合script.sh可以實(shí)現(xiàn)應(yīng)用程序的動態(tài)啟動
步驟
1、編寫dockerfile
# 使用官方的OpenJDK鏡像作為基礎(chǔ)鏡像 FROM centos:7.9_jdk As build # 配置環(huán)境變量 ENV LANG en_US.utf8 ENV LANGUAGE en_US.utf8 ENV LC_ALL en_US.utf8 ENV TZ=Asia/Shanghai # 設(shè)置工作目錄 WORKDIR /app # 將本地的tomcat應(yīng)用程序的文件復(fù)制到容器內(nèi)(這里不會把package目錄也復(fù)制進(jìn)去) COPY ./package . # 給Tomcat設(shè)置權(quán)限 RUN chmod +x ./*/bin/*.sh \ && rm -rf ./*/logs/* # 二階段構(gòu)建,以減小鏡像體積 FROM centos:7.9_jdk # 配置環(huán)境變量 ENV LANG en_US.utf8 ENV LANGUAGE en_US.utf8 ENV LC_ALL en_US.utf8 ENV TZ=Asia/Shanghai # 設(shè)置工作目錄 WORKDIR /app COPY --from=build /app . # 設(shè)置時區(qū) RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone # 掛載點(diǎn) VOLUME ["/app/config"] # 當(dāng)Docker容器啟動時執(zhí)行script.sh腳本 CMD ["/app/script.sh", "/app/config/server.config", "/app"]
注:script.sh腳本已經(jīng)在centos:7.9_jdk鏡像里邊了,該鏡像是私有鏡像,因此,實(shí)際使用的時候,需要把script.sh復(fù)制到容器的app目錄下(在package目錄補(bǔ)上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
# 逐行讀取文件內(nèi)容
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"
# 執(zhí)行命令 (catalina.sh run方式啟動,catalina.out不會輸出)
sh -c "cd $2/$line/bin && ./startup.sh"
fi
done < "$1"
# 結(jié)束
echo "$(date +"%Y-%m-%d %H:%M:%S") All commands executed."
# 目的維持容器運(yùn)行
tail -f /dev/null2、構(gòu)件鏡像
docker build . -t 鏡像名稱:標(biāo)簽

3、保存鏡像到本地服務(wù)器
docker save 鏡像名稱:標(biāo)簽 -o 文件名稱

4、復(fù)制鏡像文件到指定目錄
并執(zhí)行init.sh腳本

注:init.sh腳本只在第一次運(yùn)行的時候執(zhí)行,后續(xù)啟動與關(guān)閉通過start.sh、stop.sh、restart.sh腳本控制
5、查看掛載的日志目錄
查看tomcat日志,看程序是否正常啟動

里邊確實(shí)有tomcat啟動的日志,這里忘記截圖了
6、訪問測試
這里只訪問鏡像中其中一個tomcat的接口

7、容器配置IP的作用
Docker容器的IP地址在容器網(wǎng)絡(luò)中扮演著至關(guān)重要的角色,主要體現(xiàn)在以下幾個方面:
- 網(wǎng)絡(luò)通信:每個Docker容器都有一個唯一的內(nèi)部IP地址,這個IP地址是Docker內(nèi)部網(wǎng)絡(luò)中的地址,用于容器之間的通信。容器可以通過這個內(nèi)部IP地址與其他容器進(jìn)行通信,就像在同一個局域網(wǎng)中一樣。
- 網(wǎng)絡(luò)配置:在Docker中設(shè)置靜態(tài)IP可以確保容器始終具有相同的IP地址,從而穩(wěn)定地進(jìn)行網(wǎng)絡(luò)通信。這有助于提高網(wǎng)絡(luò)通信的穩(wěn)定性和可靠性,并且使得管理和監(jiān)控變得更加容易。
- 負(fù)載均衡:虛擬IP(VIP)可以使容器以簡化的方式進(jìn)行通信,而不需要直接使用宿主機(jī)的IP地址。在負(fù)載均衡場景中,外部請求通過虛擬IP被路由到不同的容器,從而實(shí)現(xiàn)了請求的分散處理。
- 隔離與安全:Docker網(wǎng)絡(luò)啟用虛擬IP后,可以將不同的網(wǎng)絡(luò)隔離開,增強(qiáng)安全性。這意味著容器只與同一網(wǎng)絡(luò)中的其他容器通信,從而提高了容器的安全性。
- 動態(tài)IP管理:Docker會自動處理容器IP的分配和回收,開發(fā)者無需關(guān)心容器的IP地址變化,這簡化了容器的部署和管理過程。
總的來說,Docker容器的IP地址在網(wǎng)絡(luò)通信、負(fù)載均衡、隔離與安全以及動態(tài)IP管理等方面都發(fā)揮著重要作用,確保了容器的穩(wěn)定運(yùn)行和高效管理。
總結(jié)
如果以本例的目錄結(jié)構(gòu)為模板,構(gòu)件新的鏡像,只需要調(diào)整的文件如下
1、將需要打包的文件放到package(記得補(bǔ)上script.sh腳本)
2、調(diào)整init.sh腳本
3、如果覺得target目錄結(jié)構(gòu)太復(fù)雜,完全可以省去,將鏡像打包成功就算結(jié)束,容器的啟動與創(chuàng)建直接通過sh腳本控制
以上為個人經(jīng)驗(yàn),希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
pycharm與ssh遠(yuǎn)程訪問服務(wù)器docker的詳細(xì)教程
這篇文章主要介紹了pycharm與ssh遠(yuǎn)程訪問服務(wù)器docker,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-10-10
詳解docker中使用systemctl啟動服務(wù)報錯的解決辦法
這篇文章主要介紹了詳解docker中使用systemctl啟動服務(wù)報錯的解決辦法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-08-08
Docker部署Golang服務(wù)的實(shí)現(xiàn)步驟
不管是開發(fā)還是生產(chǎn)環(huán)境,通過docker方式部署服務(wù)都是一種不錯的選擇,本文主要介紹了Docker部署Golang服務(wù)的實(shí)現(xiàn)步驟,具有一定的參考價值,感興趣的可以了解一下2024-01-01
詳解Docker容器運(yùn)行多條命令(supervisor)
本篇文章主要介紹了詳解Docker容器運(yùn)行多條命令(supervisor),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-04-04

