Docker 快速入門實(shí)操教程(完結(jié))
Docker,啟動(dòng)!
如果安裝好Docker不知道怎么使用,不理解各個(gè)名詞的概念,不太了解各個(gè)功能的用途,這篇文章應(yīng)該會(huì)對(duì)你有幫助。
前置條件:已經(jīng)安裝Docker并且Docker成功啟動(dòng)。
實(shí)操內(nèi)容:使用Docker容器替換本地安裝的程序并遷移數(shù)據(jù)(MySQL、redis)。
最終目的:熟練使用Docker各項(xiàng)功能。
理解概念
Docker官方提供了一個(gè)分發(fā)平臺(tái)DockerHub,可以從上面拉取已經(jīng)提供好的鏡像直接構(gòu)建容器運(yùn)行。
這個(gè)過程會(huì)涉及到Docker的一些概念,在剛接觸的時(shí)候比較抽象,這里以烘焙出一個(gè)蛋糕為例子說明一下:
- Dockerfile: 蛋糕的配方。配方上詳細(xì)列出了需要的材料(如面粉、糖、雞蛋)以及烘焙的步驟(如先將面粉和糖混合,然后加入雞蛋攪拌)。
- 鏡像(Image): 按照配方做出了一個(gè)半成品蛋糕,這就是蛋糕的"鏡像" 。這個(gè)蛋糕可以被任何人復(fù)制,每一個(gè)復(fù)制品都會(huì)和原蛋糕一模一樣。
- 容器(Container): 將半成品蛋糕烘焙后,得到一個(gè)可食用的蛋糕??梢愿鶕?jù)同一個(gè)鏡像制作出很多個(gè)完全一樣的蛋糕,也可以在烘焙時(shí)自己加一些材料。每個(gè)蛋糕都是獨(dú)立的,和其他蛋糕沒有關(guān)聯(lián)。
所以從DockerHub拉取鏡像并且跑起來的過程就可以理解為:
- 鏡像提供者編寫好了配方(
Dockerfile
),將其制成(構(gòu)建
)了半成品蛋糕(鏡像
)。 - 用戶購買(
拉取
)這個(gè)半成品蛋糕。 - 烘焙(
創(chuàng)建
)后得到了一個(gè)可食用的蛋糕(容器
),食用蛋糕(運(yùn)行容器
)。 - 通常創(chuàng)建容器和運(yùn)行容器都會(huì)歸攏在同一步:創(chuàng)建并運(yùn)行。
還有另外兩個(gè)比較重要的概念: 層(Layers)
和 緩存(Cache)
,目前不會(huì)接觸到,可以在看 構(gòu)建/推送鏡像
這一節(jié)時(shí)再去深入理解。
創(chuàng)建/運(yùn)行容器
每一步都提供了Docker desktop(簡稱桌面版)的操作截圖和終端命令(桌面版界面友好但局限較大,僅適合初步上手)。
拉取鏡像
從DockerHub拉取MySQL鏡像到本地,這一步可能會(huì)因?yàn)榫W(wǎng)絡(luò)原因失敗,可以配置其他鏡像源或者使用代理,網(wǎng)上教程很多。
終端命令
docker pull 倉庫地址/命名空間/鏡像名稱:標(biāo)簽
- 倉庫地址: 沒有顯式指定倉庫地址時(shí),默認(rèn)會(huì)從DockerHub查找鏡像;拉取私有倉庫的鏡像,需要指定倉庫地址。
-
命名空間: 截圖最后有一個(gè)名為
ubuntu/mysql
的鏡像,其中ubuntu
是命名空間,用以區(qū)分不同的個(gè)人或組織發(fā)布的鏡像。沒有顯式指定命名空間時(shí),默認(rèn)會(huì)查找官方團(tuán)隊(duì)發(fā)布的鏡像。 - 鏡像名稱: 需要拉取的鏡像的名稱。
-
標(biāo)簽: 沒有顯式指定標(biāo)簽時(shí),默認(rèn)會(huì)拉取
latest
標(biāo)簽,latest
表示這是最新的版本。
通過 docker pull
拉取鏡像并不是必須的,在 docker run
時(shí),如果本地不存在指定鏡像,Docker會(huì)自動(dòng)拉取。
創(chuàng)建并運(yùn)行容器
拉取完成后,通過 docker run
創(chuàng)建容器并運(yùn)行前進(jìn)行一些配置:
終端命令
# 截圖對(duì)應(yīng)命令
docker run -d --name mysql_8.3.0 -p 3306:3306 -e MYSQL_ROOT_PASSWORD=root mysql:latest
# 完整命令
docker run [選項(xiàng)參數(shù)] 倉庫地址/命名空間/鏡像名稱:標(biāo)簽 [命令行] [命令行參數(shù)]
-
選項(xiàng)參數(shù):
--name
:設(shè)置容器名稱,不能重復(fù),這里使用的是鏡像名_版本號(hào)
的方式。-p
:設(shè)置端口映射,將宿主機(jī)的3306
端口映射到容器的3306
端口,宿主機(jī)上的其他進(jìn)程通過該端口才能訪問到容器內(nèi)的服務(wù)。如果不配置端口映射,則只能在容器內(nèi)部訪問服務(wù)或通過虛擬網(wǎng)絡(luò)讓容器可以相互通信。-e
:設(shè)置環(huán)境變量,配置MYSQL_ROOT_PASSWORD=root
用以指定root用戶密碼,這是由鏡像創(chuàng)建者約定的,不同的鏡像配置項(xiàng)會(huì)有所不同。-v
:設(shè)置目錄掛載,用法參考目錄掛載
章節(jié)。-d
:讓容器在后臺(tái)運(yùn)行 -
命令行: 在容器啟動(dòng)時(shí)執(zhí)行命令(如
ls
),可以省略。 -
命令行參數(shù): 傳給 命令行 的額外參數(shù)(如
/etc
,這樣在容器啟動(dòng)時(shí)就會(huì)執(zhí)行ls /etc
),可以省略。
常用命令
容器已經(jīng)創(chuàng)建好后就不再適用于 docker run
命令了, docker run
命令主要是用于創(chuàng)建新的容器并運(yùn)行,如果需要啟動(dòng)已經(jīng)存在的容器,則使用 docker start
命令。
# 列出所有容器
docker ps -a
# 列出所有鏡像
docker image ls
docker images
# 啟動(dòng)容器
docker start 容器名稱/容器ID
# 停止容器
docker stop 容器名稱/容器ID
# 強(qiáng)制停止容器
docker kill 容器名稱/容器ID
# 重啟容器
docker restart 容器名稱/容器ID
# 刪除容器
docker rm 容器名稱/容器ID
# 刪除鏡像
docker rmi 容器名稱/容器ID
目錄掛載
現(xiàn)存問題:
- 數(shù)據(jù)沒有保存到宿主機(jī)中,當(dāng)容器刪除后,數(shù)據(jù)就丟失了。
- 宿主機(jī)和容器之間的文件傳遞比較麻煩。
- 多個(gè)容器需要共享數(shù)據(jù)。
目錄掛載可以解決以上問題,Docker為目錄掛載提供了三種方式:
-
bind mount: 把宿主機(jī)目錄映射到容器內(nèi),雙向文件傳遞。適合變動(dòng)比較頻繁的場景,比如代碼目錄、配置文件等。
-
volume: 由容器創(chuàng)建和管理,存儲(chǔ)在宿主機(jī)中,官方推薦,Linux 文件系統(tǒng)。適合存儲(chǔ)不需要關(guān)心的數(shù)據(jù),如數(shù)據(jù)庫數(shù)據(jù)。
-
tmpfs mount: 適合存儲(chǔ)臨時(shí)文件,存儲(chǔ)在宿主機(jī)內(nèi)存中。不可多容器共享。
以MySQL鏡像為例,其 Dockerfile
中寫了創(chuàng)建 volume
用于持久化保存數(shù)據(jù)的命令(其他鏡像也可以通過這種方式查看需要持久化的目錄)。
雖然 Dockerfile
中有創(chuàng)建 volume
的命令,但是如果創(chuàng)建容器時(shí)沒有主動(dòng)為 volume
命名,其就是匿名 volume
,Docker會(huì)為匿名 volume
隨機(jī)生成一個(gè)名稱,當(dāng)掛載該 volume
的容器被刪除后,該 volume
也會(huì)被刪除。
當(dāng)創(chuàng)建容器時(shí)主動(dòng)指定的 volume
路徑和 Dockerfile
約定的路徑一致,則該鏡像創(chuàng)建的 volume
就不會(huì)被掛載為匿名 volume
了,容器刪除后該 volume
也會(huì)保留,這也是最方便的一種命名方式。
終端命令
docker run -d --name mysql_8.3.0 -p 3306:3306 -e MYSQL_ROOT_PASSWORD=root -v=mysql_volume:/var/lib/mysql -v D:\mount:/pc_mount mysql:latest
掛載目錄時(shí),如果只賦予了名稱則是 volume
方式,如果指定了具體目錄就是 bind mount
方式。
所以在這個(gè)容器中:
- 將容器內(nèi)的
/var/lib/mysql
目錄掛載為volume
并且命名為mysql_volume
。 - 將宿主機(jī)的
D:\mount
目錄映射至容器中的/pc_mount
。
在掛載目錄時(shí),如果你指定的目錄不存在于容器中,則會(huì)自動(dòng)創(chuàng)建,這里的 /pc_mount
目錄就會(huì)自動(dòng)被創(chuàng)建。
遷移實(shí)操
現(xiàn)在需要將宿主機(jī)中MySQL數(shù)據(jù)遷移到容器中,打算采用navicat的數(shù)據(jù)遷移工具,那么就需要同時(shí)運(yùn)行兩個(gè)數(shù)據(jù)庫,端口同為 3306
會(huì)沖突,宿主機(jī)上MySQL端口改起來并不方便,容器創(chuàng)建后端口也不能修改,那么就可以使用數(shù)據(jù)掛載的方式。
遷移方案:
- 停止運(yùn)行端口為
3306
的MySQL容器。 - 新創(chuàng)建一個(gè)MySQL容器,端口指定為
3305
(或其他任意未被占用的端口),指定volume
的名稱和端口3306
的容器一致。 - 遷移數(shù)據(jù),刪除端口為
3305
的容器,運(yùn)行端口為3306
的容器,數(shù)據(jù)遷移成功。
當(dāng)數(shù)據(jù)庫文件較大時(shí),使用navicat遷移則會(huì)顯得有些性能不足了,這時(shí)候就需要通過命令行導(dǎo)入:
-
將需要導(dǎo)入的SQL文件放在宿主機(jī)掛載的目錄下(宿主機(jī):
D:\mount
;容器:/pc_mount
)。 -
打開容器的終端
docker exec -it mysql_8.3.0 bash
-
登入MySQL并選擇需要導(dǎo)入的數(shù)據(jù)庫
mysql -u root -proot use test-base; source /pc_mount/001.sql;
從容器中導(dǎo)出SQL文件到宿主機(jī)同理,將SQL文件導(dǎo)出至掛載的 /pc_mount
目錄下,在宿主機(jī)的 D:\mount
就可以看到。
虛擬網(wǎng)絡(luò)
每個(gè)Docker容器都運(yùn)行在自己的環(huán)境中,互不干擾,所以上述內(nèi)容中都依賴宿主機(jī)的端口映射進(jìn)行容器通信。但是有些時(shí)候我們只要讓這個(gè)項(xiàng)目能在宿主機(jī)上訪問到,并不在意其所依賴的服務(wù)是否能夠被宿主機(jī)操作和管理。就可以通過Docker提供的虛擬網(wǎng)絡(luò)實(shí)現(xiàn)容器之間的通信,再映射項(xiàng)目入口到宿主機(jī)即可。
桌面版并沒有為虛擬網(wǎng)絡(luò)提供較好的GUI支持,需要終端執(zhí)行。
# 查看已存在的虛擬網(wǎng)絡(luò)
docker network ls
默認(rèn)已經(jīng)存在了三個(gè)虛擬網(wǎng)絡(luò),這是由Docker創(chuàng)建的,對(duì)應(yīng)著不同的網(wǎng)絡(luò)驅(qū)動(dòng)類型,驅(qū)動(dòng)類型的區(qū)別如下:
- Bridge網(wǎng)絡(luò): 默認(rèn)值。容器在獨(dú)立的網(wǎng)絡(luò)空間運(yùn)行,可以相互通信并訪問外部網(wǎng)絡(luò)。容器內(nèi)服務(wù)能通過端口映射被外部訪問。
- Host網(wǎng)絡(luò): 容器共享宿主機(jī)的網(wǎng)絡(luò)空間,不再需要端口映射,直接使用宿主機(jī)的端口。這種模式提供了最高的網(wǎng)絡(luò)性能,但是失去了隔離性。
- None網(wǎng)絡(luò): 容器擁有自己的網(wǎng)絡(luò)空間,但不配置任何網(wǎng)絡(luò)接口。它只有本地回環(huán)接口,沒有任何外部網(wǎng)絡(luò)訪問能力,提供了最高的網(wǎng)絡(luò)隔離性。
# 創(chuàng)建名為 test_net 的網(wǎng)絡(luò)
docker network create test_net
# 在該網(wǎng)絡(luò)下創(chuàng)建兩個(gè)容器
docker run --name redis_temp --network=test_net -d redis:latest
docker run --name redisinsight -p 8001:8001 --network test_net -d redislabs/redisinsight:latest
創(chuàng)建了redis容器,但是并沒有為其映射端口。所以現(xiàn)在在宿主機(jī)中并不能訪問到這個(gè)redis容器。
創(chuàng)建了redisInsight容器并且映射了8001端口,這是一個(gè)redis的GUI工具,用于測試是否可以通過虛擬網(wǎng)絡(luò)訪問到redis容器。
訪問 http://localhost:8001/ 進(jìn)入redisInsight的主頁,添加一個(gè)redis數(shù)據(jù)庫。
Docker內(nèi)部的DNS服務(wù)會(huì)自動(dòng)將容器名稱解析為容器對(duì)應(yīng)的IP地址(即容器名稱就是域名),所以主機(jī)地址填寫容器名稱即可。
連接成功,這樣既可以操作容器內(nèi)的redis數(shù)據(jù),又不會(huì)占用宿主機(jī)自身的redis應(yīng)用搶占端口。同理,部署其他項(xiàng)目時(shí),如果項(xiàng)目容器需要連接數(shù)據(jù)庫容器,也可以通過虛擬網(wǎng)絡(luò)實(shí)現(xiàn)。
如果容器已經(jīng)被創(chuàng)建,可以更改已存在的容器的連接的網(wǎng)絡(luò)
docker network connect 網(wǎng)絡(luò)名稱 容器名稱
使用技巧
查看軟件版本
部分鏡像的 Tag
是 latest
,并沒有明確指出具體的版本號(hào),想要查看版本號(hào)就只能手動(dòng)查看。
桌面版點(diǎn)擊容器右側(cè) ···
打開更多選項(xiàng),選擇 Open in terminal
進(jìn)入容器的終端,執(zhí)行該軟件查看版本的命令。
終端命令
docker exec mysql_8.3.0 mysql -V
但是問題就來了,如果需要版本號(hào)是為了給容器命名,這種方案需要先運(yùn)行容器,將容器刪除,再重新創(chuàng)建容器,很麻煩。
通常鏡像的環(huán)境變量中會(huì)指明版本號(hào),可以直接點(diǎn)開鏡像查看
終端命令
docker inspect mysql:latest
這個(gè)方式雖然比較方便,但是需要進(jìn)行推測,并非一定正確。
保持容器運(yùn)行
當(dāng)在桌面版運(yùn)行ubuntu等容器時(shí),會(huì)發(fā)現(xiàn)容器啟動(dòng)后就停止了,進(jìn)入 Exited
狀態(tài),如果想要容器持續(xù)運(yùn)行,就需要需要在容器內(nèi)部執(zhí)行一個(gè)持續(xù)運(yùn)行的進(jìn)程。
桌面版已經(jīng)不能滿足需求了,需要終端執(zhí)行
docker run -it --name ubuntu_22.04 ubuntu:latest
-t
指令分配一個(gè)虛擬的終端或控制臺(tái),可以讓容器持續(xù)運(yùn)行不會(huì)關(guān)閉。
-i
指令可以讓打開的控制臺(tái)能夠接受用戶輸入。
構(gòu)建/推送鏡像
想要通過Docker將項(xiàng)目部署到服務(wù)器上或是分發(fā)項(xiàng)目供他人使用,就需要將項(xiàng)目構(gòu)建為鏡像,官方主要推薦通過 Dockerfile
構(gòu)建鏡像。 Dockerfile
是一個(gè)文本文件(無文件后綴),由一系列的命令和參數(shù)構(gòu)成,這些命令對(duì)應(yīng)了在構(gòu)建鏡像時(shí)的操作步驟。
編寫Dockerfile文件
Dockerfile常用指令:
- FROM: 指定基礎(chǔ)鏡像。所有后續(xù)的操作都是基于這個(gè)基礎(chǔ)鏡像進(jìn)行的。
- WORKDIR: 設(shè)定后續(xù)命令的執(zhí)行目錄。
- **COPY: ** 復(fù)制文件、指定目錄中的所有內(nèi)容(不含目錄本身)到鏡像中。
- ADD: 復(fù)制文件、指定目錄中的所有內(nèi)容(不含目錄本身)到鏡像中。對(duì)tar格式的壓縮文件會(huì)自動(dòng)解壓。
- RUN: 構(gòu)建過程中執(zhí)行命令。比如安裝一些軟件,創(chuàng)建一些文件等。
-
CMD: 為容器提供默認(rèn)的執(zhí)行命令,會(huì)被
docker run
的命令行參數(shù)覆蓋。 -
ENTRYPOINT: 為容器提供默認(rèn)的執(zhí)行命令,不會(huì)被
docker run
的命令行參數(shù)覆蓋。 - EXPOSE: 公開容器的一個(gè)端口供外部訪問。
通過maven執(zhí)行 package
手動(dòng)將項(xiàng)目打包,命名為 output-dem.jar
,在項(xiàng)目根目錄下新建一個(gè) Dockerfile
文件:
# 使用JDK17基礎(chǔ)鏡像
FROM openjdk:17-jdk-slim
# 設(shè)置工作目錄,容器也會(huì)使用該目錄作為工作目錄
WORKDIR /app
# 將jar包復(fù)制到/app路徑下
COPY target/output-demo.jar app.jar
# 設(shè)置在運(yùn)行此鏡像后默認(rèn)執(zhí)行的命令,讓它運(yùn)行剛才的jar包
ENTRYPOINT ["java", "-jar", "app.jar"]
# 暴露端口,取決于項(xiàng)目實(shí)際使用的端口號(hào)
EXPOSE 8080
如果不是Java開發(fā),設(shè)備上并沒有安裝 JDK
和 maven
等構(gòu)建需要的環(huán)境(其他語言同理),但是又有打包項(xiàng)目的需求,則可以通過多階段構(gòu)建的方式,在鏡像中完成編譯等操作:
# 使用包含JDK17和Maven3.8.5的基礎(chǔ)鏡像
# 將本構(gòu)建階段命名為 build ,以便在后面的階段中引用
FROM maven:3.8.5-openjdk-17-slim AS build
# 設(shè)置工作目錄,容器也會(huì)使用該目錄作為工作目錄
WORKDIR /app
# 將當(dāng)前目錄下的所有文件添加到工作目錄下(.和./都可以表示當(dāng)前目錄)
ADD . .
# 使用Maven構(gòu)建項(xiàng)目為jar包
RUN mvn clean package
# 使用Maven構(gòu)建項(xiàng)目為jar包(跳過測試階段)
# RUN mvn clean package -DskipTests=true
# 新的構(gòu)建階段
# 引入JDK17的基礎(chǔ)鏡像
FROM openjdk:17-jdk-slim
# 設(shè)置工作目錄,容器也會(huì)使用該目錄作為工作目錄
WORKDIR /app
# 將 build 階段構(gòu)建jar包復(fù)制到新階段的/app路徑下
COPY --from=build /app/target/output-demo.jar app.jar
# 設(shè)置在運(yùn)行此鏡像后默認(rèn)執(zhí)行的命令,讓它運(yùn)行剛才的jar包
ENTRYPOINT ["java", "-jar", "app.jar"]
# 暴露端口,取決于項(xiàng)目實(shí)際使用的端口號(hào)
EXPOSE 8080
在Docker的多階段構(gòu)建中,每次使用新的 FROM
指令,都會(huì)開始一個(gè)新的構(gòu)建階段,上一階段的指令會(huì)創(chuàng)建為一個(gè)臨時(shí)的鏡像。在新階段中,前一階段的層和設(shè)置都被丟棄,只有 --from
指定的之前階段的內(nèi)容被保留,就像是開始了一個(gè)全新的 Dockerfile
一樣。
構(gòu)建鏡像
寫好 Dockerfile
后,就可以通過該文件構(gòu)建鏡像了
docker build -t 倉庫地址/命名空間/鏡像名:標(biāo)簽 .
docker build -t 倉庫地址/命名空間/鏡像名:標(biāo)簽 -f /path/myDockerfile .
-t
指定鏡像名稱(如果不推送到私有倉庫,僅本地使用, 倉庫地址/命名空間/
可以省略)。
-f
指定 Dockerfile
所在的目錄,也可以指定 自定義名稱的Dockerfile
( -f
參數(shù)可省略)。
.
使用當(dāng)前目錄下作為上下文環(huán)境, COPY
等命令會(huì)從該目錄查找文件。未指定 -f
參數(shù)時(shí),則使用上下文環(huán)境中名為 Dockerfile
的文件。
推送鏡像
每次發(fā)布更改內(nèi)容都需要打包鏡像后上傳到生產(chǎn)環(huán)境再部署很麻煩,將鏡像推送至私有倉庫中,在生產(chǎn)環(huán)境直接從倉庫中拉取鏡像則更加高效。
# 登錄倉庫
docker login 倉庫地址
# 推送鏡像
docker push 倉庫地址/命名空間/鏡像名:標(biāo)簽
沒有顯式指定倉庫地址時(shí),默認(rèn)會(huì)將DockerHub作為倉庫地址。
層與緩存
層(Layers): 根據(jù) Dockerfile
構(gòu)建鏡像時(shí),每一個(gè)會(huì)改變文件系統(tǒng)狀態(tài)的指令( RUN
、COPY
、 ADD
等)都會(huì)新建一個(gè)層 ,每個(gè)層都是前一層的改動(dòng)的結(jié)果,并且每個(gè)層都只保留改動(dòng)的部分,共享未改動(dòng)的部分。依次將所有的層合并起來就是完成的鏡像。
根據(jù)這個(gè)例子可以方便理解層的概念:
# Dockerfile A
RUN apt-get install -y software-package # 第一層
RUN rm -rf /var/lib/apt/lists/* # 第二層
在這個(gè)片段中,第一層中安裝了一個(gè)軟件包,第二層中刪除了軟件包。
因?yàn)?每個(gè)層都是前一層的改動(dòng)的結(jié)果
,所以第二層的刪除文件并不能影響到第一層,只是會(huì)在第二層中對(duì)該文件打上一個(gè) 刪除
的標(biāo)記,這個(gè)文件會(huì)作為一個(gè)無用的文件存在于最終構(gòu)建的鏡像中,增加了鏡像的體積。
# Dockerfile B
RUN apt-get install -y software-package && rm -rf /var/lib/apt/lists/*
在這個(gè)片段中,安裝和刪除軟件包是在同一個(gè)指令下執(zhí)行的,所以他們是處于同一層的操作,當(dāng)這一層的構(gòu)建結(jié)束時(shí),這些文件就會(huì)被清理掉,它們也就不會(huì)存在于最終的鏡像中了。
緩存: 緩存多個(gè)鏡像之間可以共享層,如果多鏡像都是基于同一個(gè)基礎(chǔ)鏡像進(jìn)行構(gòu)建的。那么,這個(gè)基礎(chǔ)鏡像的所有層都只需要存儲(chǔ)一次,就能在所有的鏡像中共享。如果一個(gè)鏡像的大部分層已經(jīng)在本地存在,那么在拉取這個(gè)鏡像時(shí),只有不存在的層需要被下載,這可以極大地節(jié)省時(shí)間和網(wǎng)絡(luò)帶寬。
Docker Compose
當(dāng)項(xiàng)目依賴的服務(wù)較多時(shí),每個(gè)容器都要單獨(dú)配置運(yùn)行,指定網(wǎng)絡(luò)。使用Docker Compose,可以通過一個(gè)YAML文件定義服務(wù),并同時(shí)運(yùn)行它們。
Docker Compose將所管理的容器分為三層:工程(Project)、服務(wù)(Service)、容器(Container)。
通過一個(gè)例子來理解三層結(jié)構(gòu):
- 工程: 一個(gè)工程可以被視為一家公司,它為所有服務(wù)提供了整體的工作環(huán)境和資源配置。
- 服務(wù): 公司內(nèi)設(shè)有各種部門,如財(cái)務(wù)和行政等,每個(gè)部門有自己特定的職責(zé)和任務(wù)。每個(gè)部門都可以被看作一個(gè)服務(wù)。
- 容器: 每個(gè)部門由一個(gè)或多個(gè)員工組成。盡管每個(gè)員工都是獨(dú)立的,但他們共享同樣的環(huán)境。一個(gè)員工相當(dāng)于一個(gè)容器。
所有部門都在同一家公司工作并使用該公司的資源,所以所有服務(wù)在工程中共享同樣的網(wǎng)絡(luò)、卷等資源。
各個(gè)部門之間還是會(huì)進(jìn)行交流和協(xié)作,所以各個(gè)服務(wù)之間可以互相通信。
同一部門的所有員工都具有相同的工作環(huán)境,所以屬于同一服務(wù)的所有容器都有統(tǒng)一的配置。員工各自做自己的項(xiàng)目,所以容器間有一定的隔離性。
在要部署項(xiàng)目的目錄創(chuàng)建一個(gè) docker-compose.yml
文件:
# 指定Docker Compose配置文件的版本
version: '3.8'
services:
# 定義應(yīng)用服務(wù),名為 app
app:
image: '倉庫地址/命名空間/鏡像名稱:標(biāo)簽'
# 將容器的8080端口映射到宿主機(jī)的8080端口
ports:
- 8080:8080
volumes:
# 將 docker-compose.yml 所在目錄映射到容器中的 /app 目錄(在 Dockerfile 中給定的工作目錄)
- ./:/app
# 定義啟動(dòng)依賴,會(huì)先啟動(dòng) mysqldb 和 redisdb,再啟動(dòng) app
depends_on:
- mysqldb
- redisdb
# 指定容器啟動(dòng)后執(zhí)行的命令
command: ["java", "-jar", "app.jar"]
# 如果服務(wù)非手動(dòng)停止,Docker會(huì)自動(dòng)嘗試重啟服務(wù)
restart: always
# 定義一個(gè)MySQL服務(wù),名為 mysqldb
# 其他服務(wù)連接MySQL數(shù)據(jù)庫時(shí),主機(jī)地址就是 mysqldb:3306
mysqldb:
image: mysql:8.0.30
environment:
- MYSQL_ROOT_PASSWORD=root
volumes:
- db_data:/var/lib/mysql
# 定義一個(gè)Redis服務(wù),名為 redisdb
# 其他服務(wù)連接Redis數(shù)據(jù)庫時(shí),主機(jī)地址就是 redisdb:6379
redisdb:
image: redis:7.2.4
volumes:
- redis_data:/data
volumes:
db_data:
redis_data:
在 docker-compose.yml
文件所在的目錄執(zhí)行
docker compose up -d
docker compose up
根據(jù) docker-compose.yml
文件內(nèi)容啟動(dòng)、創(chuàng)建、連接服務(wù)。
-d
參數(shù)表示以后臺(tái)方式運(yùn)行。
-f
如果文件名稱不是 docker-compose.yml
,可以通過 -f
命令指定,使用方法與 構(gòu)建鏡像
章節(jié)一致。
每次更改了 docker-compose.yml
文件,都需要重新運(yùn)行 docker-compose up -d
命令以應(yīng)用更改。文章來源:http://www.zghlxwxcb.cn/news/detail-826230.html
結(jié)語
任何技術(shù)都有其深度與復(fù)雜性,難以通過一篇文章詳盡闡述。本文的初衷是為你在遭遇問題時(shí),提供一個(gè)尋找解答的方向指引。文章來源地址http://www.zghlxwxcb.cn/news/detail-826230.html
到了這里,關(guān)于Docker 快速入門實(shí)操教程(完結(jié))的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!