隨著近幾年 Container 時代的來臨,撰寫 Dockerfile 相信大家都不陌生,但有時候還是難免會忘記一些規則,所以在這邊記錄一下,最主要提醒自己,也能分享給看到這此文章的朋友
ARG 和 ENV
依實際使用經驗,大致上有幾個重點說明
- ARG 是在 docker build 階段時使用,而 ENV 是在 docker run 階段時使用
- ARG 因為只在 build 階段生效,而 Dockerfile 支援
multi-stage builds
,所以遇到 FROM 時,若要讓 ARG 繼續有效時,記得再宣告一次 ARG - ARG 宣告後,在 build 階段時若有執行 shell script 時,一樣可以當成環境變數來使用
- ARG 可以搭配 ENV,在 build 階段就先決定 docker run 時的環境變數,可做為環境變數的預設值
- ENV 有單一環境變數指定和多個環境變數指定兩種寫法
第 2 點範例
ARG TAG=3.8
FROM public.ecr.aws/lambda/python:$TAG
# Have to declare ARG argument again
ARG TAG
RUN echo ${TAG} > tag_image_version.txt
依此範例,ARG 若沒再宣告一次時,會找不到此參數
第 3 點範例
ARG TAG=3.8
FROM public.ecr.aws/lambda/python:$TAG
# Have to declare ARG argument again
ARG TAG
RUN chmod 755 test.sh && \
./test.sh
test.sh 如下
#!/usr/bin/env bash
echo ${TAG} > tag_image_version.txt
在 shell script 中可以直接使用 ARG 所指定的變數
第 4 點範例
ARG TAG=3.8
FROM public.ecr.aws/lambda/python:$TAG
# Have to declare ARG argument again
ARG TAG
ENV TAG ${TAG}
這樣一來,在 docker run 階段時的應用程式就可以用環境變數存取
例如 Python
os.environ.get('TAG')
例如 TypeScript or Node
process.env.TAG
第 5 點範例
FROM public.ecr.aws/lambda/python:$TAG
# 單一環境變數指定
ENV FOO1 Hello
# 多個環境變數指定
# ENV FOO2=${FOO1} FOO3=Hi
COPY
遞迴 COPY
COPY . .
最常用的方式,依 docker build 時,所指定的 context 為基準點,不管資料夾有多少子層,都完整的 COPY 過去 docker container 中
COPY ./dir ./dir
同第 1 點,不同的地方,會在 docker container 中,依 WORKDIR 的路徑,會新建一個 dir 資料,dir 下的所有子層,也都會完整 COPY
非遞回 COPY
COPY ./dir/* ./dir
在 docker container 中,依 WORKDIR 的路徑,會新建一個 dir 資料,但只會 COPY dir 下第一層的所有的檔案,但不會包括子層資料夾的檔案
Context
來看一個 docker build 指令
docker build -t test-lambda:latest \
-f ../../Dockerfile-lambda ../../
一般 docker build 時,最後我們只會指定一個 "." 來代表把當下的路徑指定成 context ,但如果依此範例,則會依 上上層 的資料夾來當 context,會直接影響 Dockerfile 中的 COPY、ADD 所依的路徑基準點
先寫到這邊,之後有覺得需要記錄的,再持續更新
歡迎留言