7.6 ENV 設定環境變數
7.6.1 基本語法
## 格式一:單個變數
ENV <key> <value>
## 格式二:多個變數(推薦)
ENV <key1>=<value1> <key2>=<value2> ...
7.6.2 基本用法
設定單個變數
ENV NODE_VERSION 20
ENV APP_ENV production
設定多個變數
ENV NODE_VERSION=20 \
APP_ENV=production \
APP_NAME="My Application"
💡 包含空格的值用雙引號括起來。
7.6.3 環境變數的作用
1. 後續指令中使用
ENV NODE_VERSION=20.10.0
## 在 RUN 中使用
RUN curl -fsSL https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-x64.tar.xz \
| tar -xJ -C /usr/local --strip-components=1
## 在 WORKDIR 中使用
ENV APP_HOME=/app
WORKDIR $APP_HOME
## 在 COPY 中使用
COPY . $APP_HOME
2. 容器執行時使用
ENV DATABASE_URL=postgres://localhost/mydb
應用程式碼中可以讀取:
import os
db_url = os.environ.get('DATABASE_URL')
const dbUrl = process.env.DATABASE_URL;
7.6.4 支援環境變數的指令
以下指令可以使用 $變數名` 或 `${變數名} 格式:
| 指令 | 範例 |
|---|---|
RUN |
RUN echo $VERSION |
CMD |
CMD ["sh", "-c", "echo $HOME"] |
ENTRYPOINT |
同上 |
COPY |
COPY . $APP_HOME |
ADD |
ADD app.tar.gz $APP_HOME |
WORKDIR |
WORKDIR $APP_HOME |
EXPOSE |
EXPOSE $PORT |
VOLUME |
VOLUME $DATA_DIR |
USER |
USER $USERNAME |
LABEL |
LABEL version=$VERSION |
FROM |
FROM node:$NODE_VERSION |
注意:
FROM是上表中的特例——它只能引用在第一條FROM之前用ARG宣告的變數,無法使用ENV定義的環境變數(ENV要進入建立階段後才生效)。其餘指令才能引用ENV環境變數。
7.6.5 執行時覆蓋
使用 -e 或 --env 覆蓋 Dockerfile 中定義的環境變數:
## 覆蓋單個變數
$ docker run -e APP_ENV=development myimage
## 覆蓋多個變數
$ docker run -e APP_ENV=development -e DEBUG=true myimage
## 從環境變數檔案讀取
$ docker run --env-file .env myimage
.env 檔案格式
## .env
APP_ENV=development
DEBUG=true
DATABASE_URL=postgres://localhost/mydb
7.6.6 ENV vs ARG
| 屬性 | ENV | ARG |
|---|---|---|
| 生效時間 | 建立時 + 執行時 | 僅建立時 |
| 持久性 | 寫入映象,執行時可用 | 建立後消失 |
| 覆蓋方式 | docker run -e |
docker build --build-arg |
| 適用場景 | 應用設定 | 建立引數 (如版本號) |
組合使用
## ARG 接收建立時引數
ARG NODE_VERSION=20
## ENV 儲存到執行時
ENV NODE_VERSION=$NODE_VERSION
## 後續指令使用
RUN curl -fsSL https://nodejs.org/dist/v${NODE_VERSION}/...
## 建立時指定版本
$ docker build --build-arg NODE_VERSION=18 -t myapp .
7.6.7 最佳實踐
1. 統一管理版本號
## ✅ 好:版本集中管理
ENV NGINX_VERSION=1.30 \
NODE_VERSION=22 \
PYTHON_VERSION=3.12
RUN apt-get install nginx=${NGINX_VERSION}
## ❌ 差:版本分散在各處
RUN apt-get install nginx=1.30
2. 不要儲存敏感訊息
## ❌ 錯誤:密碼寫入映象
ENV DB_PASSWORD=secret123
## ✅ 正確:執行時傳入
## docker run -e DB_PASSWORD=xxx myimage
...
3. 為應用提供合理預設值
ENV APP_ENV=production \
APP_PORT=8080 \
LOG_LEVEL=info
4. 使用有意義的變數名
## ✅ 好:清晰的命名
ENV REDIS_HOST=localhost \
REDIS_PORT=6379
## ❌ 差:模糊的命名
ENV HOST=localhost \
PORT=6379
7.6.8 常見問題
Q:環境變數在 CMD 中不展開
exec 格式不會自動執行 shell 展開,因此指令引數裡的 $PORT 會按字面值傳給程序;但環境變數本身仍會注入程序環境,應用可以透過語言執行時讀取。
## ❌ 不會展開 $PORT
CMD ["python", "app.py", "--port", "$PORT"]
## ✅ 使用 shell 格式或顯式呼叫 sh
CMD ["sh", "-c", "python app.py --port $PORT"]
Q:如何檢視容器的環境變數
$ docker inspect mycontainer --format '{{json .Config.Env}}'
$ docker exec mycontainer env
Q:多行 ENV 還是多個 ENV
## ✅ 推薦:減少層數
ENV VAR1=value1 \
VAR2=value2 \
VAR3=value3
## ⚠️ 多個 ENV 會建立多層
ENV VAR1=value1
ENV VAR2=value2
ENV VAR3=value3