在操作啟動一個 spring 的為服務,我們還沒介紹撰寫一個dockerfile 時我們會經常使用下述的指令。容我一一介紹~
指定基礎映像檔,所有後續指令都基於此映像檔進行。
語法:
FROM <image>[:tag] [AS <alias>]
範例:
FROM node:14-alpine
在映像檔構建過程中執行命令,通常用於安裝軟體包或執行指令。
語法:
RUN <command>
RUN ["executable", "param1", "param2"]
範例:
RUN apt-get update && apt-get install -y python3
指定容器啟動時預設執行的命令或參數。可被 docker run 命令行參數覆蓋。
語法:
CMD ["executable","param1","param2"]
CMD command param1 param2
範例:
CMD ["npm", "start"]
4. ENTRYPOINT
用途:
設定容器啟動時執行的主命令,通常與 CMD 搭配使用,以提供預設參數。
語法:
ENTRYPOINT ["executable", "param1", "param2"]
ENTRYPOINT command param1 param2
範例:
ENTRYPOINT ["python3", "app.py"]
將檔案或目錄從構建上下文(通常是 Dockerfile 所在目錄)複製到映像檔內。
語法:
COPY [--chown=<user>:<group>] <src>... <dest>
範例:
COPY package.json /app/package.json
與 COPY 類似,但還可以從 URL 複製檔案,並自動解壓縮壓縮檔案。
語法:
ADD [--chown=<user>:<group>] <src>... <dest>
範例:
ADD https://example.com/app.tar.gz /app/
設定環境變數,這些變數可在構建和運行容器時使用。
語法:
ENV <key>=<value> ...
範例:
ENV NODE_ENV=production
宣告容器要開放的埠,供連接使用(僅作為資訊,實際埠映射需在 docker run 時指定)。
語法:
EXPOSE <port>[/<protocol>]
範例:
EXPOSE 80
設定工作目錄,後續的指令(如 RUN、CMD、ENTRYPOINT)都將在此目錄下執行。
語法:
WORKDIR /path/to/workdir
範例:
WORKDIR /app
指定執行後續指令或運行容器時的使用者。
語法:
USER <user>[:<group>]
範例:
USER node
11. ARG
用途:
定義構建參數,這些參數可以在構建映像檔時傳入,僅在構建階段可用。
語法:
ARG <name>[=<default value>]
範例:
ARG VERSION=1.0.0
12. VOLUME
用途:
建立資料卷掛載點,以便在容器外部保存資料。
語法:
VOLUME ["/data"]
範例:
VOLUME ["/app/data"]
為映像檔添加中繼資料(Metadata),如作者、版本等。
語法:
LABEL <key>=<value> ...
範例:
LABEL maintainer="yourname@example.com"
LABEL version="1.0"
指定執行 RUN 指令時所使用的 shell。
語法:
SHELL ["executable", "parameters"]
範例:
SHELL ["powershell", "-Command"]
定義容器的健康檢查指令,以監控應用程式的狀態。
語法:
HEALTHCHECK [options] CMD <command>
HEALTHCHECK NONE
範例:
HEALTHCHECK --interval=30s --timeout=10s \
CMD curl -f http://localhost/ || exit 1
定義當此映像檔被作為基礎映像檔時,應該自動執行的指令。
語法:
ONBUILD <Dockerfile instruction>
範例:
ONBUILD COPY . /app/src
指定停止容器時要傳送的系統呼叫信號,控制容器關閉的方式。
語法:
STOPSIGNAL <signal>
範例:
STOPSIGNAL SIGTERM
指定映像檔的維護者資訊,已被 LABEL 取代。
語法:
MAINTAINER <name>
範例:
MAINTAINER Your Name <yourname@example.com>
注意:
建議使用 LABEL 指令來替代。
19. ADD 與 COPY 的差異
COPY:僅支持從構建上下文中複製本地檔案或目錄。
ADD:除了 COPY 的功能外,還支持從 URL 複製檔案,並自動解壓縮壓縮檔案。
建議:
如果不需要 ADD 的額外功能,優先使用 COPY,以保持 Dockerfile 的簡潔和可預測性。
20. CMD 與 ENTRYPOINT 的差異
CMD:提供容器啟動時的預設命令或參數,可被 docker run 的參數覆蓋。
ENTRYPOINT:設定容器啟動時執行的固定命令,docker run 的參數將作為其參數傳入。
範例:
ENTRYPOINT ["nginx"]
CMD ["-g", "daemon off;"]
在此範例中,ENTRYPOINT 固定為 nginx,而 CMD 提供預設參數。
21. 多階段構建
用途:
使用多個 FROM 指令,在單一 Dockerfile 中構建多個階段,減少最終映像檔的大小,並提高構建效率。
語法:
dockerfile
複製程式碼
FROM <image> AS <stage_name>
# 構建階段指令
...
FROM <image>
# 使用前一階段的構建結果
COPY --from=<stage_name> /path /path
範例:
dockerfile
複製程式碼
# 建構階段
FROM node:14-alpine AS build
WORKDIR /app
COPY package.json .
RUN npm install
COPY . .
RUN npm run build
# 執行階段
FROM nginx:alpine
COPY --from=build /app/build /usr/share/nginx/html
在需要破壞 Docker 構建快取時,通常會在 ARG 中加入隨機值或時間戳。
範例:
ARG CACHEBUST=1
RUN curl -s http://example.com/file.txt -o /file.txt
每次改變 CACHEBUST 的值,都會強制重新執行後續的指令。
小結
透過熟悉並善用這些 Dockerfile 指令,您可以:
構建高效、可重複使用的映像檔: 使用多階段構建和最佳實踐,減少映像檔大小。
提高構建速度: 利用 Docker 的構建快取機制,避免重複工作。
增強映像檔的可維護性: 使用 LABEL 添加中繼資料,明確指令的用途和行為。
最佳實踐建議:
最小化映像檔大小: 使用輕量級的基礎映像檔(如 alpine 版)。
合併指令: 在單個 RUN 指令中執行多個命令,減少層數。
使用 .dockerignore: 排除不必要的檔案,避免增加映像檔大小。
明確指定版本號: 避免使用 latest 標籤,以確保構建的一致性。
定期更新基礎映像檔: 確保安全性和最新功能。
透過這些指令和建議,您可以有效地利用 Docker 來構建、部署和管理您的應用程式。