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"
解析:
- 多階段構建:使用了兩個FROM指令,分別定義了構建階段和運行階段的基礎映像。
- 輕量級基礎映像:選用了
python:3.8-slim
和python:3.8-alpine
,這些映像較小,有利於減少最終映像的大小。 - 依賴安裝:在構建階段使用
pip install
安裝依賴,並將安裝後的依賴從構建階段複製到運行階段。 - 環境變數設置:通過設置
PATH
環境變數,確保運行階段容器能夠找到Python依賴包。 - 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
- (指令未完成,需要進一步信息以補充說明)