使用插值在 Compose 檔案中設定、使用和管理變數
Compose 檔案可以使用變數來提供更大的彈性。如果您想在映像檔標籤之間快速切換以測試多個版本,或者想將磁碟區來源調整到您的本機環境,您不需要每次都編輯 Compose 檔案,只需設定在執行階段將值插入 Compose 檔案的變數即可。
插值也可以用於在執行階段將值插入 Compose 檔案,然後用於將變數傳遞到容器的環境中
以下是一個簡單的範例
$ cat .env
TAG=v1.5
$ cat compose.yml
services:
web:
image: "webapp:${TAG}"
當您執行 docker compose up
時,Compose 檔案中定義的 web
服務會插入在 .env
檔案中設定的映像檔 webapp:v1.5
。您可以使用 config 命令 驗證這一點,該命令會將您解析的應用程式設定列印到終端機
$ docker compose config
services:
web:
image: 'webapp:v1.5'
插值語法
插值適用於未加引號和雙引號的值。支援大括號 (${VAR}
) 和無大括號 ($VAR
) 的表達式。
對於大括號表達式,支援以下格式
- 直接替代
${VAR}
->VAR
的值
- 預設值
${VAR:-default}
-> 如果VAR
已設定且不為空,則為VAR
的值,否則為default
${VAR-default}
-> 如果VAR
已設定,則為VAR
的值,否則為default
- 必要值
${VAR:?error}
-> 如果VAR
已設定且不為空,則為VAR
的值,否則以錯誤訊息結束${VAR?error}
-> 如果VAR
已設定,則為VAR
的值,否則以錯誤訊息結束
- 替代值
${VAR:+replacement}
-> 如果VAR
已設定且不為空,則為replacement
,否則為空${VAR+replacement}
-> 如果VAR
已設定,則為replacement
,否則為空
如需詳細資訊,請參閱 Compose 規格中的 插值。
使用插值設定變數的方法
Docker Compose 可以從多個來源將變數插入您的 Compose 檔案。
請注意,當多個來源宣告相同的變數時,會套用優先順序
- 來自您的 shell 環境的變數
- 如果未設定
--env-file
,則由本機工作目錄 (PWD
) 中的.env
檔案設定的變數 - 來自
--env-file
設定的檔案或專案目錄中的.env
檔案的變數
您可以透過執行 docker compose config --environment
來檢查 Compose 用於插入 Compose 模型的變數和值。
.env
檔案
Docker Compose 中的 .env
檔案是一個文字檔,用於定義在執行 docker compose up
時應該可供插值使用的變數。這個檔案通常包含變數的鍵值對,它可以讓您集中管理一個地方的設定。如果您需要儲存多個變數,.env
檔案會很有用。
.env
檔案是設定變數的預設方法。.env
檔案應放在專案目錄的根目錄中,與您的 compose.yaml
檔案放在一起。如需格式化環境檔案的詳細資訊,請參閱 環境檔案的語法。
基本範例
$ cat .env
## define COMPOSE_DEBUG based on DEV_MODE, defaults to false
COMPOSE_DEBUG=${DEV_MODE:-false}
$ cat compose.yaml
services:
webapp:
image: my-webapp-image
environment:
- DEBUG=${COMPOSE_DEBUG}
$ DEV_MODE=true docker compose config
services:
webapp:
environment:
DEBUG: "true"
其他資訊
如果您在
.env
檔案中定義變數,您可以使用environment
屬性 直接在compose.yml
中參考它。例如,如果您的.env
檔案包含環境變數DEBUG=1
,而您的compose.yml
檔案如下所示services: webapp: image: my-webapp-image environment: - DEBUG=${DEBUG}
Docker Compose 會將
${DEBUG}
替換為.env
檔案中的值重要
在容器環境中使用環境變數時,請注意環境變數的優先順序,尤其是在
.env
檔案和容器環境中同時定義變數的情況下。您可以將
.env
檔案放置在專案目錄根目錄以外的位置,然後使用CLI 中的--env-file
選項,以便 Compose 可以找到它。如果使用
--env-file
指定另一個.env
檔案,則您的.env
檔案會被覆蓋。
重要
從
.env
檔案進行變數替換是 Docker Compose CLI 的功能。在執行
docker stack deploy
時,Swarm 不支援此功能。
.env
檔案語法
環境變數檔案適用以下語法規則
- 以
#
開頭的行會被視為註釋並忽略。 - 空行會被忽略。
- 未加引號和雙引號 (
"
) 的值會套用插值 (interpolation)。 - 每一行代表一個鍵值對。值可以選擇性地用引號括起來。
VAR=VAL
->VAL
VAR="VAL"
->VAL
VAR='VAL'
->VAL
- 未加引號的值的內嵌註釋必須以空格開頭。
VAR=VAL # 註釋
->VAL
VAR=VAL# 不是註釋
->VAL# 不是註釋
- 加引號的值的內嵌註釋必須在結尾引號之後。
VAR="VAL # 不是註釋"
->VAL # 不是註釋
VAR="VAL" # 註釋
->VAL
- 單引號 (
'
) 的值會被逐字使用。VAR='$OTHER'
->$OTHER
VAR='${OTHER}'
->${OTHER}
- 引號可以使用
\
進行跳脫。VAR='Let\'s go!'
->Let's go!
VAR="{\"hello\": \"json\"}"
->{"hello": "json"}
- 雙引號值支援常見的 shell 跳脫序列,包括
\n
、\r
、\t
和\\
。VAR="some\tvalue"
->some value
VAR='some\tvalue'
->some\tvalue
VAR=some\tvalue
->some\tvalue
使用 --env-file
替代
您可以在 .env
檔案中設定多個環境變數的預設值,然後將檔案作為參數傳遞給 CLI。
這種方法的優點是您可以將檔案儲存在任何位置並為其命名,例如,此檔案路徑是相對於執行 Docker Compose 命令的目前工作目錄。使用 --env-file
選項傳遞檔案路徑
$ docker compose --env-file ./config/.env.dev up
其他資訊
- 如果您想暫時覆蓋
compose.yml
檔案中已引用的.env
檔案,這個方法會很有用。例如,您可能會有不同的.env
檔案用於生產環境 (.env.prod
) 和測試環境 (.env.test
)。在以下範例中,有兩個環境檔案,.env
和.env.dev
。兩者都為TAG
設定了不同的值。如果命令列中未使用$ cat .env TAG=v1.5 $ cat ./config/.env.dev TAG=v1.6 $ cat compose.yml services: web: image: "webapp:${TAG}"
--env-file
,則預設會載入.env
檔案傳遞$ docker compose config services: web: image: 'webapp:v1.5'
--env-file
參數會覆蓋預設檔案路徑當傳遞無效的檔案路徑作為$ docker compose --env-file ./config/.env.dev config services: web: image: 'webapp:v1.6'
--env-file
參數時,Compose 會傳回錯誤$ docker compose --env-file ./doesnotexist/.env.dev config ERROR: Couldn't find env file: /home/user/./doesnotexist/.env.dev
- 您可以使用多個
--env-file
選項來指定多個環境檔案,Docker Compose 會依序讀取它們。後面的檔案可以覆蓋先前檔案中的變數。$ docker compose --env-file .env --env-file .env.override up
- 您可以在啟動容器時從命令列覆蓋特定的環境變數。
$ docker compose --env-file .env.dev up -e DATABASE_URL=mysql://new_user:new_password@new_db:3306/new_database
本地 .env
檔案與.env
檔案
.env
檔案.env
檔案也可以用來宣告預先定義的環境變數,用於控制 Compose 行為和要載入的檔案。
在沒有明確使用 --env-file
旗標的情況下執行時,Compose 會在您的工作目錄 (PWD) 中搜尋 .env
檔案,並載入用於自我設定和插值的值。如果此檔案中的值定義了 COMPOSE_FILE
預先定義的變數,導致專案目錄被設定到另一個資料夾,Compose 將會載入第二個 .env
檔案(如果有的話)。第二個 .env
檔案的優先順序較低。
這種機制使得使用一組自定義變數作為覆蓋來叫用現有 Compose 專案成為可能,而無需透過命令列傳遞環境變數。
$ cat .env
COMPOSE_FILE=../compose.yaml
POSTGRES_VERSION=9.3
$ cat ../compose.yaml
services:
db:
image: "postgres:${POSTGRES_VERSION}"
$ cat ../.env
POSTGRES_VERSION=9.2
$ docker compose config
services:
db:
image: "postgres:9.3"
從 shell 替代
您可以使用主機或執行 docker compose
命令的 shell 環境中現有的環境變數。這讓您可以在執行階段將值動態插入 Docker Compose 設定中。例如,假設 shell 包含 POSTGRES_VERSION=9.3
,並且您提供以下設定
db:
image: "postgres:${POSTGRES_VERSION}"
當您使用此設定執行 docker compose up
時,Compose 會在 shell 中搜尋 POSTGRES_VERSION
環境變數並替換其值。在本例中,Compose 會在執行設定之前將映像解析為 postgres:9.3
。
如果未設定環境變數,Compose 會以空字串替換。在前面的範例中,如果未設定 POSTGRES_VERSION
,則 image 選項的值為 postgres:
。
注意事項
postgres:
不是有效的映像參考。Docker 需要不帶標籤的參考,例如預設為最新映像的postgres
,或者帶有標籤的參考,例如postgres:15
。