Buy Me a Coffee

Dockerfile 進階技巧與完整範例解析

Dockerfile 進階技巧與完整範例解析

深入介紹一些進階技巧,並提供一個完整的Dockerfile範例,幫助讀者更好地理解如何在實際項目中運用Dockerfile。

多階段構建

多階段構建是Dockerfile的一個強大特性,允許在單一Dockerfile中使用多個FROM指令,每個FROM指令都可以使用不同的基礎映像。這樣做的好處是可以將構建環境與運行環境分離,從而減小最終映像的大小,並保持構建過程的清晰和高效。

Dockerfile 完整範例解析

以下是一個使用多階段構建來創建一個簡單Python應用的Dockerfile範例。這個範例展示了如何將應用的構建過程和運行環境分開,最終產生一個輕量級的映像。

# 第一階段:構建環境
FROM python:3.9-slim AS builder
WORKDIR /app
COPY requirements.txt .
RUN pip install --user -r requirements.txt

# 複製應用代碼(僅複製所需文件)
COPY src/ .
COPY setup.py .

# 使用ARG傳入版本號,預設為latest
ARG VERSION=latest
RUN python setup.py bdist_wheel

# 第二階段:運行環境
FROM python:3.9-slim
LABEL maintainer="example@example.com" \
      version="${VERSION}" \
      description="A complex Python application example with multi-stage build"
      
# 安裝運行時依賴
COPY --from=builder /app/dist/*.whl /app/
RUN pip install /app/*.whl && rm -rf /app

WORKDIR /data
VOLUME /data

# 設置環境變數
ENV APP_ENV=production

# 設定預設Shell
SHELL ["/bin/bash", "-c"]

# 設定啟動命令
ENTRYPOINT ["python", "-m", "myapp"]
CMD ["--help"]

# 當基於此映像建立新映像時,執行額外的命令
ONBUILD RUN echo "Built on top of the complex Python application example"

解析:

  1. 多階段構建:使用了兩個FROM指令,分別定義了構建階段和運行階段的基礎映像。
  2. 輕量級基礎映像:選用了python:3.8-slimpython:3.8-alpine,這些映像較小,有利於減少最終映像的大小。
  3. 依賴安裝:在構建階段使用pip install安裝依賴,並將安裝後的依賴從構建階段複製到運行階段。
  4. 環境變數設置:通過設置PATH環境變數,確保運行階段容器能夠找到Python依賴包。
  5. CMD指令:定義了容器啟動時執行的默認命令。

Dockerfile 關鍵字

1. FROM

  • 指定基礎鏡像
  • 格式
    • FROM <image>
    • FROM <image>:<tag>
    • FROM <registry>/<image>:<tag>
  • 範例
    • FROM ubuntu:18.04
    • FROM demoyuw/nginx:v0.2
    • FROM 10.30.1.1/images/python:3.8-alpine3.11

2. ENV

  • 設定容器環境變數
  • 格式
    • ENV <key>=<value>
  • 範例
    • ENV LANG=en_US.UTF-8
    • ENV DEBUG=true

3. WORKDIR

  • 建立資料夾,並設定預設資料夾
  • 格式
    • WORKDIR <path>
  • 範例
    • WORKDIR /app
    • WORKDIR /data

4. RUN

  • 執行命令
  • 格式
    • RUN <command>
    • RUN ["command", "args"]
  • 範例
    • RUN apt-get install python3
    • RUN ["/bin/bash", "-c", "echo hello world >> hello.txt"]

5. ADD

  • 將檔案從本地端搬到容器上
  • 格式
    • ADD <src> <dest>
  • 範例
    • ADD cirros-0.3.4-x86_64-disk.img /
    • ADD . /app

6. COPY

  • 將檔案從本地端搬到容器上
  • 格式
    • COPY <src> <dest>
  • 範例
    • COPY cirros-0.3.4-x86_64-disk.img /
    • COPY . /app

7. EXPOSE

  • 公開容器的通訊埠
  • 格式
    • EXPOSE <port> [<protocol>...]
  • 範例
    • EXPOSE 80/TCP
    • EXPOSE 8000/UDP

8. VOLUME

  • 建立持久化儲存空間
  • 格式
    • VOLUME [<path>...]
  • 範例
    • VOLUME /data
    • VOLUME /data /logs

9. ENTRYPOINT

  • 設定容器啟動時執行的命令
  • 格式
    • ENTRYPOINT ["command", "args"]
  • 範例
    • ENTRYPOINT ["/bin/bash"]
    • ENTRYPOINT ["sh", "execute.sh"]

10. CMD

  • 設定容器啟動時執行的參數
  • 格式
    • CMD <command>
    • CMD ["command", "args"]
  • 範例
    • CMD echo "Hello world"
    • CMD ["python", "app.py"]

11. HEALTHCHECK

  • 設定容器健康檢查
  • 格式
    • HEALTHCHECK <command>
  • 範例
    • HEALTHCHECK CMD curl -f http://localhost:80/health

12. ONBUILD

  • 基礎鏡像建置時執行的命令
  • 格式
    • ONBUILD <command>
  • 範例
    • ONBUILD RUN apt-get update

13. ARG

  • 建置時傳遞參數
  • 格式
    • ARG <name>
  • 範例
    • ARG VERSION=1.0
    • RUN apt-get install python3-$VERSION

14. LABEL

  • 設定容器的標籤
  • 格式
    • LABEL <key>=<value>
  • 範例
    • LABEL author="John Doe"
    • LABEL description="This is a simple web application"

15. SHELL

  • 設定容器的

預設Shell

  • 格式
    • SHELL <shell>
  • 範例
    • SHELL /bin/bash
    • SHELL /bin/zsh

16. STOP

  • (指令未完成,需要進一步信息以補充說明)