科技新知

Docker Variable control

我們在Docker Image的打包時,最簡單當然就是每個步驟都使用最新版本。例如Docker Base Image,大家可能選用latest tag,安裝linux package (Linux包),也可能就apt install / yum 安裝最新的穩定版本。但如果我們想要更好地做測試,就要使用指定版本,方便追蹤問題。而Docker在打包和運行時,都有不同的方式讓大家定義或覆寫指定參數。

Docker build arg

我們先從打包Image開始。

例如我們需要使用一個Base image為 ubuntu,版本預設為22.04,但有需要時可以經build指令覆寫,可以這樣寫

ARG ubuntu_version=22.04
FROM ubuntu:${ubuntu_version}
 
# default ubuntu_version=22.04
docker image build -t test2204 ./
# or overwrite by --build-arg
docker image build -t test2404 --build-arg="ubuntu_version=24.04"
 

雖然Dockerfile的RUN指令都是使用linux shell,但在Dockerfile中想表達條件控制(if else statment)就不太易看。在外部加入script做控制,是另一個可行的後備選擇,它更可以連image名字也進行參數化。

# in bash script, you also canif [ $beta==true ]
then
    ubuntu_version=24.04
else
    ubuntu_version=22.04
fi

docker image build -t test:${ubuntu_version} --build-arg ubuntu_version=${ubuntu_version}
 

Docker Container Run and Docker Compose

一般來講,Linux Container 在執行時,就等於進入Linux Shell。也就是,我們可以使用Shell中的環境變數。

我們在打包Image前,已經可以在Dockerfile中定義自己的ENV數參(也就是環境變數)。與前面的Build Arg有所不同的是,ENV是定義在Dockerfile中,在Container運行時以環境變數的形式存在,它也可以在運行中被改變。而Arg,則只在打包Image時存在,運行期間就不存在了。(當然,你在打包時,用Arg傳入Env,以運到這個目的。)

另一個更特別的性質是,那怕ENV沒有定義在Dockerfile中,我們運行時也可以加入更多的環境變數,大家就當成是一般Linux操作,隨時在自己的shell中加入變數。

# -e, --env for inline variable# --env-file for file
docker container run -e MYVAR1 --env MYVAR2=foo --env-file ./env.list ubuntu bash
 

同樣地Docker compose,也支援環境變數。筆者建議environment可以使用Array格式,日後可以更方便地直接改為env_file。

# docker-compose.yamlservices:
  ubuntu:
    image: ubuntu:22.04environment:
      - RACK_ENV=development
      - SHOW=true
      - USER_INPUT
 

上述的寫法沒有任何問題,不過如果你的docker-compose.yaml是放在git等版本控制中,你更新環境變數就有可能會影響到其他人,這時你就會想轉成env_file。

docker-compose.yaml預設就會讀當前資料夾的.env,就算不存在,也可以正常運行。(當然,大家的Image/Container應該要有預設值)

# docker-compose.yamlservices:
  ubuntu:
    image: ubuntu:22.04# if env_file is not defined, it will load .env.# or you can load the specific file.# env_file:#   - ./a.env 
 

env_file內,每一行就是一個變數

# .env or a.env
RACK_ENV=development
SHOW=true
USER_INPUT
 

使用預設的.env還有一個好處,就是我們可以把docker-compose.yaml也變成受環境變數控制。

# docker-compose.yaml with variable control, only works in default .envservices:
  ubuntu:
    image: ubuntu:${ubuntu_version}
 
# .env
ubuntu_version=22.04
 

馬交野


4DX  28年後
英語版  馴龍記
4DX    馴龍記
4DX  英語版  馴龍記
榴心風暴
IMAX with Laser 罪人們
野黨
器子
劇場版 我與機器子
大風殺
那些年的我們
超異能特攻
英語版  史迪仔
私家偵探
IMAX with Laser 馴龍記 英語版
拼命三郎
殺神John Wick之芭蕾殺姬
不赦之罪
MX4D 職業特工隊:最終清算
年少心事 3rd MIQFF
史迪仔 英語版
殺神JOHN WICK外傳:芭蕾殺姬
罪人們
28 年後
獵狐行動
關於我和鬼變成家人的那封利是
職業特工隊:最終清算
馴龍記
28年後
史迪仔
死神來了:血脈
獵金•遊戲
4DX  28年後