使用插值在 Compose 檔案中設定、使用及管理變數
Compose 檔案可以使用變數來提供更大的靈活性。如果您想快速切換映像檔標籤以測試多個版本,或者想要根據您的本機環境調整 Volume 來源,您不需要每次都編輯 Compose 檔案,只需設定變數,即可在執行階段將值插入 Compose 檔案中。
插值也可以用於在執行階段將值插入 Compose 檔案中,這些值隨後會被傳遞到容器的環境變數中。
以下是一個簡單的範例
$ cat .env
TAG=v1.5
$ cat compose.yaml
services:
web:
image: "webapp:${TAG}"
當您執行 docker compose up 時,Compose 檔案中定義的 web 服務會插入 (interpolate) .env 檔案中設定的 webapp:v1.5 映像檔。您可以使用 config 指令來驗證這一點,該指令會將解析後的應用程式設定列印到終端機。
$ docker compose config
services:
web:
image: 'webapp:v1.5'
插值語法
插值適用於未引號和雙引號的值。同時支援括號 (${VAR}) 和無括號 ($VAR) 的運算式。
對於括號運算式,支援以下格式
- 直接替換
${VAR}->VAR的值
- 預設值
${VAR:-default}-> 如果VAR已設定且非空,則為其值;否則為default${VAR-default}-> 如果VAR已設定,則為其值;否則為default
- 必要值
${VAR:?error}-> 如果VAR已設定且非空,則為其值;否則以錯誤訊息退出${VAR?error}-> 如果VAR已設定,則為其值;否則以錯誤訊息退出
- 替代值
${VAR:+replacement}-> 如果VAR已設定且非空,則為replacement;否則為空${VAR+replacement}-> 如果VAR已設定,則為replacement;否則為空
更多資訊,請參閱 Compose 規範中的插值 (Interpolation)。
使用插值設定變數的方法
Docker Compose 可以將來自多個來源的變數插入您的 Compose 檔案中。
請注意,當多個來源宣告同一個變數時,會適用優先權順序。
- 來自 Shell 環境的變數
- 如果未設定
--env-file,則使用本地工作目錄 (PWD) 中.env檔案所設定的變數 - 來自
--env-file指定檔案或專案目錄中.env檔案的變數
您可以執行 docker compose config --environment 來檢查 Compose 用於插值 Compose 模型的變數及其值。
.env 檔案
Docker Compose 中的 .env 檔案是一個文字檔案,用於定義執行 docker compose up 時可供插值使用的變數。此檔案通常包含鍵值對 (key-value pairs),讓您可以將設定集中管理。如果您有多個需要儲存的變數,使用 .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.yaml中參照它。例如,如果您的.env檔案包含環境變數DEBUG=1,且您的compose.yaml檔案如下所示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 檔案語法
以下語法規則適用於環境檔案
以
#開頭的行會被視為註解並被忽略。空行會被忽略。
未加引號及雙引號 (
") 的值會套用插值。每一行代表一個鍵值對。值可以選擇加上引號。
VAR=VAL->VALVAR="VAL"->VALVAR='VAL'->VAL
未加引號值的行內註解必須在前面加上空格。
VAR=VAL # comment->VALVAR=VAL# not a comment->VAL# not a comment
加引號值的行內註解必須放在結束引號之後。
VAR="VAL # not a comment"->VAL # not a commentVAR="VAL" # comment->VAL
單引號 (
') 的值會被逐字使用。VAR='$OTHER'->$OTHERVAR='${OTHER}'->${OTHER}
引號可以使用
\進行跳脫。VAR='Let\'s go!'->Let's go!VAR="{\"hello\": \"json\"}"->{"hello": "json"}
雙引號值中支援常見的 Shell 跳脫序列,包括
\n、\r、\t和\\。VAR="some\tvalue"->some valueVAR='some\tvalue'->some\tvalueVAR=some\tvalue->some\tvalue
單引號值可以跨越多行。範例
KEY='SOME VALUE'如果您接著執行
docker compose config,您將會看到environment: KEY: |- SOME VALUE
使用 --env-file 進行替換
您可以在 .env 檔案中為多個環境變數設定預設值,然後在 CLI 中將該檔案作為參數傳遞。
這種方法的好處是您可以將檔案儲存在任何地方並適當命名,例如,此檔案路徑是相對於執行 Docker Compose 指令的當前工作目錄。傳遞檔案路徑是使用 --env-file 選項完成的。
$ docker compose --env-file ./config/.env.dev up
補充資訊
- 如果您想暫時覆蓋已經在
compose.yaml檔案中參照的.env檔案,此方法很有用。例如,您可能針對正式環境 (.env.prod) 和測試環境 (.env.test) 擁有不同的.env檔案。在以下範例中,有兩個環境檔案:.env和.env.dev。兩者都為TAG設定了不同的值。如果在命令列中未使用$ cat .env TAG=v1.5 $ cat ./config/.env.dev TAG=v1.6 $ cat compose.yaml 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 檔案也可用於宣告用於控制 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)。