Docker 容器編排利器 Docker Compose
一论寨、Docker Compose 簡(jiǎn)介
Docker Compose
項(xiàng)目是 Docker 官方的開源項(xiàng)目砾嫉,Compose
定位是 「定義和運(yùn)行多個(gè) Docker 容器的應(yīng)用(Defining and running multi-container Docker applications
)」,來源于之前的 Fig 項(xiàng)目陋守,使用 Python 語言編寫础倍。負(fù)責(zé)實(shí)現(xiàn)對(duì) Docker 容器集群的快速編排亡嫌。項(xiàng)目地址為:https://github.com/docker/compose/releases
Compose
的默認(rèn)管理對(duì)象是項(xiàng)目运沦,通過子命令對(duì)項(xiàng)目中的一組容器進(jìn)行便捷地生命周期管理,實(shí)現(xiàn)上調(diào)用了 Docker 服務(wù)提供的 API 來對(duì)容器進(jìn)行管理涮母。因此谆趾,只要所操作的平臺(tái)支持 Docker API,就可以在其上利用 Compose
來進(jìn)行編排管理叛本。
我們知道使用一個(gè) Dockerfile
模板文件沪蓬,可以讓用戶很方便的定義一個(gè)單獨(dú)的應(yīng)用容器。然而炮赦,在日常工作中怜跑,經(jīng)常會(huì)碰到需要多個(gè)容器相互配合來完成某項(xiàng)任務(wù)的情況。例如要實(shí)現(xiàn)一個(gè) Web 項(xiàng)目吠勘,除了 Web 服務(wù)容器本身性芬,往往還需要再加上后端的負(fù)載均衡容器等。
Docker Compose 恰好滿足了這樣的需求剧防,它是用于定義和運(yùn)行多容器 Docker 應(yīng)用程序的工具植锉。它允許用戶通過一個(gè)單獨(dú)的 docker-compose.yml
模板文件(YAML 格式)來定義一組相關(guān)聯(lián)的應(yīng)用容器為一個(gè)項(xiàng)目(project)。然后使用一個(gè)命令峭拘,就可以通過 YAML
配置文件創(chuàng)建并啟動(dòng)所有服務(wù)俊庇。
Compose
中有兩個(gè)重要的概念:
- 服務(wù) (
service
):一個(gè)應(yīng)用的容器,實(shí)際上可以包括若干運(yùn)行相同鏡像的容器實(shí)例鸡挠。 - 項(xiàng)目 (
project
):由一組關(guān)聯(lián)的應(yīng)用容器組成的一個(gè)完整業(yè)務(wù)單元辉饱,在docker-compose.yml
文件中定義。
Docker Compose 使用的三個(gè)步驟為:
- 使用
Dockerfile
文件定義應(yīng)用程序的環(huán)境拣展; - 使用
docker-compose.yml
文件定義構(gòu)成應(yīng)用程序的服務(wù)彭沼,這樣它們可以在隔離環(huán)境中一起運(yùn)行; - 最后备埃,執(zhí)行
docker-compose up
命令來創(chuàng)建并啟動(dòng)所有服務(wù)姓惑。
二、Docker Compose 安裝
2.1 Mac按脚、Windows 平臺(tái)默認(rèn)支持
Docker Desktop for Mac/Windows
自帶 docker-compose
二進(jìn)制文件于毙,安裝 Docker 之后可以直接使用。
$ docker-compose --version
Docker Compose version v2.23.3-desktop.2
2.2 Linux 安裝(通過包管理)
2.2.1 安裝
運(yùn)行以下命令以下載Docker Compose的當(dāng)前穩(wěn)定版本:
# 烏班圖 安裝
sudo apt-get install docker-compose-plugin -y
# Centos 安裝
sudo yum install docker-compose-plugin -y
2.2.2 測(cè)試
docker compose version
2.2.3 卸載
如果您需要卸載 Docker Compose辅搬,可以使用以下命令:
在 Ubuntu 上:
sudo apt-get remove docker-compose-plugin -y
在 CentOS 上:
sudo yum remove docker-compose-plugin -y
2.3 使用PIP 安裝與卸載
2.3.1 PIP安裝
這種方式是將 Compose 當(dāng)作一個(gè) Python 應(yīng)用來從 pip 源中安裝唯沮。
首先,確保你的系統(tǒng)已經(jīng)安裝了Python和pip。你可以在終端中運(yùn)行以下命令來檢查它們是否已經(jīng)安裝:
python --version
pip --version
如果這些命令返回版本信息介蛉,則說明Python和pip已經(jīng)安裝夯缺。如果沒有安裝,請(qǐng)根據(jù)你使用的操作系統(tǒng)安裝Python和pip甘耿。
沒有安裝的話請(qǐng)參考教程:Linux系統(tǒng)安裝python3.8與卸載教程
接下來,使用pip安裝docker-compose竿滨。在終端中運(yùn)行以下命令:
$ sudo pip install -U docker-compose
2.3.2 PIP 卸載
如果是通過 pip
安裝的佳恬,則執(zhí)行如下命令即可刪除。
$ sudo pip uninstall docker-compose
三于游、基本使用
3.1 術(shù)語
首先介紹幾個(gè)術(shù)語毁葱。
- 服務(wù) (
service
):一個(gè)應(yīng)用容器,實(shí)際上可以運(yùn)行多個(gè)相同鏡像的實(shí)例贰剥。 - 項(xiàng)目 (
project
):由一組關(guān)聯(lián)的應(yīng)用容器組成的一個(gè)完整業(yè)務(wù)單元倾剿。
可見,一個(gè)項(xiàng)目可以由多個(gè)服務(wù)(容器)關(guān)聯(lián)而成蚌成,Compose
面向項(xiàng)目進(jìn)行管理前痘。
3.2 部署Flask 應(yīng)用
下面我們部署一個(gè)web 網(wǎng)站,該項(xiàng)目應(yīng)該包含 web 應(yīng)用和緩存担忧。
我們用Flask 框架構(gòu)建一個(gè)能夠記錄頁面訪問次數(shù)的 web 網(wǎng)站芹缔。
首先,創(chuàng)建一個(gè)簡(jiǎn)單的 Flask 應(yīng)用瓶盛。創(chuàng)建一個(gè)新目錄 flask-app
最欠,并在其中創(chuàng)建一個(gè)名為 app.py
的文件:
# flask-app/app.py
from flask import Flask
from redis import Redis
app = Flask(__name__)
redis = Redis(host='redis', port=6379)
@app.route('/')
def hello():
visits = redis.incr('counter')
return 'Hello World! I have been seen {} times.\n'.format(visits)
if __name__ == "__main__":
app.run(host="0.0.0.0", debug=True)
接著,編寫 Dockerfile
文件,內(nèi)容為:
FROM python:3.12-alpine
ADD . /code
WORKDIR /code
RUN pip install redis flask
CMD ["python", "app.py"]
編寫 docker-compose.yml
文件惩猫,這個(gè)是 Compose 使用的主模板文件芝硬。
version: '3.0'
services:
web:
build: .
ports:
- "5000:5000"
redis:
image: "redis:alpine"
這個(gè) docker-compose.yml
文件定義了兩個(gè)服務(wù):web
和 redis
。web
服務(wù)使用當(dāng)前目錄下的 Dockerfile 構(gòu)建轧房,并將容器內(nèi)的端口 5000 綁定到宿主機(jī)的端口 5000拌阴。web
服務(wù)依賴于 redis
服務(wù)。
在 flask-app
目錄中锯厢,運(yùn)行以下命令來啟動(dòng)應(yīng)用:
docker compose up --build
這個(gè)命令會(huì)構(gòu)建 Flask 應(yīng)用的 Docker 鏡像皮官,啟動(dòng) Redis 容器,然后啟動(dòng) Flask 應(yīng)用容器实辑〗劣酰看到終端輸出如下,說明容器啟動(dòng)起來了胡岔。
現(xiàn)在漓穿,您可以通過瀏覽器訪問 http://localhost:5000
來查看您的 Flask 應(yīng)用,并且每次刷新頁面都會(huì)看到訪問次數(shù)的增加。
或者終端使用 curl
命令訪問本地運(yùn)行的 Flask 應(yīng)用
curl http://localhost:5000
如圖馍佑,此時(shí)訪問本地 5000
端口斋否,每次刷新頁面,計(jì)數(shù)就會(huì)加 1拭荤。
四茵臭、Compose 常用命令
4.1 命令對(duì)象與格式
docker compose
命令的基本的使用格式是
docker compose [-f <arg>...] [options] [COMMAND] [ARGS...]
部分命令選項(xiàng)如下:
-
-f,--file
:指定使用的 Compose 模板文件舅世,默認(rèn)為docker-compose.yml
旦委,可以多次指定,指定多個(gè) yml雏亚; -
-p, --project-name
:指定工程名稱缨硝,默認(rèn)使用docker-compose.yml
文件所在目錄的名稱; -
-v
:打印版本并退出罢低; -
--log-level
:定義日志等級(jí)(DEBUG, INFO, WARNING, ERROR, CRITICAL)查辩。
我們通過終端輸入命令docker compose
可以查看到所有命令和選項(xiàng):
用法: docker compose [選項(xiàng)] 命令
使用 Docker 定義和運(yùn)行多容器應(yīng)用程序
選項(xiàng):
--ansi string 控制何時(shí)打印 ANSI 控制字符 ("never"|"always"|"auto")
(默認(rèn) "auto")
--compatibility 以向后兼容模式運(yùn)行 Compose
--dry-run 以干運(yùn)行模式執(zhí)行命令
--env-file stringArray 指定一個(gè)替代的環(huán)境文件
-f, --file stringArray 指定 Compose 配置文件
--parallel int 控制最大并行性,-1 為無限制 (默認(rèn) -1)
--profile stringArray 指定要啟用的配置文件
--progress string 設(shè)置進(jìn)度輸出的類型 (auto, tty, plain, quiet) (默認(rèn) "auto")
--project-directory string 指定一個(gè)替代的工作目錄
(默認(rèn):第一個(gè)指定的 Compose 文件的路徑)
-p, --project-name string 項(xiàng)目名稱
命令:
attach 將本地標(biāo)準(zhǔn)輸入网持、輸出和錯(cuò)誤流附加到服務(wù)的運(yùn)行容器上
build 構(gòu)建或重建服務(wù)
config 解析宜岛、解析并呈現(xiàn) Compose 文件的規(guī)范格式
cp 在服務(wù)容器和本地文件系統(tǒng)之間復(fù)制文件/文件夾
create 為服務(wù)創(chuàng)建容器
down 停止并刪除容器和網(wǎng)絡(luò)
events 從容器接收實(shí)時(shí)事件
exec 在運(yùn)行中的容器內(nèi)執(zhí)行命令
images 列出由創(chuàng)建的容器使用的鏡像
kill 強(qiáng)制停止服務(wù)容器
logs 查看容器的輸出
ls 列出運(yùn)行中的 Compose 項(xiàng)目
pause 暫停服務(wù)
port 打印端口的公共端口綁定
ps 列出容器
pull 拉取服務(wù)鏡像
push 推送服務(wù)鏡像
restart 重啟服務(wù)容器
rm 刪除已停止的服務(wù)容器
run 對(duì)服務(wù)運(yùn)行一次性命令
scale 設(shè)置服務(wù)運(yùn)行的容器數(shù)量
start 啟動(dòng)服務(wù)
stats 顯示容器的實(shí)時(shí)資源使用統(tǒng)計(jì)信息
stop 停止服務(wù)
top 顯示正在運(yùn)行的進(jìn)程
unpause 恢復(fù)暫停的服務(wù)
up 創(chuàng)建并啟動(dòng)容器
version 顯示 Docker Compose 版本信息
wait 阻塞直到第一個(gè)服務(wù)容器停止
watch 監(jiān)視服務(wù)的構(gòu)建上下文,并在文件更新時(shí)重建/刷新容器
運(yùn)行 'docker compose 命令 --help' 以獲取有關(guān)一個(gè)命令的更多信息翎碑。
4.2 docker-compose 常用命令
4.2.1 config
-
docker compose config -q
驗(yàn)證docker-compose.yml
文件谬返。當(dāng)配置正確時(shí),不輸出任何內(nèi)容日杈,當(dāng)配置錯(cuò)誤時(shí)遣铝,輸出錯(cuò)誤信息。
4.2.2 pull
-
docker compose pull
拉取服務(wù)依賴的鏡像莉擒。
# 拉取工程中所有服務(wù)依賴的鏡像
docker compose pull
# 拉取工程中 redis 服務(wù)依賴的鏡像
docker compose pull redis
# 拉取鏡像過程中不打印拉取進(jìn)度信息
docker compose pull -q
4.2.3 up
docker compose up
創(chuàng)建并啟動(dòng)所有服務(wù)的容器酿炸。指定多個(gè) yml 加 -f
選項(xiàng)。以守護(hù)進(jìn)程模式運(yùn)行加 -d
選項(xiàng)涨冀。
# 前臺(tái)啟動(dòng)
docker compose up
# 后臺(tái)啟動(dòng)
docker compose up -d
# -f 指定使用的 Compose 模板文件填硕,默認(rèn)為 docker-compose.yml,可以多次指定鹿鳖,指定多個(gè) yml
docker compose -f docker-compose.yml up -d
4.2.4 logs
docker compose logs
查看服務(wù)容器的輸出日志扁眯。默認(rèn)情況下,docker-compose 將對(duì)不同的服務(wù)輸出使用不同的顏色來區(qū)分翅帜∫鎏矗可以通過 --no-color
來關(guān)閉顏色。
# 輸出日志涝滴,不同的服務(wù)輸出使用不同的顏色來區(qū)分
docker compose logs
# 跟蹤日志輸出
docker compose logs -f
# 關(guān)閉顏色
docker compose logs --no-color
4.2.5 ps
docker compose ps
列出工程中所有服務(wù)的容器绣版。
# 列出工程中所有服務(wù)的容器
docker compose ps
# 列出工程中指定服務(wù)的容器
docker compose ps redis
4.2.6 run
docker compose run
在指定服務(wù)容器上執(zhí)行一個(gè)命令胶台。
# 在工程中指定服務(wù)的容器上執(zhí)行 echo "hello"
docker compose run redis echo "hello"
4.2.7 exec
docker compose exec
進(jìn)入服務(wù)容器。
# 進(jìn)入工程中指定服務(wù)的容器
docker compose exec redis bash
# 當(dāng)一個(gè)服務(wù)擁有多個(gè)容器時(shí)杂抽,可通過 --index 參數(shù)進(jìn)入到該服務(wù)下的任何容器
docker compose exec --index=1 redis bash
4.2.8 pause
docker compose pause
暫停服務(wù)容器诈唬。
# 暫停工程中所有服務(wù)的容器
docker compose pause
# 暫停工程中指定服務(wù)的容器
docker compose pause redis
4.2.9 unpause
docker compose unpause
恢復(fù)服務(wù)容器。
# 恢復(fù)工程中所有服務(wù)的容器
docker compose unpause
# 恢復(fù)工程中指定服務(wù)的容器
docker compose unpause redis
4.2.10 restart
docker compose restart
重啟服務(wù)容器缩麸。
# 重啟工程中所有服務(wù)的容器
docker compose restart
# 重啟工程中指定服務(wù)的容器
docker compose restart redis
4.2.11 start
docker compose start
啟動(dòng)服務(wù)容器铸磅。
# 啟動(dòng)工程中所有服務(wù)的容器
docker compose start
# 啟動(dòng)工程中指定服務(wù)的容器
docker compose start nginx
4.2.12 stop
docker compose stop
停止服務(wù)容器。
# 停止工程中所有服務(wù)的容器
docker compose stop
# 停止工程中指定服務(wù)的容器
docker compose stop redis
4.2.13 kill
docker compose kill
通過發(fā)送 SIGKILL
信號(hào)停止指定服務(wù)的容器杭朱。
# 通過發(fā)送 SIGKILL 信號(hào)停止工程中指定服務(wù)的容器
docker compose kill redis
4.2.14 rm
docker compose rm
刪除服務(wù)(停止?fàn)顟B(tài))容器愚屁。
# 刪除所有(停止?fàn)顟B(tài))服務(wù)的容器
docker compose rm
# 先停止所有服務(wù)的容器,再刪除所有服務(wù)的容器
docker compose rm -s
# 不詢問是否刪除痕檬,直接刪除
docker compose rm -f
# 刪除服務(wù)容器掛載的數(shù)據(jù)卷
docker compose rm -v
# 刪除工程中指定服務(wù)的容器
docker compose rm -sv redis
4.2.15 down
停止并刪除所有服務(wù)的容器、網(wǎng)絡(luò)送浊、鏡像梦谜、數(shù)據(jù)卷。
# 停止并刪除工程中所有服務(wù)的容器袭景、網(wǎng)絡(luò)
docker compose down
# 停止并刪除工程中所有服務(wù)的容器唁桩、網(wǎng)絡(luò)、鏡像
docker compose down --rmi all
# 停止并刪除工程中所有服務(wù)的容器耸棒、網(wǎng)絡(luò)荒澡、數(shù)據(jù)卷
docker compose down -v
4.2.16 images
docker compose images
打印服務(wù)容器所對(duì)應(yīng)的鏡像。
# 打印所有服務(wù)的容器所對(duì)應(yīng)的鏡像
docker compose images
# 打印指定服務(wù)的容器所對(duì)應(yīng)的鏡像
docker compose images redis
4.2.17 port
docker compose port
打印指定服務(wù)容器的某個(gè)端口所映射的宿主機(jī)端口与殃。
[root@VM-16-centos flask-app]# docker compose port nginx 80
0.0.0.0:80
4.2.18 top
docker compose top
顯示正在運(yùn)行的進(jìn)程单山。
# 顯示工程中所有服務(wù)的容器正在運(yùn)行的進(jìn)程
docker compose top
# 顯示工程中指定服務(wù)的容器正在運(yùn)行的進(jìn)程
docker compose top redis
五、docker-compose.yml 文件詳解
5.1 概念
Docker Compose 允許用戶通過 docker-compose.yml
文件(YAML 格式)來定義一組相關(guān)聯(lián)的容器為一個(gè)工程(project)
幅疼。一個(gè)工程包含多個(gè)服務(wù)(service)
米奸,每個(gè)服務(wù)中定義了創(chuàng)建容器時(shí)所需的鏡像、參數(shù)爽篷、依賴等悴晰。
工程名若無特殊指定,即為
docker-compose.yml
文件所在目錄的名稱逐工。
Docker Compose 模板文件我們需要關(guān)注的頂級(jí)配置有:version
铡溪、services
、networks
泪喊、volumes
幾個(gè)部分棕硫,除 version
外,其他幾個(gè)頂級(jí)配置下還有很多下級(jí)配置窘俺,后面也會(huì)詳細(xì)給大家介紹饲帅,先來看看這幾個(gè)頂級(jí)配置都什么意思:
-
version
:描述 Compose 文件的版本信息复凳,當(dāng)前最新版本為3.8
,對(duì)應(yīng)的 Docker 版本為19.03.0+
灶泵; -
services
:定義服務(wù)育八,可以多個(gè),每個(gè)服務(wù)中定義了創(chuàng)建容器時(shí)所需的鏡像赦邻、參數(shù)髓棋、依賴等; -
networkds
:定義網(wǎng)絡(luò)惶洲,可以多個(gè)按声,根據(jù) DNS server 讓相同網(wǎng)絡(luò)中的容器可以直接通過容器名稱進(jìn)行通信; -
volumes
:數(shù)據(jù)卷恬吕,用于實(shí)現(xiàn)目錄掛載签则。
5.2 案例
在配置文件中,所有的容器通過 services
來定義铐料,然后使用 docker-compose
腳本來啟動(dòng)渐裂,停止和重啟容器,非常適合多個(gè)容器組合使用進(jìn)行開發(fā)的場(chǎng)景钠惩。我們先從一個(gè)簡(jiǎn)單的 Compose 案例開始柒凉。我們編寫第一個(gè) docker-compose.yml
文件。
# 創(chuàng)建目錄
mkdir -p ./docker-nginx
# 切換至指定目錄
cd ./docker-nginx/
# 編寫 docker-compose.yml 文件
vi docker-compose.yml
在文件 docker-compose.yml
文件中添加以下內(nèi)容:
# 描述 Compose 文件的版本信息
version: "3.8"
# 定義服務(wù)篓跛,可以多個(gè)
services:
nginx: # 服務(wù)名稱
image: nginx # 創(chuàng)建容器時(shí)所需的鏡像
container_name: mynginx # 容器名稱膝捞,默認(rèn)為"工程名稱_服務(wù)條目名稱_序號(hào)"
ports: # 宿主機(jī)與容器的端口映射關(guān)系
- "80:80" # 左邊宿主機(jī)端口:右邊容器端口
networks: # 配置容器連接的網(wǎng)絡(luò),引用頂級(jí) networks 下的條目
- nginx-net
# 定義網(wǎng)絡(luò)愧沟,可以多個(gè)蔬咬。如果不聲明,默認(rèn)會(huì)創(chuàng)建一個(gè)網(wǎng)絡(luò)名稱為"工程名稱_default"的 bridge 網(wǎng)絡(luò)
networks:
nginx-net: # 一個(gè)具體網(wǎng)絡(luò)的條目名稱
name: nginx-net # 網(wǎng)絡(luò)名稱沐寺,默認(rèn)為"工程名稱_網(wǎng)絡(luò)條目名稱"
driver: bridge # 網(wǎng)絡(luò)模式计盒,默認(rèn)為 bridge
使用 docker-compose up
創(chuàng)建并啟動(dòng)所有服務(wù)。
# 前臺(tái)啟動(dòng)
docker-compose up
# 后臺(tái)啟動(dòng)
docker-compose up -d
瀏覽器訪問:http://localhost/結(jié)果如下:
使用 docker-compose down
可以停止并刪除容器芽丹、網(wǎng)絡(luò)北启。
5.3 version
-
version
是Docker Compose文件的一個(gè)主要組成部分,用于指定當(dāng)前Docker Compose文件的版本拔第。
version
字段通常在文件的頂部進(jìn)行定義咕村,如下所示:
version: "3.8"
在這個(gè)例子中,version
被設(shè)置為'3.8'
蚊俺,這意味著這個(gè)Docker Compose文件使用的是3.8版本的語法和功能懈涛。
重要的是要注意不同版本的Docker Compose之間可能存在不兼容性。因此泳猬,在升級(jí)或更改您的docker-compose.yaml
文件時(shí)批钠,請(qǐng)確保查看有關(guān)版本的特定說明和變更日志宇植,以便了解您當(dāng)前所使用版本的支持的功能和變更情況。
官網(wǎng)提供的鏈接比較老了埋心,且compose版本和其version字段不相同指郁,對(duì)應(yīng)起來比較麻煩(二者的對(duì)應(yīng)關(guān)系可以參考鏈接)
5.4 services
剛才我們提到 docker-compose.yml
文件中包含很多下級(jí)配置項(xiàng),下面帶大家把一些常用的配置項(xiàng)詳細(xì)了解一下拷呆,先從頂級(jí)配置 services
開始闲坎。
services
用來定義服務(wù),可以多個(gè)茬斧,每個(gè)服務(wù)中定義了創(chuàng)建容器時(shí)所需的鏡像腰懂、參數(shù)、依賴等项秉,就像將命令行參數(shù)傳遞給 docker run
一樣绣溜。同樣,網(wǎng)絡(luò)和數(shù)據(jù)卷的定義也是一樣的娄蔼。
5.4.1 services 簡(jiǎn)單舉例
舉個(gè)例子涮毫,之前我們通過 docker run
命令構(gòu)建一個(gè) MySQL 應(yīng)用容器的命令如下:
docker run -di --name mysql8 -p 3306:3306 -v /mydata/docker_mysql/conf:/etc/mysql/conf.d -v /mydata/docker_mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=1234 mysql:8
使用 docker-compose.yml
以后則可以這樣定義:
# 描述 Compose 文件的版本信息
version: "3.8"
# 定義服務(wù),可以多個(gè)
services:
mysql: # 服務(wù)名稱
image: mysql:8 # 創(chuàng)建容器時(shí)所需的鏡像以及版本號(hào)
container_name: mysql8 # 容器名稱贷屎,默認(rèn)為"工程名稱_服務(wù)條目名稱_序號(hào)"
ports: # 宿主機(jī)與容器的端口映射關(guān)系
- "3306:3306" # 左邊宿主機(jī)端口:右邊容器端口
environment: # 創(chuàng)建容器時(shí)所需的環(huán)境變量
MYSQL_ROOT_PASSWORD: 1234 # MySQL root 用戶的密碼
volumes:
- "/mydata/docker_mysql/conf:/etc/mysql/conf.d"
- "/mydata/docker_mysql/data:/var/lib/mysql"
然后通過 dokcer-compose
相關(guān)命令即可完成容器的創(chuàng)建,停止或刪除等一系列操作艘虎。
5.4.2 image
指定創(chuàng)建容器時(shí)所需的鏡像名稱標(biāo)簽或者鏡像 ID唉侄。如果鏡像在本地不存在,會(huì)去遠(yuǎn)程拉取野建。
services:
web:
image: mysql:8
5.4.3 build
除了可以基于指定的鏡像構(gòu)建容器属划,還可以基于 Dockerfile
文件構(gòu)建,在使用 up
命令時(shí)會(huì)執(zhí)行構(gòu)建任務(wù)候生。
通過 build
配置項(xiàng)可以指定 Dockerfile
所在文件夾的路徑同眯。Compose 將會(huì)利用 Dockerfile
自動(dòng)構(gòu)建鏡像,然后使用鏡像啟動(dòng)服務(wù)容器唯鸭。
build
配置項(xiàng)可以使用絕對(duì)路徑须蜗,也可以使用相對(duì)路徑。
# 絕對(duì)路徑目溉,在該路徑下基于名稱為 Dockerfile 的文件構(gòu)建鏡像
/usr/local/docker-centos
# 相對(duì)路徑明肮,相對(duì)當(dāng)前 docker-compose.yml 文件所在目錄,基于名稱為 Dockerfile 的文件構(gòu)建鏡像
.
接下來我們來個(gè)稍微復(fù)雜點(diǎn)的練習(xí)缭付,首先我們使用Go編寫一個(gè)HTTP Server:
創(chuàng)建一個(gè)目錄:
# 創(chuàng)建目錄
mkdir -p /usr/local/docker-centos
# 切換至指定目錄
cd /usr/local/docker-centos/
mkdir ./httpserver
編寫main.go內(nèi)容如下:
package main
import (
"fmt"
"net/http"
)
func main() {
http.HandleFunc("/", rootHandler)
http.HandleFunc("/ping", pingHandler)
fmt.Println("Server started at http://localhost:8080")
http.ListenAndServe(":8080", nil)
}
func rootHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, "哈嘍柿估,Go!")
}
func pingHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, "pong")
}
接著通過基礎(chǔ)鏡像 centos:8
,在該鏡像中安裝 go 和 并且運(yùn)行HTTP Server以后將其制作為一個(gè)新的鏡像 mycentos:8
陷猫。編寫 Dockerfile
文件秫舌。
# 編寫 Dockerfile 文件
vi Dockerfile
Dockerfile
文件內(nèi)容如下:
# 指明構(gòu)建的新鏡像是來自于 centos:8 基礎(chǔ)鏡像
FROM centos:8
# 通過鏡像標(biāo)簽聲明了作者信息
LABEL maintainer="blog.jarvis.com"
# 設(shè)置工作目錄
WORKDIR /usr/local
# 拷貝 Go 語言壓縮包并解壓到指定目錄
ADD go1.22.1.linux-amd64.tar.gz /usr/local/
# 設(shè)置 Go 環(huán)境變量
ENV GOROOT=/usr/local/go
ENV GOPATH=/usr/local/gopath
ENV PATH=$PATH:$GOROOT/bin:$GOPATH/bin
# 將 httpserver 代碼拷貝到容器中
COPY ./httpserver /usr/local/httpserver
# 設(shè)置工作目錄到 httpserver 目錄
WORKDIR /usr/local/httpserver
# 編譯 Go HTTP 服務(wù)器
RUN go build -o httpserver main.go
# 暴露容器運(yùn)行時(shí)的 8080 監(jiān)聽端口給外部
EXPOSE 8080
# 使用 CMD 運(yùn)行 HTTP 服務(wù)器
CMD ["./httpserver"]
接著通過如下命令下載Go 編譯器:
# 下載GO 編譯器
wget https://golang.google.cn/dl/go1.22.1.linux-amd64.tar.gz
創(chuàng)建目錄并編寫 docker-compose.yml
文件的妖。
# 描述 Compose 文件的版本信息
version: "3.8"
# 定義服務(wù),可以多個(gè)
services:
mycentos: # 服務(wù)名稱
build: . # 相對(duì)當(dāng)前 docker-compose.yml 文件所在目錄足陨,基于名稱為 Dockerfile-alternate 的文件構(gòu)建鏡像
container_name: mycentos7 # 容器名稱嫂粟,默認(rèn)為"工程名稱_服務(wù)條目名稱_序號(hào)"
ports: # 宿主機(jī)與容器的端口映射關(guān)系
- "8080:8080" # 左邊宿主機(jī)端口:右邊容器端口
然后通過 dokcer-compose
相關(guān)命令即可完成容器的創(chuàng)建,停止或刪除等一系列操作钠右。
(一). context
該選項(xiàng)可以是 Dockerfile 文件的絕對(duì)/相對(duì)路徑赋元,也可以是遠(yuǎn)程 Git 倉(cāng)庫(kù)的 URL,當(dāng)提供的值是相對(duì)路徑時(shí)飒房,相對(duì)當(dāng)前 docker-compose.yml 文件所在目錄搁凸。
build:
context: . # 相對(duì)當(dāng)前 docker-compose.yml 文件所在目錄,基于名稱為 Dockerfile 的文件構(gòu)建鏡像
(二). dockerfile
一般情況下狠毯,默認(rèn)都基于文件名叫 Dockerfile 的文件構(gòu)建鏡像护糖,當(dāng)然也可以是自定義的文件名,使用 dockerfile
聲明嚼松,不過這個(gè)選項(xiàng)只能聲明文件名嫡良,文件所在路徑還是要通過 centext 來聲明。
build:
context: . # 相對(duì)當(dāng)前 docker-compose.yml 文件所在目錄
dockerfile: Dockerfile-alternate # 基于名稱為 Dockerfile-alternate 的文件構(gòu)建鏡像
5.4.4 container_name
Compose 創(chuàng)建的容器默認(rèn)生成的名稱格式為:工程名稱_服務(wù)條目名稱_序號(hào)
献酗。如果要使用自定義名稱寝受,使用 container_name
聲明。
services:
mycentos:
build: .
container_name: mycentos7 # 容器名稱罕偎,默認(rèn)為"工程名稱_服務(wù)條目名稱_序號(hào)"
因?yàn)?Docker 容器名稱必須是唯一的很澄,所以如果指定了自定義名稱,就不能將服務(wù)擴(kuò)展至多個(gè)容器颜及。這樣做可能會(huì)導(dǎo)致錯(cuò)誤甩苛。
關(guān)于序號(hào)
序號(hào)是干什么用的呢,看下面這個(gè)列子你就懂了俏站,docker-compose.yml
文件內(nèi)容如下:
# 描述 Compose 文件的版本信息
version: "3.8"
# 定義服務(wù)讯蒲,可以多個(gè)
services:
helloworld: # 服務(wù)名稱
image: hello-world
然后通過 --scale
指定 helloworld
服務(wù)一次性啟動(dòng) 3 個(gè)。
docker-compose up -d --scale helloworld=3
通過下圖可以看到有 3 個(gè)容器被創(chuàng)建肄扎,容器名稱最后的序號(hào)是從 1 開始累加的墨林,這就是序號(hào)的作用。所以如果指定了自定義名稱犯祠,就不能將服務(wù)擴(kuò)展至多個(gè)容器萌丈。
5.4.5 depends_on
使用 Compose 最大的好處就是敲最少的命令做更多的事情,但一般項(xiàng)目容器啟動(dòng)的順序是有要求的雷则,如果直接從上到下啟動(dòng)容器辆雾,必然會(huì)因?yàn)槿萜饕蕾噯栴}而啟動(dòng)失敗。例如在沒有啟動(dòng)數(shù)據(jù)庫(kù)容器的情況下啟動(dòng)了 Web 應(yīng)用容器月劈,應(yīng)用容器會(huì)因?yàn)檎也坏綌?shù)據(jù)庫(kù)而退出度迂。depends_on
就是用來解決容器依賴藤乙、啟動(dòng)先后問題的配置項(xiàng)。
version: "3.8"
services:
web:
build: .
depends_on:
- db
- redis
redis:
image: redis
db:
image: mysql
上述 YAML 文件定義的容器會(huì)先啟動(dòng) db 和 redis 兩個(gè)服務(wù)惭墓,最后才啟動(dòng) web 服務(wù)坛梁。
5.4.6 ports
容器對(duì)外暴露的端口,格式:左邊宿主機(jī)端口:右邊容器端口
腊凶。
ports:
- "80:80"
- "8080:8080"
5.4.7 expose
容器暴露的端口不映射到宿主機(jī)划咐,只允許能被連接的服務(wù)訪問。
expose:
- "80"
- "8080"
5.4.8 restart
容器重啟策略钧萍,簡(jiǎn)單的理解就是 Docker 重啟以后容器要不要一起啟動(dòng):
-
no
:默認(rèn)的重啟策略褐缠,在任何情況下都不會(huì)重啟容器; -
on-failure
:容器非正常退出時(shí)风瘦,比如退出狀態(tài)為非0
(異常退出)队魏,才會(huì)重啟容器; -
always
:容器總是重新啟動(dòng)万搔,即使容器被手動(dòng)停止了胡桨,當(dāng) Docker 重啟時(shí)容器也還是會(huì)一起啟動(dòng); -
unless-stopped
:容器總是重新啟動(dòng)瞬雹,除非容器被停止(手動(dòng)或其他方式)昧谊,那么 Docker 重啟時(shí)容器則不會(huì)啟動(dòng)。
services:
nginx:
image: nginx
container_name: mynginx
ports:
- "80:80"
restart: always
5.4.9 environment
添加環(huán)境變量酗捌∧匚埽可以使用數(shù)組也可以使用字典。布爾相關(guān)的值(true意敛、false、yes膛虫、no)都需要用引號(hào)括起來草姻,以確保 YML 解析器不會(huì)將它們轉(zhuǎn)換為真或假。
environment:
RACK_ENV: development
SHOW: 'true'
SESSION_SECRET:
或者以下格式:
environment:
- RACK_ENV=development
- SHOW=true
- SESSION_SECRET
5.4.10 env_file
從文件中獲取環(huán)境變量稍刀,可以指定一個(gè)或多個(gè)文件撩独,其優(yōu)先級(jí)低于 environment 指定的環(huán)境變量。
env_file:
- /opt/runtime_opts.env # 絕對(duì)路徑
- ./common.env # 相對(duì)路徑账月,相對(duì)當(dāng)前 docker-compose.yml 文件所在目錄
- ./apps/web.env # 相對(duì)路徑综膀,相對(duì)當(dāng)前 docker-compose.yml 文件所在目錄
注意:env 文件中的每一行需采用
鍵=值
格式。以#
開頭的行會(huì)被視為注釋并被忽略局齿【缛埃空行也會(huì)被忽略。
5.4.11 command
覆蓋容器啟動(dòng)后默認(rèn)執(zhí)行的命令抓歼。
command: echo "helloworld"
該命令也可以是一個(gè)列表讥此。
command: ["echo", "helloworld"]
5.4.12 volumes
數(shù)據(jù)卷拢锹,用于實(shí)現(xiàn)目錄掛載,支持指定目錄掛載萄喳、匿名掛載卒稳、具名掛載。
- 指定目錄掛載的格式為:
左邊宿主機(jī)目錄:右邊容器目錄
他巨,或者左邊宿主機(jī)目錄:右邊容器目錄:讀寫權(quán)限
充坑; - 匿名掛載格式為:
容器目錄即可
,或者容器目錄即可:讀寫權(quán)限
染突; - 具名掛載格式為:
數(shù)據(jù)卷?xiàng)l目名稱:容器目錄
捻爷,或者數(shù)據(jù)卷?xiàng)l目名稱:容器目錄:讀寫權(quán)限
。
# 描述 Compose 文件的版本信息
version: "3.8"
# 定義服務(wù)觉痛,可以多個(gè)
services:
mysql: # 服務(wù)名稱
image: mysql:8 # 創(chuàng)建容器時(shí)所需的鏡像
container_name: mysql8 # 容器名稱役衡,默認(rèn)為"工程名稱_服務(wù)條目名稱_序號(hào)"
ports: # 宿主機(jī)與容器的端口映射關(guān)系
- "3306:3306" # 左邊宿主機(jī)端口:右邊容器端口
environment: # 創(chuàng)建容器時(shí)所需的環(huán)境變量
MYSQL_ROOT_PASSWORD: 1234
volumes:
# 絕對(duì)路徑
- "/mydata/docker_mysql/data:/var/lib/mysql"
# 相對(duì)路徑,相對(duì)當(dāng)前 docker-compose.yml 文件所在目錄
- “./conf:/etc/mysql/conf.d“
# 匿名掛載薪棒,匿名掛載只需要寫容器目錄即可手蝎,容器外對(duì)應(yīng)的目錄會(huì)在 /var/lib/docker/volume 中生成
- "/var/lib/mysql"
# 具名掛載,就是給數(shù)據(jù)卷起了個(gè)名字俐芯,容器外對(duì)應(yīng)的目錄會(huì)在 /var/lib/docker/volume 中生成
- "mysql-data-volume:/var/lib/mysql"
# 定義數(shù)據(jù)卷棵介,可以多個(gè)
volumes:
mysql-data-volume: # 一個(gè)具體數(shù)據(jù)卷的條目名稱
name: mysql-data-volume # 數(shù)據(jù)卷名稱,默認(rèn)為"工程名稱_數(shù)據(jù)卷?xiàng)l目名稱"
5.4.13 network_mode
設(shè)置網(wǎng)絡(luò)模式吧史,類似 docker run
時(shí)添加的參數(shù) --net host
或者 --network host
的用法邮辽。
network_mode: "bridge"
network_mode: "host"
network_mode: "none"
network_mode: "service:[service name]"
network_mode: "container:[container name/id]"
5.4.14 networks
配置容器連接的網(wǎng)絡(luò),引用頂級(jí) networks 下的條目贸营。
# 定義服務(wù)吨述,可以多個(gè)
services:
nginx: # 服務(wù)名稱
networks: # 配置容器連接的網(wǎng)絡(luò),引用頂級(jí) networks 下的條目
- nginx-net # 一個(gè)具體網(wǎng)絡(luò)的條目名稱
# 定義網(wǎng)絡(luò)钞脂,可以多個(gè)揣云。如果不聲明,默認(rèn)會(huì)創(chuàng)建一個(gè)網(wǎng)絡(luò)名稱為"工程名稱_default"的 bridge 網(wǎng)絡(luò)
networks:
nginx-net: # 一個(gè)具體網(wǎng)絡(luò)的條目名稱
name: nginx-net # 網(wǎng)絡(luò)名稱冰啃,默認(rèn)為"工程名稱_網(wǎng)絡(luò)條目名稱"
driver: bridge # 網(wǎng)絡(luò)模式邓夕,默認(rèn)為 bridge
aliases
網(wǎng)絡(luò)上此服務(wù)的別名。同一網(wǎng)絡(luò)上的其他容器可以使用服務(wù)名或此別名連接到服務(wù)容器阎毅。同一服務(wù)在不同的網(wǎng)絡(luò)上可以具有不同的別名焚刚。
# 定義服務(wù),可以多個(gè)
services:
nginx: # 服務(wù)名稱
networks: # 配置容器連接的網(wǎng)絡(luò)扇调,引用頂級(jí) networks 下的條目
nginx-net: # 一個(gè)具體網(wǎng)絡(luò)的條目名稱
aliases: # 服務(wù)別名矿咕,可以多個(gè)
- nginx1 # 同一網(wǎng)絡(luò)上的其他容器可以使用服務(wù)名或此別名連接到服務(wù)容器
# 定義網(wǎng)絡(luò),可以多個(gè)。如果不聲明痴腌,默認(rèn)會(huì)創(chuàng)建一個(gè)網(wǎng)絡(luò)名稱為"工程名稱_default"的 bridge 網(wǎng)絡(luò)
networks:
nginx-net: # 一個(gè)具體網(wǎng)絡(luò)的條目名稱
name: nginx-net # 網(wǎng)絡(luò)名稱雌团,默認(rèn)為"工程名稱_網(wǎng)絡(luò)條目名稱"
driver: bridge # 網(wǎng)絡(luò)模式,默認(rèn)為 bridge
5.5 volumes
通過頂級(jí)配置 services
的學(xué)習(xí)士聪,大家應(yīng)該已經(jīng)明白頂級(jí)配置 volumes
是干嘛的了锦援,這里再詳細(xì)把配置的不同方式研究一下。
以下方式的數(shù)據(jù)卷聲明創(chuàng)建卷時(shí)會(huì)使用默認(rèn)的名稱:"工程名稱_數(shù)據(jù)卷?xiàng)l目名稱"
剥悟。
# 描述 Compose 文件的版本信息
version: "3.8"
# 定義服務(wù)灵寺,可以多個(gè)
services:
mysql:
image: mysql:8
container_name: mysql8
ports:
- "3306:3306"
environment
MYSQL_ROOT_PASSWORD: 1234
volumes:
# 具名掛載,就是給數(shù)據(jù)卷起了個(gè)名字区岗,容器外對(duì)應(yīng)的目錄會(huì)在 /var/lib/docker/volume 中生成
- "mysql-data-volume:/var/lib/mysql"
# 定義數(shù)據(jù)卷略板,可以多個(gè)
volumes:
mysql-data-volume: # 一個(gè)具體數(shù)據(jù)卷的條目名稱
以下方式的數(shù)據(jù)卷聲明創(chuàng)建卷時(shí)會(huì)使用自定義的名稱。
# 描述 Compose 文件的版本信息
version: "3.8"
# 定義服務(wù)慈缔,可以多個(gè)
services:
mysql:
image: mysql:8
container_name: mysql8
ports:
- "3306:3306"
environment
MYSQL_ROOT_PASSWORD: 1234
volumes:
# 具名掛載叮称,就是給數(shù)據(jù)卷起了個(gè)名字,容器外對(duì)應(yīng)的目錄會(huì)在 /var/lib/docker/volume 中生成
- "mysql-data-volume:/var/lib/mysql"
# 定義數(shù)據(jù)卷藐鹤,可以多個(gè)
volumes:
mysql-data-volume: # 一個(gè)具體數(shù)據(jù)卷的條目名稱
name: mysql-data-volume # 數(shù)據(jù)卷名稱瓤檐,默認(rèn)為"工程名稱_數(shù)據(jù)卷?xiàng)l目名稱"
5.6 networks
通過頂級(jí)配置 services
的講解,大家其實(shí)已經(jīng)明白頂級(jí)配置 volumes
是干嘛的了娱节,這里再詳細(xì)把配置的不同方式研究一下挠蛉。
如果不聲明網(wǎng)絡(luò),每個(gè)工程默認(rèn)會(huì)創(chuàng)建一個(gè)網(wǎng)絡(luò)名稱為"工程名稱_default"
的 bridge
網(wǎng)絡(luò)肄满。
# 描述 Compose 文件的版本信息
version: "3.8"
# 定義服務(wù)谴古,可以多個(gè)
services:
nginx:
image: nginx
container_name: mynginx
ports:
- "80:80"
# 定義網(wǎng)絡(luò),可以多個(gè)稠歉。如果不聲明掰担,默認(rèn)會(huì)創(chuàng)建一個(gè)網(wǎng)絡(luò)名稱為"工程名稱_default"的 bridge 網(wǎng)絡(luò)
#networks:
以下方式的網(wǎng)絡(luò)聲明創(chuàng)建網(wǎng)絡(luò)時(shí)會(huì)使用默認(rèn)的名稱:"工程名稱_網(wǎng)絡(luò)條目名稱"
刃泡,網(wǎng)絡(luò)模式默認(rèn)為 bridge
预厌。
# 描述 Compose 文件的版本信息
version: "3.8"
# 定義服務(wù),可以多個(gè)
services:
nginx:
image: nginx
container_name: mynginx
ports:
- "80:80"
networks: # 配置容器連接的網(wǎng)絡(luò)乔外,引用頂級(jí) networks 下的條目
nginx-net:
# 定義網(wǎng)絡(luò)横媚,可以多個(gè)
networks:
nginx-net: # 一個(gè)具體網(wǎng)絡(luò)的條目名稱
以下方式的網(wǎng)絡(luò)聲明創(chuàng)建網(wǎng)絡(luò)時(shí)會(huì)使用自定義的名稱纠炮,還可以通過 driver
選擇網(wǎng)絡(luò)模式月趟,默認(rèn)為 bridge
灯蝴。
# 描述 Compose 文件的版本信息
version: "3.8"
# 定義服務(wù),可以多個(gè)
services:
nginx:
image: nginx
container_name: mynginx
ports:
- "80:80"
networks: # 配置容器連接的網(wǎng)絡(luò)孝宗,引用頂級(jí) networks 下的條目
nginx-net:
# 定義網(wǎng)絡(luò)穷躁,可以多個(gè)
networks:
nginx-net: # 一個(gè)具體網(wǎng)絡(luò)的條目名稱
name: nginx-net # 網(wǎng)絡(luò)名稱,默認(rèn)為"工程名稱_網(wǎng)絡(luò)條目名稱"
driver: bridge # 網(wǎng)絡(luò)模式,默認(rèn)為 bridge
六问潭、小結(jié)
Docker Compose 的整體使用步驟還是比較簡(jiǎn)單的猿诸,三個(gè)步驟為:
- 使用
Dockerfile
文件定義應(yīng)用程序的環(huán)境; - 使用
docker-compose.yml
文件定義構(gòu)成應(yīng)用程序的服務(wù)狡忙,這樣它們可以在隔離環(huán)境中一起運(yùn)行梳虽; - 最后,執(zhí)行
docker-compose up
命令來創(chuàng)建并啟動(dòng)所有服務(wù)灾茁。
雖然 docker-compose.yml 文件詳解和Compose 常用命令這兩大塊的內(nèi)容比較多窜觉,但是如果要快速入門使用 Compose
,其實(shí)只需要了解其中部分內(nèi)容即可北专。后期大家可在項(xiàng)目生產(chǎn)環(huán)境中根據(jù)自身情況再進(jìn)一步深入學(xué)習(xí)即可禀挫。