- 一、Docker Compose 簡介
- 二、Docker Compose 安裝
- 2.1 Mac、Windows 平臺預設支援
- 2.2 Linux 安裝(透過包管理)
- 2.2.1 安裝
- 2.2.2 測試
- 2.2.3 解除安裝
- 2.3 使用PIP 安裝與解除安裝
- 2.3.1 PIP安裝
- 2.3.2 PIP 解除安裝
- 三、基本使用
- 3.1 術語
- 3.2 部署Flask 應用
- 四、Compose 常用命令
- 4.1 命令物件與格式
- 4.2 docker-compose 常用命令
- 4.2.1 config
- 4.2.2 pull
- 4.2.3 up
- 4.2.4 logs
- 4.2.5 ps
- 4.2.6 run
- 4.2.7 exec
- 4.2.8 pause
- 4.2.9 unpause
- 4.2.10 restart
- 4.2.11 start
- 4.2.12 stop
- 4.2.13 kill
- 4.2.14 rm
- 4.2.15 down
- 4.2.16 images
- 4.2.17 port
- 4.2.18 top
- 五、docker-compose.yml 檔案詳解
- 5.1 概念
- 5.2 案例
- 5.3 version
- 5.4 services
- 5.4.1 services 簡單舉例
- 5.4.2 image
- 5.4.3 build
- (一). context
- (二). dockerfile
- 5.4.4 container_name
- 關於序號
- 5.4.5 depends_on
- 5.4.6 ports
- 5.4.7 expose
- 5.4.8 restart
- 5.4.9 environment
- 5.4.10 env_file
- 5.4.11 command
- 5.4.12 volumes
- 5.4.13 network_mode
- 5.4.14 networks
- aliases
- 5.5 volumes
- 5.6 networks
- 六、小結
一、Docker Compose 簡介
Docker Compose
專案是 Docker 官方的開源專案,Compose
定位是 「定義和執行多個 Docker 容器的應用(Defining and running multi-container Docker applications
)」,來源於之前的 Fig 專案,使用 Python 語言編寫。負責實現對 Docker 容器叢集的快速編排。專案地址為:https://github.com/docker/compose/releases
Compose
的預設管理物件是專案,透過子命令對專案中的一組容器進行便捷地生命週期管理,實現上呼叫了 Docker 服務提供的 API 來對容器進行管理。因此,只要所操作的平臺支援 Docker API,就可以在其上利用 Compose
來進行編排管理。
我們知道使用一個 Dockerfile
模板檔案,可以讓使用者很方便的定義一個單獨的應用容器。然而,在日常工作中,經常會碰到需要多個容器相互配合來完成某項任務的情況。例如要實現一個 Web 專案,除了 Web 服務容器本身,往往還需要再加上後端的負載均衡容器等。
Docker Compose 恰好滿足了這樣的需求,它是用於定義和執行多容器 Docker 應用程式的工具。它允許使用者透過一個單獨的 docker-compose.yml
模板檔案(YAML 格式)來定義一組相關聯的應用容器為一個專案(project)。然後使用一個命令,就可以透過 YAML
配置檔案建立並啟動所有服務。
Compose
中有兩個重要的概念:
- 服務 (
service
):一個應用的容器,實際上可以包括若干執行相同映象的容器例項。 - 專案 (
project
):由一組關聯的應用容器組成的一個完整業務單元,在docker-compose.yml
檔案中定義。
Docker Compose 使用的三個步驟為:
- 使用
Dockerfile
檔案定義應用程式的環境; - 使用
docker-compose.yml
檔案定義構成應用程式的服務,這樣它們可以在隔離環境中一起執行; - 最後,執行
docker-compose up
命令來建立並啟動所有服務。
二、Docker Compose 安裝
官方文件:https://docs.docker.com/compose/install/linux/
2.1 Mac、Windows 平臺預設支援
Docker Desktop for Mac/Windows
自帶 docker-compose
二進位制檔案,安裝 Docker 之後可以直接使用。
$ docker-compose --version
Docker Compose version v2.23.3-desktop.2
2.2 Linux 安裝(透過包管理)
2.2.1 安裝
執行以下命令以下載Docker Compose的當前穩定版本:
# 烏班圖 安裝
sudo apt-get install docker-compose-plugin -y
# Centos 安裝
sudo yum install docker-compose-plugin -y
2.2.2 測試
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 當作一個 Python 應用來從 pip 源中安裝。
首先,確保你的系統已經安裝了Python和pip。你可以在終端中執行以下命令來檢查它們是否已經安裝:
python --version
pip --version
如果這些命令返回版本資訊,則說明Python和pip已經安裝。如果沒有安裝,請根據你使用的作業系統安裝Python和pip。
沒有安裝的話請參考教程:Linux系統安裝python3.8與解除安裝教程
接下來,使用pip安裝docker-compose。在終端中執行以下命令:
$ sudo pip install -U docker-compose
2.3.2 PIP 解除安裝
如果是透過 pip
安裝的,則執行如下命令即可刪除。
$ sudo pip uninstall docker-compose
三、基本使用
3.1 術語
首先介紹幾個術語。
- 服務 (
service
):一個應用容器,實際上可以執行多個相同映象的例項。 - 專案 (
project
):由一組關聯的應用容器組成的一個完整業務單元。
可見,一個專案可以由多個服務(容器)關聯而成,Compose
面向專案進行管理。
3.2 部署Flask 應用
下面我們部署一個web 網站,該專案應該包含 web 應用和快取。
我們用Flask 框架構建一個能夠記錄頁面訪問次數的 web 網站。
首先,建立一個簡單的 Flask 應用。建立一個新目錄 flask-app
,並在其中建立一個名為 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
檔案,內容為:
FROM python:3.12-alpine
ADD . /code
WORKDIR /code
RUN pip install redis flask
CMD ["python", "app.py"]
編寫 docker-compose.yml
檔案,這個是 Compose 使用的主模板檔案。
version: '3.0'
services:
web:
build: .
ports:
- "5000:5000"
redis:
image: "redis:alpine"
這個 docker-compose.yml
檔案定義了兩個服務:web
和 redis
。web
服務使用當前目錄下的 Dockerfile 構建,並將容器內的埠 5000 繫結到宿主機的埠 5000。web
服務依賴於 redis
服務。
在 flask-app
目錄中,執行以下命令來啟動應用:
docker compose up --build
這個命令會構建 Flask 應用的 Docker 映象,啟動 Redis 容器,然後啟動 Flask 應用容器。看到終端輸出如下,說明容器啟動起來了。
現在,您可以透過瀏覽器訪問 http://localhost:5000
來檢視您的 Flask 應用,並且每次重新整理頁面都會看到訪問次數的增加。
或者終端使用 curl
命令訪問本地執行的 Flask 應用
curl http://localhost:5000
如圖,此時訪問本地 5000
埠,每次重新整理頁面,計數就會加 1。
四、Compose 常用命令
4.1 命令物件與格式
docker compose
命令的基本的使用格式是
docker compose [-f <arg>...] [options] [COMMAND] [ARGS...]
部分命令選項如下:
-f,--file
:指定使用的 Compose 模板檔案,預設為docker-compose.yml
,可以多次指定,指定多個 yml;-p, --project-name
:指定工程名稱,預設使用docker-compose.yml
檔案所在目錄的名稱;-v
:列印版本並退出;--log-level
:定義日誌等級(DEBUG, INFO, WARNING, ERROR, CRITICAL)。
我們透過終端輸入命令docker compose
可以檢視到所有命令和選項:
用法: docker compose [選項] 命令
使用 Docker 定義和執行多容器應用程式
選項:
--ansi string 控制何時列印 ANSI 控制字元 ("never"|"always"|"auto")
(預設 "auto")
--compatibility 以向後相容模式執行 Compose
--dry-run 以幹執行模式執行命令
--env-file stringArray 指定一個替代的環境檔案
-f, --file stringArray 指定 Compose 配置檔案
--parallel int 控制最大並行性,-1 為無限制 (預設 -1)
--profile stringArray 指定要啟用的配置檔案
--progress string 設定進度輸出的型別 (auto, tty, plain, quiet) (預設 "auto")
--project-directory string 指定一個替代的工作目錄
(預設:第一個指定的 Compose 檔案的路徑)
-p, --project-name string 專案名稱
命令:
attach 將本地標準輸入、輸出和錯誤流附加到服務的執行容器上
build 構建或重建服務
config 解析、解析並呈現 Compose 檔案的規範格式
cp 在服務容器和本地檔案系統之間複製檔案/資料夾
create 為服務建立容器
down 停止並刪除容器和網路
events 從容器接收實時事件
exec 在執行中的容器內執行命令
images 列出由建立的容器使用的映象
kill 強制停止服務容器
logs 檢視容器的輸出
ls 列出執行中的 Compose 專案
pause 暫停服務
port 列印埠的公共埠繫結
ps 列出容器
pull 拉取服務映象
push 推送服務映象
restart 重啟服務容器
rm 刪除已停止的服務容器
run 對服務執行一次性命令
scale 設定服務執行的容器數量
start 啟動服務
stats 顯示容器的實時資源使用統計資訊
stop 停止服務
top 顯示正在執行的程序
unpause 恢復暫停的服務
up 建立並啟動容器
version 顯示 Docker Compose 版本資訊
wait 阻塞直到第一個服務容器停止
watch 監視服務的構建上下文,並在檔案更新時重建/重新整理容器
執行 'docker compose 命令 --help' 以獲取有關一個命令的更多資訊。
4.2 docker-compose 常用命令
4.2.1 config
docker compose config -q
驗證docker-compose.yml
檔案。當配置正確時,不輸出任何內容,當配置錯誤時,輸出錯誤資訊。
4.2.2 pull
docker compose pull
拉取服務依賴的映象。
# 拉取工程中所有服務依賴的映象
docker compose pull
# 拉取工程中 redis 服務依賴的映象
docker compose pull redis
# 拉取映象過程中不列印拉取進度資訊
docker compose pull -q
4.2.3 up
docker compose up
建立並啟動所有服務的容器。指定多個 yml 加 -f
選項。以守護程序模式執行加 -d
選項。
# 前臺啟動
docker compose up
# 後臺啟動
docker compose up -d
# -f 指定使用的 Compose 模板檔案,預設為 docker-compose.yml,可以多次指定,指定多個 yml
docker compose -f docker-compose.yml up -d
4.2.4 logs
docker compose logs
檢視服務容器的輸出日誌。預設情況下,docker-compose 將對不同的服務輸出使用不同的顏色來區分。可以透過 --no-color
來關閉顏色。
# 輸出日誌,不同的服務輸出使用不同的顏色來區分
docker compose logs
# 跟蹤日誌輸出
docker compose logs -f
# 關閉顏色
docker compose logs --no-color
4.2.5 ps
docker compose ps
列出工程中所有服務的容器。
# 列出工程中所有服務的容器
docker compose ps
# 列出工程中指定服務的容器
docker compose ps redis
4.2.6 run
docker compose run
在指定服務容器上執行一個命令。
# 在工程中指定服務的容器上執行 echo "hello"
docker compose run redis echo "hello"
4.2.7 exec
docker compose exec
進入服務容器。
# 進入工程中指定服務的容器
docker compose exec redis bash
# 當一個服務擁有多個容器時,可透過 --index 引數進入到該服務下的任何容器
docker compose exec --index=1 redis bash
4.2.8 pause
docker compose pause
暫停服務容器。
# 暫停工程中所有服務的容器
docker compose pause
# 暫停工程中指定服務的容器
docker compose pause redis
4.2.9 unpause
docker compose unpause
恢復服務容器。
# 恢復工程中所有服務的容器
docker compose unpause
# 恢復工程中指定服務的容器
docker compose unpause redis
4.2.10 restart
docker compose restart
重啟服務容器。
# 重啟工程中所有服務的容器
docker compose restart
# 重啟工程中指定服務的容器
docker compose restart redis
4.2.11 start
docker compose start
啟動服務容器。
# 啟動工程中所有服務的容器
docker compose start
# 啟動工程中指定服務的容器
docker compose start nginx
4.2.12 stop
docker compose stop
停止服務容器。
# 停止工程中所有服務的容器
docker compose stop
# 停止工程中指定服務的容器
docker compose stop redis
4.2.13 kill
docker compose kill
透過傳送 SIGKILL
訊號停止指定服務的容器。
# 透過傳送 SIGKILL 訊號停止工程中指定服務的容器
docker compose kill redis
4.2.14 rm
docker compose rm
刪除服務(停止狀態)容器。
# 刪除所有(停止狀態)服務的容器
docker compose rm
# 先停止所有服務的容器,再刪除所有服務的容器
docker compose rm -s
# 不詢問是否刪除,直接刪除
docker compose rm -f
# 刪除服務容器掛載的資料卷
docker compose rm -v
# 刪除工程中指定服務的容器
docker compose rm -sv redis
4.2.15 down
停止並刪除所有服務的容器、網路、映象、資料卷。
# 停止並刪除工程中所有服務的容器、網路
docker compose down
# 停止並刪除工程中所有服務的容器、網路、映象
docker compose down --rmi all
# 停止並刪除工程中所有服務的容器、網路、資料卷
docker compose down -v
4.2.16 images
docker compose images
列印服務容器所對應的映象。
# 列印所有服務的容器所對應的映象
docker compose images
# 列印指定服務的容器所對應的映象
docker compose images redis
4.2.17 port
docker compose port
列印指定服務容器的某個埠所對映的宿主機埠。
[root@VM-16-centos flask-app]# docker compose port nginx 80
0.0.0.0:80
4.2.18 top
docker compose top
顯示正在執行的程序。
# 顯示工程中所有服務的容器正在執行的程序
docker compose top
# 顯示工程中指定服務的容器正在執行的程序
docker compose top redis
五、docker-compose.yml 檔案詳解
5.1 概念
Docker Compose 允許使用者透過 docker-compose.yml
檔案(YAML 格式)來定義一組相關聯的容器為一個工程(project)
。一個工程包含多個服務(service)
,每個服務中定義了建立容器時所需的映象、引數、依賴等。
工程名若無特殊指定,即為
docker-compose.yml
檔案所在目錄的名稱。
Docker Compose 模板檔案我們需要關注的頂級配置有:version
、services
、networks
、volumes
幾個部分,除 version
外,其他幾個頂級配置下還有很多下級配置,後面也會詳細給大家介紹,先來看看這幾個頂級配置都什麼意思:
version
:描述 Compose 檔案的版本資訊,當前最新版本為3.8
,對應的 Docker 版本為19.03.0+
;services
:定義服務,可以多個,每個服務中定義了建立容器時所需的映象、引數、依賴等;networkds
:定義網路,可以多個,根據 DNS server 讓相同網路中的容器可以直接透過容器名稱進行通訊;volumes
:資料卷,用於實現目錄掛載。
5.2 案例
在配置檔案中,所有的容器透過 services
來定義,然後使用 docker-compose
指令碼來啟動,停止和重啟容器,非常適合多個容器組合使用進行開發的場景。我們先從一個簡單的 Compose 案例開始。我們編寫第一個 docker-compose.yml
檔案。
# 建立目錄
mkdir -p ./docker-nginx
# 切換至指定目錄
cd ./docker-nginx/
# 編寫 docker-compose.yml 檔案
vi docker-compose.yml
在檔案 docker-compose.yml
檔案中新增以下內容:
# 描述 Compose 檔案的版本資訊
version: "3.8"
# 定義服務,可以多個
services:
nginx: # 服務名稱
image: nginx # 建立容器時所需的映象
container_name: mynginx # 容器名稱,預設為"工程名稱_服務條目名稱_序號"
ports: # 宿主機與容器的埠對映關係
- "80:80" # 左邊宿主機埠:右邊容器埠
networks: # 配置容器連線的網路,引用頂級 networks 下的條目
- nginx-net
# 定義網路,可以多個。如果不宣告,預設會建立一個網路名稱為"工程名稱_default"的 bridge 網路
networks:
nginx-net: # 一個具體網路的條目名稱
name: nginx-net # 網路名稱,預設為"工程名稱_網路條目名稱"
driver: bridge # 網路模式,預設為 bridge
使用 docker-compose up
建立並啟動所有服務。
# 前臺啟動
docker-compose up
# 後臺啟動
docker-compose up -d
瀏覽器訪問:http://localhost/結果如下:
使用 docker-compose down
可以停止並刪除容器、網路。
5.3 version
version
是Docker Compose檔案的一個主要組成部分,用於指定當前Docker Compose檔案的版本。
version
欄位通常在檔案的頂部進行定義,如下所示:
version: "3.8"
在這個例子中,version
被設定為'3.8'
,這意味著這個Docker Compose檔案使用的是3.8版本的語法和功能。
重要的是要注意不同版本的Docker Compose之間可能存在不相容性。因此,在升級或更改您的docker-compose.yaml
檔案時,請確保檢視有關版本的特定說明和變更日誌,以便了解您當前所使用版本的支援的功能和變更情況。
官網提供的連結比較老了,且compose版本和其version欄位不相同,對應起來比較麻煩(二者的對應關係可以參考連結)
5.4 services
剛才我們提到 docker-compose.yml
檔案中包含很多下級配置項,下面帶大家把一些常用的配置項詳細瞭解一下,先從頂級配置 services
開始。
services
用來定義服務,可以多個,每個服務中定義了建立容器時所需的映象、引數、依賴等,就像將命令列引數傳遞給 docker run
一樣。同樣,網路和資料卷的定義也是一樣的。
5.4.1 services 簡單舉例
舉個例子,之前我們透過 docker run
命令構建一個 MySQL 應用容器的命令如下:
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"
# 定義服務,可以多個
services:
mysql: # 服務名稱
image: mysql:8 # 建立容器時所需的映象以及版本號
container_name: mysql8 # 容器名稱,預設為"工程名稱_服務條目名稱_序號"
ports: # 宿主機與容器的埠對映關係
- "3306:3306" # 左邊宿主機埠:右邊容器埠
environment: # 建立容器時所需的環境變數
MYSQL_ROOT_PASSWORD: 1234 # MySQL root 使用者的密碼
volumes:
- "/mydata/docker_mysql/conf:/etc/mysql/conf.d"
- "/mydata/docker_mysql/data:/var/lib/mysql"
然後透過 dokcer-compose
相關命令即可完成容器的建立,停止或刪除等一系列操作。
5.4.2 image
指定建立容器時所需的映象名稱標籤或者映象 ID。如果映象在本地不存在,會去遠端拉取。
services:
web:
image: mysql:8
5.4.3 build
除了可以基於指定的映象構建容器,還可以基於 Dockerfile
檔案構建,在使用 up
命令時會執行構建任務。
透過 build
配置項可以指定 Dockerfile
所在資料夾的路徑。Compose 將會利用 Dockerfile
自動構建映象,然後使用映象啟動服務容器。
build
配置項可以使用絕對路徑,也可以使用相對路徑。
# 絕對路徑,在該路徑下基於名稱為 Dockerfile 的檔案構建映象
/usr/local/docker-centos
# 相對路徑,相對當前 docker-compose.yml 檔案所在目錄,基於名稱為 Dockerfile 的檔案構建映象
.
接下來我們來個稍微複雜點的練習,首先我們使用Go編寫一個HTTP Server:
建立一個目錄:
# 建立目錄
mkdir -p /usr/local/docker-centos
# 切換至指定目錄
cd /usr/local/docker-centos/
mkdir ./httpserver
編寫main.go內容如下:
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")
}
接著透過基礎映象 centos:8
,在該映象中安裝 go 和 並且執行HTTP Server以後將其製作為一個新的映象 mycentos:8
。編寫 Dockerfile
檔案。
# 編寫 Dockerfile 檔案
vi Dockerfile
Dockerfile
檔案內容如下:
# 指明構建的新映象是來自於 centos:8 基礎映象
FROM centos:8
# 透過映象標籤宣告瞭作者資訊
LABEL maintainer="blog.jarvis.com"
# 設定工作目錄
WORKDIR /usr/local
# 複製 Go 語言壓縮包並解壓到指定目錄
ADD go1.22.1.linux-amd64.tar.gz /usr/local/
# 設定 Go 環境變數
ENV GOROOT=/usr/local/go
ENV GOPATH=/usr/local/gopath
ENV PATH=$PATH:$GOROOT/bin:$GOPATH/bin
# 將 httpserver 程式碼複製到容器中
COPY ./httpserver /usr/local/httpserver
# 設定工作目錄到 httpserver 目錄
WORKDIR /usr/local/httpserver
# 編譯 Go HTTP 伺服器
RUN go build -o httpserver main.go
# 暴露容器執行時的 8080 監聽埠給外部
EXPOSE 8080
# 使用 CMD 執行 HTTP 伺服器
CMD ["./httpserver"]
接著透過如下命令下載Go 編譯器:
# 下載GO 編譯器
wget https://golang.google.cn/dl/go1.22.1.linux-amd64.tar.gz
建立目錄並編寫 docker-compose.yml
檔案。
# 描述 Compose 檔案的版本資訊
version: "3.8"
# 定義服務,可以多個
services:
mycentos: # 服務名稱
build: . # 相對當前 docker-compose.yml 檔案所在目錄,基於名稱為 Dockerfile-alternate 的檔案構建映象
container_name: mycentos7 # 容器名稱,預設為"工程名稱_服務條目名稱_序號"
ports: # 宿主機與容器的埠對映關係
- "8080:8080" # 左邊宿主機埠:右邊容器埠
然後透過 dokcer-compose
相關命令即可完成容器的建立,停止或刪除等一系列操作。
(一). context
該選項可以是 Dockerfile 檔案的絕對/相對路徑,也可以是遠端 Git 倉庫的 URL,當提供的值是相對路徑時,相對當前 docker-compose.yml 檔案所在目錄。
build:
context: . # 相對當前 docker-compose.yml 檔案所在目錄,基於名稱為 Dockerfile 的檔案構建映象
(二). dockerfile
一般情況下,預設都基於檔名叫 Dockerfile 的檔案構建映象,當然也可以是自定義的檔名,使用 dockerfile
宣告,不過這個選項只能宣告檔名,檔案所在路徑還是要透過 centext 來宣告。
build:
context: . # 相對當前 docker-compose.yml 檔案所在目錄
dockerfile: Dockerfile-alternate # 基於名稱為 Dockerfile-alternate 的檔案構建映象
5.4.4 container_name
Compose 建立的容器預設生成的名稱格式為:工程名稱_服務條目名稱_序號
。如果要使用自定義名稱,使用 container_name
宣告。
services:
mycentos:
build: .
container_name: mycentos7 # 容器名稱,預設為"工程名稱_服務條目名稱_序號"
因為 Docker 容器名稱必須是唯一的,所以如果指定了自定義名稱,就不能將服務擴充套件至多個容器。這樣做可能會導致錯誤。
關於序號
序號是幹什麼用的呢,看下面這個列子你就懂了,docker-compose.yml
檔案內容如下:
# 描述 Compose 檔案的版本資訊
version: "3.8"
# 定義服務,可以多個
services:
helloworld: # 服務名稱
image: hello-world
然後透過 --scale
指定 helloworld
服務一次性啟動 3 個。
docker-compose up -d --scale helloworld=3
透過下圖可以看到有 3 個容器被建立,容器名稱最後的序號是從 1 開始累加的,這就是序號的作用。所以如果指定了自定義名稱,就不能將服務擴充套件至多個容器。
5.4.5 depends_on
使用 Compose 最大的好處就是敲最少的命令做更多的事情,但一般專案容器啟動的順序是有要求的,如果直接從上到下啟動容器,必然會因為容器依賴問題而啟動失敗。例如在沒有啟動資料庫容器的情況下啟動了 Web 應用容器,應用容器會因為找不到資料庫而退出。depends_on
就是用來解決容器依賴、啟動先後問題的配置項。
version: "3.8"
services:
web:
build: .
depends_on:
- db
- redis
redis:
image: redis
db:
image: mysql
上述 YAML 檔案定義的容器會先啟動 db 和 redis 兩個服務,最後才啟動 web 服務。
5.4.6 ports
容器對外暴露的埠,格式:左邊宿主機埠:右邊容器埠
。
ports:
- "80:80"
- "8080:8080"
5.4.7 expose
容器暴露的埠不對映到宿主機,只允許能被連線的服務訪問。
expose:
- "80"
- "8080"
5.4.8 restart
容器重啟策略,簡單的理解就是 Docker 重啟以後容器要不要一起啟動:
no
:預設的重啟策略,在任何情況下都不會重啟容器;on-failure
:容器非正常退出時,比如退出狀態為非0
(異常退出),才會重啟容器;always
:容器總是重新啟動,即使容器被手動停止了,當 Docker 重啟時容器也還是會一起啟動;unless-stopped
:容器總是重新啟動,除非容器被停止(手動或其他方式),那麼 Docker 重啟時容器則不會啟動。
services:
nginx:
image: nginx
container_name: mynginx
ports:
- "80:80"
restart: always
5.4.9 environment
新增環境變數。可以使用陣列也可以使用字典。布林相關的值(true、false、yes、no)都需要用引號括起來,以確保 YML 解析器不會將它們轉換為真或假。
environment:
RACK_ENV: development
SHOW: 'true'
SESSION_SECRET:
或者以下格式:
environment:
- RACK_ENV=development
- SHOW=true
- SESSION_SECRET
5.4.10 env_file
從檔案中獲取環境變數,可以指定一個或多個檔案,其優先順序低於 environment 指定的環境變數。
env_file:
- /opt/runtime_opts.env # 絕對路徑
- ./common.env # 相對路徑,相對當前 docker-compose.yml 檔案所在目錄
- ./apps/web.env # 相對路徑,相對當前 docker-compose.yml 檔案所在目錄
注意:env 檔案中的每一行需採用
鍵=值
格式。以#
開頭的行會被視為註釋並被忽略。空行也會被忽略。
5.4.11 command
覆蓋容器啟動後預設執行的命令。
command: echo "helloworld"
該命令也可以是一個列表。
command: ["echo", "helloworld"]
5.4.12 volumes
資料卷,用於實現目錄掛載,支援指定目錄掛載、匿名掛載、具名掛載。
- 指定目錄掛載的格式為:
左邊宿主機目錄:右邊容器目錄
,或者左邊宿主機目錄:右邊容器目錄:讀寫許可權
; - 匿名掛載格式為:
容器目錄即可
,或者容器目錄即可:讀寫許可權
; - 具名掛載格式為:
資料卷條目名稱:容器目錄
,或者資料卷條目名稱:容器目錄:讀寫許可權
。
# 描述 Compose 檔案的版本資訊
version: "3.8"
# 定義服務,可以多個
services:
mysql: # 服務名稱
image: mysql:8 # 建立容器時所需的映象
container_name: mysql8 # 容器名稱,預設為"工程名稱_服務條目名稱_序號"
ports: # 宿主機與容器的埠對映關係
- "3306:3306" # 左邊宿主機埠:右邊容器埠
environment: # 建立容器時所需的環境變數
MYSQL_ROOT_PASSWORD: 1234
volumes:
# 絕對路徑
- "/mydata/docker_mysql/data:/var/lib/mysql"
# 相對路徑,相對當前 docker-compose.yml 檔案所在目錄
- “./conf:/etc/mysql/conf.d“
# 匿名掛載,匿名掛載只需要寫容器目錄即可,容器外對應的目錄會在 /var/lib/docker/volume 中生成
- "/var/lib/mysql"
# 具名掛載,就是給資料捲起了個名字,容器外對應的目錄會在 /var/lib/docker/volume 中生成
- "mysql-data-volume:/var/lib/mysql"
# 定義資料卷,可以多個
volumes:
mysql-data-volume: # 一個具體資料卷的條目名稱
name: mysql-data-volume # 資料卷名稱,預設為"工程名稱_資料卷條目名稱"
5.4.13 network_mode
設定網路模式,類似 docker run
時新增的引數 --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
配置容器連線的網路,引用頂級 networks 下的條目。
# 定義服務,可以多個
services:
nginx: # 服務名稱
networks: # 配置容器連線的網路,引用頂級 networks 下的條目
- nginx-net # 一個具體網路的條目名稱
# 定義網路,可以多個。如果不宣告,預設會建立一個網路名稱為"工程名稱_default"的 bridge 網路
networks:
nginx-net: # 一個具體網路的條目名稱
name: nginx-net # 網路名稱,預設為"工程名稱_網路條目名稱"
driver: bridge # 網路模式,預設為 bridge
aliases
網路上此服務的別名。同一網路上的其他容器可以使用服務名或此別名連線到服務容器。同一服務在不同的網路上可以具有不同的別名。
# 定義服務,可以多個
services:
nginx: # 服務名稱
networks: # 配置容器連線的網路,引用頂級 networks 下的條目
nginx-net: # 一個具體網路的條目名稱
aliases: # 服務別名,可以多個
- nginx1 # 同一網路上的其他容器可以使用服務名或此別名連線到服務容器
# 定義網路,可以多個。如果不宣告,預設會建立一個網路名稱為"工程名稱_default"的 bridge 網路
networks:
nginx-net: # 一個具體網路的條目名稱
name: nginx-net # 網路名稱,預設為"工程名稱_網路條目名稱"
driver: bridge # 網路模式,預設為 bridge
5.5 volumes
透過頂級配置 services
的學習,大家應該已經明白頂級配置 volumes
是幹嘛的了,這裡再詳細把配置的不同方式研究一下。
以下方式的資料卷宣告建立卷時會使用預設的名稱:"工程名稱_資料卷條目名稱"
。
# 描述 Compose 檔案的版本資訊
version: "3.8"
# 定義服務,可以多個
services:
mysql:
image: mysql:8
container_name: mysql8
ports:
- "3306:3306"
environment
MYSQL_ROOT_PASSWORD: 1234
volumes:
# 具名掛載,就是給資料捲起了個名字,容器外對應的目錄會在 /var/lib/docker/volume 中生成
- "mysql-data-volume:/var/lib/mysql"
# 定義資料卷,可以多個
volumes:
mysql-data-volume: # 一個具體資料卷的條目名稱
以下方式的資料卷宣告建立卷時會使用自定義的名稱。
# 描述 Compose 檔案的版本資訊
version: "3.8"
# 定義服務,可以多個
services:
mysql:
image: mysql:8
container_name: mysql8
ports:
- "3306:3306"
environment
MYSQL_ROOT_PASSWORD: 1234
volumes:
# 具名掛載,就是給資料捲起了個名字,容器外對應的目錄會在 /var/lib/docker/volume 中生成
- "mysql-data-volume:/var/lib/mysql"
# 定義資料卷,可以多個
volumes:
mysql-data-volume: # 一個具體資料卷的條目名稱
name: mysql-data-volume # 資料卷名稱,預設為"工程名稱_資料卷條目名稱"
5.6 networks
透過頂級配置 services
的講解,大家其實已經明白頂級配置 volumes
是幹嘛的了,這裡再詳細把配置的不同方式研究一下。
如果不宣告網路,每個工程預設會建立一個網路名稱為"工程名稱_default"
的 bridge
網路。
# 描述 Compose 檔案的版本資訊
version: "3.8"
# 定義服務,可以多個
services:
nginx:
image: nginx
container_name: mynginx
ports:
- "80:80"
# 定義網路,可以多個。如果不宣告,預設會建立一個網路名稱為"工程名稱_default"的 bridge 網路
#networks:
以下方式的網路宣告建立網路時會使用預設的名稱:"工程名稱_網路條目名稱"
,網路模式預設為 bridge
。
# 描述 Compose 檔案的版本資訊
version: "3.8"
# 定義服務,可以多個
services:
nginx:
image: nginx
container_name: mynginx
ports:
- "80:80"
networks: # 配置容器連線的網路,引用頂級 networks 下的條目
nginx-net:
# 定義網路,可以多個
networks:
nginx-net: # 一個具體網路的條目名稱
以下方式的網路宣告建立網路時會使用自定義的名稱,還可以透過 driver
選擇網路模式,預設為 bridge
。
# 描述 Compose 檔案的版本資訊
version: "3.8"
# 定義服務,可以多個
services:
nginx:
image: nginx
container_name: mynginx
ports:
- "80:80"
networks: # 配置容器連線的網路,引用頂級 networks 下的條目
nginx-net:
# 定義網路,可以多個
networks:
nginx-net: # 一個具體網路的條目名稱
name: nginx-net # 網路名稱,預設為"工程名稱_網路條目名稱"
driver: bridge # 網路模式,預設為 bridge
六、小結
Docker Compose 的整體使用步驟還是比較簡單的,三個步驟為:
- 使用
Dockerfile
檔案定義應用程式的環境; - 使用
docker-compose.yml
檔案定義構成應用程式的服務,這樣它們可以在隔離環境中一起執行; - 最後,執行
docker-compose up
命令來建立並啟動所有服務。
雖然 docker-compose.yml 檔案詳解和Compose 常用命令這兩大塊的內容比較多,但是如果要快速入門使用 Compose
,其實只需要瞭解其中部分內容即可。後期大家可在專案生產環境中根據自身情況再進一步深入學習即可。
本文由部落格一文多發平臺 OpenWrite 釋出!