Dockerfile 基本操作(Docker)

選擇鏡像

基本原則:

  • 優先使用官方鏡像,無官方鏡像再選擇可信的開源鏡像。
  • 指定固定版本的 tag,避免使用 latest,確保穩定性。
  • 優先選擇體積小的鏡像(如 Alpine、Debian slim 版本),有助於縮小鏡像大小、提高安全性。

常用指令

指令 功用
FROM 指定建立映像檔所使用的基礎鏡像。
ENV 設定環境變數,可在 Dockerfile 多處使用。
RUN 映像構建階段執行的指令,每一個 RUN 都會建立一層(Layer)。
CMD 容器啟動時預設要執行的命令,只能有一個,若定義多個以最後一個為準。
EXPOSE 宣告容器對外開放的 Port(實際是否對外還需 docker run 時設定)。
VOLUME 宣告可掛載的資料卷路徑。
COPY 將本機檔案複製到映像中(不具備解壓縮功能)。
ADD 功能類似 COPY,但可自動解壓 .tar 檔案、支援 URL。
ENTRYPOINT 設定容器啟動時要執行的主程序,無法被覆蓋。
WORKDIR 設定工作目錄,不存在會自動建立。
HEALTHCHECK 設定容器的健康檢查機制。
ARG 定義建構映像時可傳入的變數,不會保留於映像中。

Dockerfile 建立說明與注意事項

RUN 指令最佳實務

  • 每個 RUN 指令都會建立新的 Layer,建議使用 && 將多條指令串接,減少層數,優化映像大小。

COPY 與 ADD 差異

  • COPY 用於單純複製。
  • ADD 可自動解壓 .tar.gz 類型檔案,也支援 URL,但功能過多可能造成預期外行為,建議預設使用 COPY

WORKDIR

  • 等同於執行 cd,自動建立目錄。

ENV vs ARG

  • ARG:只作用於建構階段,可用於傳入版本號等參數,不會保留在最終映像中。
  • ENV:定義環境變數,會被寫入映像,可供容器內程式使用。

CMD 與 ENTRYPOINT 差異

比較項目 CMD ENTRYPOINT
覆蓋性 可被 docker run 指令行覆蓋 預設不可覆蓋(除非加 --entrypoint
可搭配使用 可搭配 ENTRYPOINT 作為參數傳入 可搭配 CMD 接收參數
使用情境 預設執行指令 強制執行的主程序(如設定容器主行程)

Shell vs Exec 格式

  • Shell 格式:以 /bin/sh -c 方式執行
CMD echo "hello docker"
ENTRYPOINT echo "hello docker"
  • Exec 格式:直接執行指令(陣列語法),推薦使用
CMD ["echo", "hello docker"]
ENTRYPOINT ["echo", "hello docker"]

範例一:基本 Apache 映像建立

# 建立 Dockerfile
FROM rockylinux:8.7

ENV APP_NAME="myweb version 1"

# 清除預設 repo
RUN rm -rf /etc/yum.repos.d/*

# 複製自定義 yum repo
COPY Rocky-AppStream.repo /etc/yum.repos.d/
COPY Rocky-BaseOS.repo /etc/yum.repos.d/

# 安裝 Apache
RUN dnf install -y httpd && dnf clean all

# 健康檢查:每 30 秒檢查一次網站服務是否正常
HEALTHCHECK --interval=30s --timeout=3s \
  CMD curl -f http://localhost:80/ || exit 1

# 預設啟動 httpd 前景執行
CMD ["/usr/sbin/httpd", "-DFOREGROUND"]

EXPOSE 80

範例二:使用 ENV 指定版本參數

FROM ubuntu:20.04

ENV VERSION=2.0.1

RUN apt-get update && \
    apt-get install -y wget && \
    wget https://github.com/ipinfo/cli/releases/download/ipinfo-${VERSION}/ipinfo_${VERSION}_linux_amd64.tar.gz && \
    tar zxf ipinfo_${VERSION}_linux_amd64.tar.gz && \
    mv ipinfo_${VERSION}_linux_amd64 /usr/bin/ipinfo && \
    rm -rf ipinfo_${VERSION}_linux_amd64.tar.gz

範例三:使用 ARG 傳入版本參數

FROM ubuntu:20.04

ARG VERSION=2.0.1

RUN apt-get update && \
    apt-get install -y wget && \
    wget https://github.com/ipinfo/cli/releases/download/ipinfo-${VERSION}/ipinfo_${VERSION}_linux_amd64.tar.gz && \
    tar zxf ipinfo_${VERSION}_linux_amd64.tar.gz && \
    mv ipinfo_${VERSION}_linux_amd64 /usr/bin/ipinfo && \
    rm -rf ipinfo_${VERSION}_linux_amd64.tar.gz