Dockerfile 撰寫時注意事項

POSTED BY   Chris
2021 年 6 月 13 日
Dockerfile 撰寫時注意事項

隨著近幾年 Container 時代的來臨,撰寫 Dockerfile 相信大家都不陌生,但有時候還是難免會忘記一些規則,所以在這邊記錄一下,最主要提醒自己,也能分享給看到這此文章的朋友

 

ARG 和 ENV

依實際使用經驗,大致上有幾個重點說明

  1. ARG 是在 docker build 階段時使用,而 ENV 是在 docker run 階段時使用
  2. ARG 因為只在 build 階段生效,而 Dockerfile 支援 multi-stage builds,所以遇到 FROM 時,若要讓 ARG 繼續有效時,記得再宣告一次 ARG
  3. ARG 宣告後,在 build 階段時若有執行 shell script 時,一樣可以當成環境變數來使用
  4. ARG 可以搭配 ENV,在 build 階段就先決定 docker run 時的環境變數,可做為環境變數的預設值
  5. ENV 有單一環境變數指定和多個環境變數指定兩種寫法

第 2 點範例

Dockerfile
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 點範例

Dockerfile
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 如下

Dockerfile
#!/usr/bin/env bash

echo ${TAG} > tag_image_version.txt

在 shell script 中可以直接使用 ARG 所指定的變數

 

第 4 點範例

Dockerfile
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 點範例

Dockerfile
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 所依的路徑基準點

 

先寫到這邊,之後有覺得需要記錄的,再持續更新

歡迎留言
0

您可能也想看

Workaround for AWS Grafana alerting
2023 年 8 月 3 日
AWS, DevOps
CDK Pipelines – 專為 CDK 打造的 CI/CD 利器
2021 年 11 月 7 日
AWS, CDK, DevOps, CI/CD
gitpod vs codespace 開發環境上雲大比拼
2021 年 9 月 23 日
DevOps