聊聊 Docker-Compose 進(jìn)階篇
一、概述
docker-compose 項(xiàng)目是docker官方的開源項(xiàng)目, 負(fù)責(zé)實(shí)現(xiàn)對(duì)docker容器集群的快速編排,來輕松高效的管理容器,定義運(yùn)行多個(gè)容器。
- docker-compose將所管理的容器分為三層, 分別是工程(project),服務(wù)(service)以及容器(containner)
- docker-compose運(yùn)行目錄下的所有文件(docker-compose.yml文件、extends文件或環(huán)境變量等)組成一個(gè)工程,如無特殊指定,工程名即為當(dāng)前目錄名。
- 一個(gè)工程當(dāng)中,可以包含多個(gè)服務(wù),每個(gè)服務(wù)中定義了容器運(yùn)行的鏡像、參數(shù)、依賴。
- 一個(gè)服務(wù)中可以包括多個(gè)容器實(shí)例,docker-compose并沒有解決負(fù)載均衡的問題。因此需要借助其他工具實(shí)現(xiàn)服務(wù)發(fā)現(xiàn)及負(fù)載均衡,比如consul。
- docker-compose?的工程配置文件默認(rèn)為 docker-compose.yml??梢酝ㄟ^環(huán)境變量COMPOSE_FILE -f 參數(shù)自定義配置文件,其自定義多個(gè)有依賴關(guān)系的服務(wù)及每個(gè)人服務(wù)運(yùn)行的容器。
官方文檔:https://docs.docker.com/compose/
GitHub:https://github.com/docker/compose/releases/
以前也寫過一篇關(guān)于docker compose基礎(chǔ)的文章,有興趣的可以先查閱看看:Docker三劍客之Compose
二、Compose 和 Docker 兼容性
Compose 文件格式有多個(gè)版本:1、2、2.x、和 3.x。下面的表格是 Compose 文件所支持的指定的 docker 發(fā)行版:
三、安裝 docker
四、安裝 docker-compose
官方安裝地址教程:https://docs.docker.com/compose/install/other/
五、環(huán)境變量
Docker Compose 允許你使用多種方法為服務(wù)設(shè)置環(huán)境變量。這些環(huán)境變量可以用來配置你的應(yīng)用程序或?qū)⒚舾行畔鬟f給你的容器。
下面是一些設(shè)置 Docker Compose 環(huán)境變量的方法:
1)在 docker-compose.yml 文件中設(shè)置環(huán)境變量
你可以在 docker-compose.yml? 文件中為每個(gè)服務(wù)設(shè)置環(huán)境變量。在服務(wù)配置中,使用 environment 關(guān)鍵字,并在其中列出需要設(shè)置的環(huán)境變量和其值。
2)從 .env 文件中讀取環(huán)境變量
你可以將環(huán)境變量存儲(chǔ)在一個(gè) .env? 文件中,并讓 Docker Compose 讀取它。在 docker-compose.yml? 文件中,使用 env_file? 關(guān)鍵字并指定 .env 文件的路徑。
3)使用 shell 環(huán)境變量
你也可以在啟動(dòng) docker-compose 命令時(shí),使用 shell 環(huán)境變量傳遞環(huán)境變量值。例如:
在 docker-compose.yml? 文件中使用 ${MY_VAR} 語法來引用 shell 環(huán)境變量。
使用環(huán)境變量可以使你的應(yīng)用程序更具靈活性,并且可以方便地管理敏感信息。
六、編排中的字段詳解
在 Docker Compose 編排文件中,有一些重要的字段需要了解:
1)version
version? 字段指定了 Docker Compose 編排文件的版本。當(dāng)前最新版本是 3。
2)services
services 字段指定了在 Docker Compose 編排中要運(yùn)行的服務(wù)。每個(gè)服務(wù)都有一個(gè)名稱,并指定要使用的鏡像和容器的配置選項(xiàng)。以下是一個(gè)簡單的 services 配置的示例:
3)build 與 image
1、build
build 字段允許在 Docker Compose 編排中指定 Dockerfile 的位置,從而可以使用 Docker Compose 構(gòu)建鏡像。例如,以下是使用本地 Dockerfile 的示例:
也可以指定一個(gè)包含 Dockerfile 的目錄:
2、image
image 字段指定要使用的 Docker 鏡像。例如:
【溫馨提示】build 和 image 二選一即可,也可以同時(shí)寫,但是一般只選擇image吧。
上面的配置指定了服務(wù)名稱為web,Dockerfile路徑為./web,鏡像名稱為 myapp/web?,標(biāo)簽為 latest?。在運(yùn)行docker-compose build? 命令時(shí),會(huì)自動(dòng)構(gòu)建名為 myapp/web:latest 的鏡像。
4)networks
networks 字段指定了要使用的網(wǎng)絡(luò)。默認(rèn)情況下,Docker Compose 創(chuàng)建一個(gè)名為 default 的網(wǎng)絡(luò)。以下是一個(gè)使用自定義網(wǎng)絡(luò)的示例:
5)volumes
volumes 字段指定了要使用的數(shù)據(jù)卷。以下是一個(gè)使用數(shù)據(jù)卷的示例(下面會(huì)細(xì)講):
6)environment 與 environment_file
1、environment
environment 字段指定了要設(shè)置的環(huán)境變量。以下是一個(gè)使用環(huán)境變量的示例:
2、environment_file
environment_file:指定從文件中讀取環(huán)境變量。
7)ports 與 expose
1、ports
ports 字段指定了要宿主機(jī)映射到容器的端口(宿主機(jī)端口:容器端口)。以下是一個(gè)使用端口映射的示例:
2、expose
expose 字段是用于在 Docker 容器內(nèi)部暴露端口的選項(xiàng),可以讓其他容器連接到這些端口,但不會(huì)將它們映射到 Docker 主機(jī)上。
在 docker-compose.yml 文件中使用 expose 選項(xiàng)來指定容器內(nèi)部需要暴露的端口。例如,以下示例定義了一個(gè) web 服務(wù),它暴露了 8000 和 8080 端口:
當(dāng)您使用 expose? 選項(xiàng)時(shí),其他容器可以使用 Docker 的內(nèi)部網(wǎng)絡(luò)進(jìn)行連接。例如,如果您有另一個(gè)服務(wù) worker,它需要連接到 web 服務(wù)的 8000 端口,則可以在 worker 服務(wù)的 docker-compose.yml 文件中使用 links 選項(xiàng):
8)depends_on
depends_on 字段指定了服務(wù)之間的依賴關(guān)系。例如,如果 web 服務(wù)依賴于 db 服務(wù),則可以使用以下示例:
9)restart
Docker Compose 提供了幾種重啟策略,以便在容器出現(xiàn)故障時(shí)自動(dòng)重啟它們。以下是可用的重啟策略:
- no: 不重啟任何容器。如果容器停止,Compose 不會(huì)嘗試自動(dòng)重啟它們。(默認(rèn)策略)
- always: 如果容器停止,Compose 將自動(dòng)重啟它。(常用)
- on-failure: 只有在容器因非 0 退出碼而停止時(shí)才會(huì)重啟。
- unless-stopped: 除非手動(dòng)停止,否則始終重啟容器。這相當(dāng)于使用 docker run 命令時(shí)使用的 --restart=unless-stopped 標(biāo)志。
這些策略可以在 docker-compose.yml 文件中通過 restart 鍵指定,例如:
這個(gè)示例使用 always 策略,這意味著如果 web 容器停止,Compose 將自動(dòng)重啟它。
10)command
command 字段可以使用多種寫法來指定容器啟動(dòng)時(shí)要執(zhí)行的命令,具體取決于您的需求和偏好。以下是一些常見的寫法示例:
1、字符串形式
在這個(gè)示例中,command 字段的值是一個(gè)字符串,表示要執(zhí)行的命令和參數(shù)。
2、列表形式
在這個(gè)示例中,command 字段的值是一個(gè)列表,每個(gè)元素都表示要執(zhí)行的命令或參數(shù)。
3、Shell 命令形式
4、使用環(huán)境變量形式
在這個(gè)示例中,command 字段中的 ${PORT}? 將被替換為 web 服務(wù)的環(huán)境變量 PORT 的值。
11)healthcheck
healthcheck:指定容器健康檢查配置。
上面的例子中,配置容器健康檢查命令為 "curl -f http://localhost/health",每 30 秒檢查一次,超時(shí)時(shí)間為 10 秒,最多重試 3 次。
12)configs 與 secrets
1、configs
configs:指定容器使用的配置文件。
上面的例子中,將名為 my-config 的配置文件復(fù)制到容器的 /etc/nginx/conf.d/default.conf 目錄下。
2、secrets
secrets:指定容器使用的機(jī)密數(shù)據(jù)。
13)hostname 與 container_name
hostname? 和 container_name 都是用來定義 Docker 容器的標(biāo)識(shí)符,但是它們的含義不同。
1、hostname
hostname 用于設(shè)置容器的主機(jī)名,也就是在容器內(nèi)部可以使用的名稱。例如,如果您在容器內(nèi)部使用 ping hostname 命令,它將解析為容器的 IP 地址。可以使用以下格式設(shè)置主機(jī)名:
在這個(gè)示例中,web 服務(wù)的容器主機(jī)名被設(shè)置為 myapp-container。
2、container_name
container_name 用于給容器命名,也就是在 Docker 主機(jī)上使用的名稱??梢允褂靡韵赂袷皆O(shè)置容器名稱:
在這個(gè)示例中,web 服務(wù)的容器名稱被設(shè)置為 myapp。
總之,hostname 和 container_name 都是用于定義容器的標(biāo)識(shí)符,但是 hostname 用于容器內(nèi)部的標(biāo)識(shí),container_name 用于 Docker 主機(jī)上的標(biāo)識(shí)。
14)user
在 Docker Compose 中,可以使用 user 字段來指定容器中運(yùn)行的進(jìn)程的用戶和用戶組。它的語法與 docker run? 命令的 --user 選項(xiàng)類似,有以下三種形式:
1、user:group(推薦)
以 user 用戶和 group 用戶組的身份運(yùn)行容器中的進(jìn)程,例如:
2、uid:gid
以 uid 用戶 ID 和 gid 用戶組 ID 的身份運(yùn)行容器中的進(jìn)程,例如:
3、user
以 user 用戶的身份運(yùn)行容器中的進(jìn)程,例如:
需要注意的是,如果在 Docker Compose 中使用了 user 字段,則容器中的所有進(jìn)程都將以指定的用戶身份運(yùn)行,而不是默認(rèn)的 root 用戶身份運(yùn)行。這可以提高容器的安全性,避免在容器中使用 root 用戶造成潛在的安全風(fēng)險(xiǎn)。
15)deploy
deploy:指定服務(wù)部署配置。
上面的例子中,配置服務(wù)的副本數(shù)量為 3,限制每個(gè)副本使用的 CPU 和內(nèi)存資源,并保留一部分資源供其他服務(wù)使用。
七、port 和 expose 區(qū)別
ports? 和 expose 是兩個(gè)不同的 Docker Compose 字段,用于在容器中暴露端口。
- ports 字段用于將容器內(nèi)部的端口映射到宿主機(jī)上的端口,以便外部網(wǎng)絡(luò)可以通過宿主機(jī)上的端口與容器中運(yùn)行的應(yīng)用程序進(jìn)行通信。這個(gè)字段的語法如下:
這個(gè)例子中,容器中運(yùn)行的 nginx 進(jìn)程監(jiān)聽的是容器內(nèi)部的 80 端口,而 ports 字段將宿主機(jī)上的 8080 端口映射到了容器內(nèi)部的 80 端口,這樣外部網(wǎng)絡(luò)就可以通過訪問宿主機(jī)上的 8080 端口來訪問容器中運(yùn)行的 nginx 應(yīng)用程序。
- expose? 與 ports 不同的是,expose 字段僅僅是將容器內(nèi)部的端口暴露給其他容器使用,而不是直接映射到宿主機(jī)上的端口。這個(gè)字段的語法如下:
這個(gè)例子中,db 和 web 兩個(gè)容器分別暴露了它們內(nèi)部的 3306 和 80 端口,其他容器可以使用這些端口來與它們通信。但是,由于這些端口沒有被映射到宿主機(jī)上,因此外部網(wǎng)絡(luò)無法直接訪問它們。如果要從外部網(wǎng)絡(luò)訪問這些容器,需要使用 ports 字段將它們映射到宿主機(jī)上的端口。
八、configs 與 secrets 區(qū)別
configs? 和 secrets 是 Docker Compose 和 Docker Swarm 中用于管理容器配置和敏感數(shù)據(jù)的兩個(gè)不同的功能。它們的區(qū)別如下:
- 用途不同:configs 用于管理容器應(yīng)用程序的配置文件,例如 nginx 的配置文件、MySQL 的配置文件等,而 secrets 則用于管理敏感數(shù)據(jù),例如數(shù)據(jù)庫的密碼、API 密鑰等。
- 存儲(chǔ)位置不同:configs 存儲(chǔ)在 Docker 主機(jī)的文件系統(tǒng)中,可以是本地文件系統(tǒng)、NFS 文件系統(tǒng)或遠(yuǎn)程 S3 存儲(chǔ)等,而 secrets 存儲(chǔ)在 Docker Swarm 的安全存儲(chǔ)中,該存儲(chǔ)是加密的、高度安全的,并且只能由授權(quán)的 Docker 服務(wù)和節(jié)點(diǎn)訪問。
- 訪問方式不同:configs 可以通過文件掛載或 Docker Compose 文件中的 configs 字段來訪問,而 secrets 可以通過文件掛載、Docker Compose 文件中的 secrets 字段、Docker CLI 的 docker secret 命令或容器內(nèi)部的文件系統(tǒng)來訪問。
- 生命周期不同:configs 的生命周期是獨(dú)立于服務(wù)的,當(dāng)服務(wù)停止時(shí),配置文件仍然可以保留在主機(jī)上,而 secrets 的生命周期是與服務(wù)綁定的,當(dāng)服務(wù)被刪除時(shí),敏感數(shù)據(jù)也會(huì)被刪除。
- 更新方式不同:configs 的更新是通過重新部署服務(wù)來實(shí)現(xiàn)的,而 secrets 的更新是通過 Docker CLI 的 docker secret 命令或容器內(nèi)部的文件系統(tǒng)來實(shí)現(xiàn)的。
以下是一個(gè)使用 configs? 和 secrets 的 Docker Compose 文件的示例:
在上面的示例中,我們定義了一個(gè) web 服務(wù),該服務(wù)使用了 nginx:latest 鏡像,并將容器內(nèi)的 80 端口映射到 Docker 主機(jī)的 80 端口。此外,我們還定義了兩個(gè)配置:configs 和 secrets。
- configs? 定義了一個(gè)名為 nginx_conf 的配置,該配置從本地的 nginx.conf 文件中讀取配置,并將其掛載到容器內(nèi)的 /etc/nginx/nginx.conf 路徑。這樣,我們就可以使用自定義的 nginx.conf 配置文件來配置 nginx 服務(wù)。
- secrets? 定義了一個(gè)名為 db_password 的敏感數(shù)據(jù),該數(shù)據(jù)從本地的 db_password.txt文件中讀取,并將其掛載到容器內(nèi)的 /run/secrets/db_password 路徑。這樣,我們就可以在容器內(nèi)部安全地訪問數(shù)據(jù)庫密碼,而不必?fù)?dān)心密碼泄露的風(fēng)險(xiǎn)。
在上述示例中,我們使用了文件掛載來訪問 configs? 和 secrets。這是最常見的訪問方式,但并不是唯一的方式。secrets 還可以通過 Docker CLI 的 docker secret 命令或容器內(nèi)部的文件系統(tǒng)來訪問。
九、掛載
在 Docker Compose 中,可以通過掛載主機(jī)目錄或文件來訪問容器內(nèi)部的文件或目錄,以便在容器內(nèi)外共享數(shù)據(jù)或配置文件。Docker Compose 支持兩種方式進(jìn)行掛載:
1)命名卷掛載
命名卷是由 Docker 創(chuàng)建和管理的卷,它們可以用于存儲(chǔ)持久化數(shù)據(jù),并可以在多個(gè)容器之間共享。在 Docker Compose 中,可以通過 volumes 字段來定義命名卷的掛載路徑和主機(jī)目錄的映射關(guān)系。關(guān)于docker的卷管理可以參考我這篇文章:Docker數(shù)據(jù)卷—Volumes。示例例如:
在上述示例中,我們定義了一個(gè) myapp 服務(wù),該服務(wù)使用了 myapp:latest 鏡像,并將命名卷 myapp_data 掛載到容器內(nèi)的 /app/data 目錄。
2)主機(jī)目錄掛載
主機(jī)目錄掛載允許將 Docker 主機(jī)上的目錄或文件夾掛載到容器內(nèi)部,以便在容器內(nèi)外共享數(shù)據(jù)。在 Docker Compose 中,可以通過 volumes 字段來定義主機(jī)目錄的掛載路徑和主機(jī)目錄的映射關(guān)系。例如:
在上述示例中,我們定義了一個(gè) myapp 服務(wù),該服務(wù)使用了 myapp:latest 鏡像,并將宿主機(jī)上的 /host/data?目錄掛載到容器內(nèi)的 /app/data 目錄。
【注意】在 Docker Compose 中,如果使用主機(jī)目錄掛載,則要求主機(jī)目錄必須存在且具有正確的權(quán)限。否則,容器將無法訪問該目錄。此外,在使用主機(jī)目錄掛載時(shí),請(qǐng)注意掛載的目錄是否包含敏感數(shù)據(jù),以避免數(shù)據(jù)泄露的風(fēng)險(xiǎn)。
十、網(wǎng)絡(luò)
Docker Compose 中的網(wǎng)絡(luò)可以用于在多個(gè)容器之間建立通信。通過定義網(wǎng)絡(luò),可以讓容器之間相互通信,同時(shí)將它們與主機(jī)網(wǎng)絡(luò)隔離開來,提高容器應(yīng)用的安全性。其實(shí)也可參考我之前的文章:Docker四種網(wǎng)絡(luò)模式(Bridge,Host,Container,None)
Docker Compose 提供了三種網(wǎng)絡(luò)類型:bridge、host 和 none,每種類型都適用于不同的場景。
1)bridge 網(wǎng)絡(luò)類型
bridge 網(wǎng)絡(luò)類型是默認(rèn)的網(wǎng)絡(luò)類型,它創(chuàng)建一個(gè)橋接網(wǎng)絡(luò),允許容器之間進(jìn)行通信。每個(gè)容器都有自己的 IP 地址,并且可以通過容器名稱來相互訪問。如果沒有指定網(wǎng)絡(luò)類型,Docker Compose 將使用 ?bridge 網(wǎng)絡(luò)類型。
在 bridge 網(wǎng)絡(luò)類型中,Docker Compose 會(huì)為每個(gè)服務(wù)創(chuàng)建一個(gè)容器,并為每個(gè)容器分配一個(gè) IP 地址。在同一個(gè)網(wǎng)絡(luò)中的容器可以相互訪問。
【請(qǐng)注意】如果您使用了Docker Compose的網(wǎng)絡(luò)功能(默認(rèn)情況下會(huì)創(chuàng)建一個(gè)網(wǎng)絡(luò)),則可以在同一網(wǎng)絡(luò)中的任何容器中使用容器名稱來訪問服務(wù)。如果您沒有使用Docker Compose網(wǎng)絡(luò)功能,則需要手動(dòng)創(chuàng)建網(wǎng)絡(luò),并將所有容器添加到同一網(wǎng)絡(luò)中。
【示例】假設(shè)我們有兩個(gè)服務(wù):web 和 db。在默認(rèn)情況下,Docker Compose 使用 bridge 網(wǎng)絡(luò)類型,我們可以不用特別指定網(wǎng)絡(luò)類型。以下是一個(gè)示例的 docker-compose.yml 文件:
在上述示例中,web 服務(wù)將使用本地 Dockerfile 構(gòu)建,并將容器端口 80 映射到主機(jī)端口 80。db 服務(wù)將使用 MySQL 5.7 鏡像,并設(shè)置 MySQL 的 root 用戶密碼為 example。
通過 docker-compose up 命令啟動(dòng)這個(gè)示例,Docker Compose 將為每個(gè)服務(wù)創(chuàng)建一個(gè)容器,并自動(dòng)創(chuàng)建一個(gè)默認(rèn)的 bridge 網(wǎng)絡(luò)來使它們互相通信。
2)host 網(wǎng)絡(luò)類型
host 網(wǎng)絡(luò)類型讓容器共享主機(jī)的網(wǎng)絡(luò)棧,這意味著容器將與主機(jī)具有相同的 IP 地址和網(wǎng)絡(luò)接口。這樣可以提高容器的網(wǎng)絡(luò)性能和可訪問性,但是容器之間不能互相訪問,因?yàn)樗鼈児蚕硗粋€(gè)網(wǎng)絡(luò)棧。
在 host 網(wǎng)絡(luò)類型中,Docker Compose 會(huì)將每個(gè)服務(wù)直接放在主機(jī)網(wǎng)絡(luò)中,容器將與主機(jī)共享 IP 地址和網(wǎng)絡(luò)接口,因此可以通過主機(jī) IP 地址來訪問容器中運(yùn)行的服務(wù)。
【示例】假設(shè)我們有一個(gè)服務(wù),它需要使用主機(jī)網(wǎng)絡(luò)接口。以下是一個(gè)示例的 docker-compose.yml 文件:
在上述示例中,我們使用 build 關(guān)鍵字來指定構(gòu)建上下文,并使用 network_mode? 關(guān)鍵字將服務(wù) web 的網(wǎng)絡(luò)模式設(shè)置為 host。這樣,web 服務(wù)將與主機(jī)共享 IP 地址和網(wǎng)絡(luò)接口,可以通過主機(jī) IP 地址來訪問服務(wù)。
3)none 網(wǎng)絡(luò)類型
none 網(wǎng)絡(luò)類型表示不為容器分配任何網(wǎng)絡(luò)資源,容器將沒有網(wǎng)絡(luò)接口。這通常用于某些特殊的容器場景,例如一些只需要與主機(jī)交互而不需要網(wǎng)絡(luò)連接的容器。
在 none 網(wǎng)絡(luò)類型中,Docker Compose 會(huì)將每個(gè)服務(wù)放在一個(gè)單獨(dú)的網(wǎng)絡(luò)命名空間中,容器將沒有任何網(wǎng)絡(luò)資源,無法進(jìn)行網(wǎng)絡(luò)通信。
【示例】假設(shè)我們有一個(gè)服務(wù),它不需要任何網(wǎng)絡(luò)連接。以下是一個(gè)示例的 docker-compose.yml 文件:
在上述示例中,我們使用 build 關(guān)鍵字來指定構(gòu)建上下文,并使用 network_mode 關(guān)鍵字將服務(wù) worker 的網(wǎng)絡(luò)模式設(shè)置為 none。這樣,worker 服務(wù)將沒有任何網(wǎng)絡(luò)資源,無法進(jìn)行網(wǎng)絡(luò)通信。
4)自定義網(wǎng)絡(luò)
Docker Compose默認(rèn)會(huì)為每個(gè)Compose項(xiàng)目創(chuàng)建一個(gè)網(wǎng)絡(luò)。這個(gè)網(wǎng)絡(luò)的名稱會(huì)以Compose項(xiàng)目的目錄名作為前綴,例如,如果您的Compose項(xiàng)目目錄名為myproject,則默認(rèn)創(chuàng)建的網(wǎng)絡(luò)名稱為myproject_default。
- 在這個(gè)默認(rèn)創(chuàng)建的網(wǎng)絡(luò)中,所有的服務(wù)和容器都可以通過它們的服務(wù)名稱或容器名稱進(jìn)行通信。這些名稱在默認(rèn)情況下都是唯一的,因此可以避免名稱沖突和混亂。
- 如果您需要訪問不同的網(wǎng)絡(luò)或自定義網(wǎng)絡(luò),則可以使用Docker Compose的networks屬性來創(chuàng)建自定義網(wǎng)絡(luò)。例如,以下是一個(gè)Docker Compose文件,其中定義了一個(gè)名為my_network的自定義網(wǎng)絡(luò):
在這個(gè)示例中,web服務(wù)將被連接到my_network網(wǎng)絡(luò)中,而不是默認(rèn)創(chuàng)建的網(wǎng)絡(luò)。該網(wǎng)絡(luò)的驅(qū)動(dòng)程序?yàn)閎ridge,這是Docker Compose默認(rèn)使用的網(wǎng)絡(luò)驅(qū)動(dòng)程序。
Compose項(xiàng)目目錄名解釋:Compose項(xiàng)目目錄名是指包含Docker Compose文件的目錄的名稱。Docker Compose文件(通常命名為docker-compose.yml)描述了Docker Compose應(yīng)該如何構(gòu)建和運(yùn)行Docker容器應(yīng)用程序。該文件通常存儲(chǔ)在Compose項(xiàng)目目錄的根目錄中。
例如,如果您正在開發(fā)一個(gè)名為myapp的應(yīng)用程序,并使用Docker Compose來管理它的容器化部署,那么您可能會(huì)在以下目錄結(jié)構(gòu)中存儲(chǔ)您的Docker Compose文件:
在這個(gè)例子中,myapp是Compose項(xiàng)目目錄名,docker-compose.yml是Compose文件的名稱,并存儲(chǔ)在myapp目錄的根目錄中。myapp目錄還包含了應(yīng)用程序的代碼和數(shù)據(jù)目錄。
十一、域名解析 DNS
Docker Compose中的容器可以使用容器名稱或服務(wù)名稱來相互訪問,而不需要使用IP地址。這是因?yàn)镈ocker Compose會(huì)為每個(gè)服務(wù)創(chuàng)建一個(gè)DNS記錄,這些記錄由默認(rèn)的DNS解析器處理。
默認(rèn)情況下,Docker Compose會(huì)創(chuàng)建一個(gè)名為"projectname_default"的網(wǎng)絡(luò),并將所有服務(wù)連接到該網(wǎng)絡(luò)中。該網(wǎng)絡(luò)使用Docker內(nèi)置的DNS解析器,為每個(gè)服務(wù)和容器分配一個(gè)DNS名稱。例如,如果您的Compose項(xiàng)目名為"myproject",那么您可以使用以下命令查看所有服務(wù)的DNS名稱:
例如,如果您的服務(wù)名稱為"web",則可以使用以下命令查看web服務(wù)的DNS名稱:
這將輸出web服務(wù)的DNS記錄,包括IP地址和DNS名稱。例如:
在這個(gè)例子中,web服務(wù)的DNS名稱為"web",IP地址為172.18.0.2。您可以使用該名稱("web")來訪問該服務(wù),而無需使用IP地址。
十二、健康檢查
Docker Compose 支持為服務(wù)定義健康檢查,用于檢查服務(wù)是否正常運(yùn)行。健康檢查可以是一個(gè)命令、一個(gè) HTTP 請(qǐng)求或者一個(gè) TCP 端口。如果健康檢查失敗,Docker Compose 將嘗試重新啟動(dòng)服務(wù),直到達(dá)到最大重試次數(shù)或者服務(wù)成功運(yùn)行。
1)健康檢查語法
在 Docker Compose 中,可以通過 healthcheck 關(guān)鍵字來定義健康檢查。具體語法如下:
參數(shù)解釋:
- test 是健康檢查的命令或者請(qǐng)求。
- interval? 是檢查健康狀態(tài)的時(shí)間間隔,單位為秒,默認(rèn)為 30s。
- timeout? 是檢查健康狀態(tài)的超時(shí)時(shí)間,單位為秒,默認(rèn)為 30s。
- retries? 是健康檢查失敗時(shí)的重試次數(shù),默認(rèn)為 3。
2)健康檢查寫法
包括以下幾種寫法:
1、字符串形式的命令
在上述示例中,healthcheck 字段的 test 屬性是一個(gè)字符串,表示需要執(zhí)行的健康檢查命令。在這個(gè)示例中,我們使用 curl 命令來測(cè)試 localhost:80 是否能夠訪問。如果健康檢查命令返回狀態(tài)碼 0,則表示服務(wù)正常,否則表示服務(wù)異常。在這個(gè)示例中,如果健康檢查失敗,Docker Compose 將在每 30 秒嘗試重新運(yùn)行健康檢查,最多重試 5 次。
2、數(shù)組形式的命令
3、自定義命令
在上述示例中,healthcheck 字段的 test 屬性是一個(gè)數(shù)組,其中第一個(gè)元素是 CMD-SHELL,表示使用 shell 執(zhí)行命令。第二個(gè)元素是一個(gè)自定義的命令,與前面的示例相同。
3)CMD-SHELL 與 CMD
CMD-SHELL? 和 CMD? 都是 Dockerfile? 中 RUN? 指令以及 Docker Compose? 中 healthcheck 指令中常用的命令格式,兩者之間的區(qū)別如下:
- CMD-SHELL(這里推薦):表示使用 shell 執(zhí)行命令。在 Docker Compose 中,健康檢查的 test 屬性中可以使用 CMD-SHELL` 來執(zhí)行自定義的 shell 命令。
- CMD:表示執(zhí)行指定的命令或者命令參數(shù)。在 Dockerfile 中,CMD 常用于指定容器啟動(dòng)時(shí)需要執(zhí)行的命令,而在 Docker Compose 中,CMD 常用于指定服務(wù)啟動(dòng)時(shí)需要執(zhí)行的命令或者命令參數(shù)。
兩者的使用方式不同,但都可以用于執(zhí)行命令或者命令參數(shù)。在 Dockerfile 中,CMD-SHELL? 并不是一個(gè)有效的指令,而在 Docker Compose 中,CMD 用于定義服務(wù)的啟動(dòng)命令,而 healthcheck? 中的 test 屬性可以使用 CMD-SHELL 來執(zhí)行自定義的 shell 命令。其實(shí)CMD在docker compose healthcheck? 也是可以使用的。只是更建議使用CMD-SHELL。
4)示例講解
以下是一個(gè)簡單的Docker Compose文件,其中定義了一個(gè)健康檢查:
在這個(gè)例子中,web服務(wù)使用nginx鏡像,并將端口80映射到主機(jī)上的端口80。此外,它定義了一個(gè)健康檢查,該檢查將定期運(yùn)行curl命令來測(cè)試服務(wù)是否響應(yīng)HTTP請(qǐng)求。具體來說,該檢查將每隔1分鐘運(yùn)行一次,超時(shí)時(shí)間為10秒,并嘗試重試3次。
您可以使用以下命令啟動(dòng)該服務(wù):
在服務(wù)啟動(dòng)后,Compose將定期運(yùn)行健康檢查,并根據(jù)檢查結(jié)果重啟服務(wù)。您可以使用以下命令查看服務(wù)的健康狀態(tài):
此命令將顯示服務(wù)的健康狀態(tài),例如:
在這個(gè)例子中,服務(wù)的健康狀態(tài)為"Up (healthy)",這表示服務(wù)正在運(yùn)行并且健康檢查通過。
十三、常用命令
以下是Docker Compose中一些常用的命令:
- docker-compose up:啟動(dòng)Compose文件中定義的服務(wù),創(chuàng)建并啟動(dòng)所有容器。
- docker-compose down:停止Compose文件中定義的服務(wù),刪除所有容器和網(wǎng)絡(luò)。
- docker-compose ps:顯示Compose文件中定義的所有容器的狀態(tài)。
- docker-compose logs:顯示Compose文件中定義的所有容器的日志。
- docker-compose build:根據(jù)Compose文件中定義的Dockerfile構(gòu)建所有服務(wù)的鏡像。
- docker-compose pull:拉取Compose文件中定義的所有服務(wù)的鏡像。
- docker-compose restart:重啟Compose文件中定義的所有服務(wù)。
- docker-compose stop:停止Compose文件中定義的所有服務(wù)。
- docker-compose start:啟動(dòng)Compose文件中定義的所有服務(wù)。
- docker-compose exec:在Compose文件中定義的容器中執(zhí)行命令。
- docker-compose run:在Compose文件中定義的容器中運(yùn)行命令。
- docker-compose config:檢查Compose文件的語法,并顯示Compose文件中定義的所有服務(wù)的配置。
這些是Docker Compose中一些常用的命令,您可以根據(jù)需要使用它們來管理和操作Compose項(xiàng)目。