關(guān)于Dockerfile鏡像制作完整實(shí)例
本文以實(shí)際應(yīng)用發(fā)版為例,詳細(xì)表述docker鏡像的制作過程,其中包括如何實(shí)現(xiàn)動(dòng)態(tài)控制應(yīng)用程序的啟動(dòng)
目錄結(jié)構(gòu)介紹
起始目錄
package目錄
target目錄
sh目錄
init.sh腳本
作用:創(chuàng)建網(wǎng)絡(luò)、啟動(dòng)鏡像、掛載目錄
#!/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ù)啟動(dòng)時(shí),自啟容器 #rst=${1:-"always"} # docker服務(wù)啟動(dòng)時(shí),不啟動(dòng)容器 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ò)的作用,文章后邊會(huì)補(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腳本
作用:啟動(dòng)容器
docker start online_ccs
stop.sh腳本
作用:停止容器
docker stop online_ccs
restart.sh腳本
作用:重啟容器
docker restart online_ccs
config目錄
把需要啟動(dòng)的應(yīng)用程序配置到server.config,容器啟動(dòng)時(shí),配合script.sh可以實(shí)現(xiàn)應(yīng)用程序的動(dòng)態(tài)啟動(dòng)
步驟
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)(這里不會(huì)把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è)置時(shí)區(qū) RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone # 掛載點(diǎn) VOLUME ["/app/config"] # 當(dāng)Docker容器啟動(dòng)時(shí)執(zhí)行script.sh腳本 CMD ["/app/script.sh", "/app/config/server.config", "/app"]
注:script.sh腳本已經(jīng)在centos:7.9_jdk鏡像里邊了,該鏡像是私有鏡像,因此,實(shí)際使用的時(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方式啟動(dòng),catalina.out不會(huì)輸出) 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/null
2、構(gòu)件鏡像
docker build . -t 鏡像名稱:標(biāo)簽
3、保存鏡像到本地服務(wù)器
docker save 鏡像名稱:標(biāo)簽 -o 文件名稱
4、復(fù)制鏡像文件到指定目錄
并執(zhí)行init.sh腳本
注:init.sh腳本只在第一次運(yùn)行的時(shí)候執(zhí)行,后續(xù)啟動(dòng)與關(guān)閉通過start.sh、stop.sh、restart.sh腳本控制
5、查看掛載的日志目錄
查看tomcat日志,看程序是否正常啟動(dòng)
里邊確實(shí)有tomcat啟動(dòng)的日志,這里忘記截圖了
6、訪問測試
這里只訪問鏡像中其中一個(gè)tomcat的接口
7、容器配置IP的作用
Docker容器的IP地址在容器網(wǎng)絡(luò)中扮演著至關(guān)重要的角色,主要體現(xiàn)在以下幾個(gè)方面:
- 網(wǎng)絡(luò)通信:每個(gè)Docker容器都有一個(gè)唯一的內(nèi)部IP地址,這個(gè)IP地址是Docker內(nèi)部網(wǎng)絡(luò)中的地址,用于容器之間的通信。容器可以通過這個(gè)內(nèi)部IP地址與其他容器進(jìn)行通信,就像在同一個(gè)局域網(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ù)載均衡場景中,外部請(qǐng)求通過虛擬IP被路由到不同的容器,從而實(shí)現(xiàn)了請(qǐng)求的分散處理。
- 隔離與安全:Docker網(wǎng)絡(luò)啟用虛擬IP后,可以將不同的網(wǎng)絡(luò)隔離開,增強(qiáng)安全性。這意味著容器只與同一網(wǎng)絡(luò)中的其他容器通信,從而提高了容器的安全性。
- 動(dòng)態(tài)IP管理:Docker會(huì)自動(dòng)處理容器IP的分配和回收,開發(fā)者無需關(guān)心容器的IP地址變化,這簡化了容器的部署和管理過程。
總的來說,Docker容器的IP地址在網(wǎng)絡(luò)通信、負(fù)載均衡、隔離與安全以及動(dòng)態(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é)束,容器的啟動(dòng)與創(chuàng)建直接通過sh腳本控制
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
pycharm與ssh遠(yuǎn)程訪問服務(wù)器docker的詳細(xì)教程
這篇文章主要介紹了pycharm與ssh遠(yuǎn)程訪問服務(wù)器docker,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-10-10詳解docker中使用systemctl啟動(dòng)服務(wù)報(bào)錯(cuò)的解決辦法
這篇文章主要介紹了詳解docker中使用systemctl啟動(dòng)服務(wù)報(bào)錯(cuò)的解決辦法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-08-08Docker部署Golang服務(wù)的實(shí)現(xiàn)步驟
不管是開發(fā)還是生產(chǎn)環(huán)境,通過docker方式部署服務(wù)都是一種不錯(cuò)的選擇,本文主要介紹了Docker部署Golang服務(wù)的實(shí)現(xiàn)步驟,具有一定的參考價(jià)值,感興趣的可以了解一下2024-01-01詳解Docker容器運(yùn)行多條命令(supervisor)
本篇文章主要介紹了詳解Docker容器運(yùn)行多條命令(supervisor),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-04-04