介紹

Dockerfile是容器化中的關鍵元件,使開發人員和 DevOps 工程師能夠將應用程式及其所有依賴項打包到可移植的輕量級容器中。本指南將提供 Dockerfile 的全面演練,從基礎知識開始,逐步發展到進階技術。最後,您將具備編寫高效、安全且可用於生產的 Dockerfile 的技能。


目錄

  1. 什麼是 Dockerfile?

  2. 為什麼要學習 Dockerfile?

  3. Dockerfile 的基礎知識

  1. 中級 Dockerfile 概念
  1. 高級 Dockerfile 技術
  1. Dockerfile 的除錯和故障排除

  2. 編寫 Dockerfile 的最佳實踐

  3. 要避免的常見錯誤

  4. 結論


1. 什麼是 Dockerfile?

Dockerfile是一個純文字文件,其中包含一系列用於建立 Docker 映像的指令。 Dockerfile 中的每一行代表映像建置過程中的一個步驟。建立的映像是一個輕量級、可移植且自給自足的環境,包含執行應用程式所需的一切,包括程式庫、依賴項和應用程式程式碼本身。

Dockerfile 的關鍵組成部分:

  1. 基本影像:

Docker 映像的起點。例如,如果您正在建立 Python 應用程式,則可以從python:3.9作為基礎映像開始。

  1. 應用程式程式碼和相依性:

將程式碼新增至映像中,並安裝相依性以確保應用程式正確運作。

  1. 命令和配置:

執行命令、設定環境變數和公開連接埠的說明。

為什麼 Dockerfile 很重要?

一個 Dockerfile:

  • 標準化應用程式的建置和部署方式。

  • 確保不同環境(開發、測試、生產)之間的一致性。

  • 使應用程式可移植且更易於管理。


2. 為什麼要學習 Dockerfile?

Dockerfile 是容器化的基礎,也是 DevOps 工程師的關鍵技能。這就是為什麼學習它們至關重要:

1.跨環境的可移植性

  • 使用 Dockerfile,您可以建立一次映像並在任何地方執行它。它消除了“在我的機器上執行”的問題。

2.簡化的 CI/CD 管道

  • 在 Jenkins、GitHub Actions 或 Azure DevOps 等 CI/CD 管道中使用 Dockerfile 自動建置、測試和部署應用程式。

3.基礎設施的版本控制

  • 就像程式碼一樣,Dockerfile 可以進行版本控制。如有必要,可以追蹤和回滾基礎設施的變化。

4.加強協作

  • 團隊可以共享 Dockerfile,以確保每個人都在同一環境中工作。它簡化了新開發人員或貢獻者的入職流程。

5.資源效率

  • 與傳統虛擬機器相比,使用最佳化的 Dockerfile 建立的 Docker 映像是輕量級的,消耗的資源更少。

例子:

想像一個在 Node.js 上執行的 Web 應用程式。 Dockerfile 不需要開發人員在本地安裝 Node.js,而是可以使用所需的 Node.js 確切版本打包應用程式,從而確保所有環境中的一致性。


3. Dockerfile 的基礎知識

了解 Dockerfile 的基礎知識對於編寫有效且實用的 Dockerfile 至關重要。讓我們探討一下基本要素。


3.1 Dockerfile語法

Dockerfile 包含簡單的指令,其中每個指令執行特定的操作。語法一般是:

INSTRUCTION arguments

例如:

FROM ubuntu:20.04
COPY . /app
RUN apt-get update && apt-get install -y python3
CMD ["python3", "/app/app.py"]

要點:

  • FROMCOPYRUNCMD等指令區分大小寫並以大寫形式編寫。

  • 每個指令都會在 Docker 映像中建立一個新圖層


3.2常用指令

讓我們分解一些最常用的指令:

  1. FROM
  • 指定建置的基礎映像。

  • 例子:

     FROM python:3.9
  • Dockerfile 必須以FROM指令開頭,多階段建置除外。
  1. COPY
  • 將檔案或目錄從主機系統複製到容器中。

  • 例子:

     COPY requirements.txt /app/
  1. RUN
  • 在建置過程中執行命令。常用於安裝軟體包。

  • 例子:

     RUN apt-get update && apt-get install -y curl
  1. CMD
  • 指定容器啟動時執行的預設命令。

  • 例子:

     CMD ["python3", "app.py"]
  1. WORKDIR
  • 設定容器內的工作目錄。

  • 例子:

     WORKDIR /usr/src/app
  1. EXPOSE
  • 記錄容器偵聽的連接埠。

  • 例子:

     EXPOSE 8080

4.中級 Dockerfile 概念

一旦您了解了基礎知識,您就可以開始使用 Dockerfiles 的更高級功能來優化和增強您的建置。


4.1建置多階段 Dockerfile

多階段建置可讓您透過分離建置和執行時間環境來建立精實生產映像。

  • 第 1 階段(建構器):安裝依賴項、編譯程式碼並建置應用程式。

  • 第 2 階段(生產):僅複製建置階段所需的文件。

例子:

# Stage 1: Build the application
FROM node:16 AS builder
WORKDIR /app
COPY package.json .
RUN npm install
COPY . .
RUN npm run build

# Stage 2: Run the application
FROM nginx:alpine
COPY --from=builder /app/build /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

好處:

  • 較小的生產圖像。

  • 使建置工具遠離執行時間環境,從而提高安全性。


4.2使用環境變數

環境變數使 Dockerfile 更加靈活和可重複使用。

例子:

ENV APP_ENV=production
CMD ["node", "server.js", "--env", "$APP_ENV"]
  • 使用ENV定義變數。

  • 使用docker run -e在執行時覆蓋變數:

  docker run -e APP_ENV=development myapp

4.3加入健康檢查

HEALTHCHECK指令定義了檢查容器運作狀況的指令。

例子:

HEALTHCHECK --interval=30s --timeout=10s --retries=3 CMD curl -f http://localhost:8080/health || exit 1
  • 目的:確保容器內的應用程式能如預期運作。

  • 自動重啟:如果健康檢查失敗,Docker可以重新啟動容器。


5.高階 Dockerfile 技術

先進的技術可協助您建立最佳化、安全且可立即投入生產的映像。


5.1優化影像尺寸

  1. 使用較小的基礎鏡像
  • 將預設影像替換為最小影像,例如alpine
     FROM python:3.9-alpine
  1. 最小化層數
  • 組合命令以減少層數:
     RUN apt-get update && apt-get install -y curl && apt-get clean

5.2使用建構參數

建置參數 ( ARG ) 允許在建置期間動態配置映像。

例子:

ARG APP_VERSION=1.0
RUN echo "Building version $APP_VERSION"

在建置期間傳遞值:

docker build --build-arg APP_VERSION=2.0 .

5.3實施安全最佳實踐

  1. 避免 root 用戶:

建立和使用非 root 使用者以增強安全性。

   RUN adduser --disabled-password appuser
   USER appuser
  1. 使用可信任基礎鏡像:

堅持使用官方或經過驗證的圖像以降低漏洞風險。

   FROM nginx:stable
  1. 掃描影像以查找漏洞:

使用TrivySnyk等工具掃描影像:

   trivy image myimage

  1. Dockerfile 的除錯和故障排除

使用 Dockerfile 時,在映像建置或執行時遇到錯誤是很常見的。有效的除錯和故障排除技能可以節省時間並幫助快速找出問題。

除錯 Dockerfile 的步驟

  1. 增量建構影像
  • 使用--target標誌在多階段 Dockerfile 中建置特定階段。這使您可以隔離建置過程不同階段的問題。
     docker build --target builder -t debug-image .
  1. 檢查中間層
  • 使用docker history查看映像層並辨識不必要的命令或問題:
     docker history <image_id>
  1. 使用RUN進行除錯
  • 將除錯命令加入RUN指令。例如,新增echo語句可以幫助驗證檔案路徑或配置:
     RUN echo "File exists:" && ls /path/to/file
  1. 紀錄檔案
  • 容器內執行的服務的日誌檔案或輸出可以提供對執行時錯誤的洞察。使用docker logs
     docker logs <container_id>
  1. 檢查建構上下文
  • 確保不必要的文件不會發送到建置上下文,因為這可能會增加建置時間並導致意外問題。使用.dockerignore檔案來過濾檔案。

常見錯誤和修復

  1. 錯誤:找不到文件
  • 原因:使用COPYADD複製的檔案在指定路徑中不存在。

  • 修復:驗證檔案路徑並使用WORKDIR設定正確的目錄。

  1. 錯誤:未安裝依賴項
  • 原因:缺少依賴項或安裝指令不正確。

  • 修復:在安裝軟體之前使用RUN apt-get update update )。

  1. 權限錯誤
  • 原因:以錯誤的使用者身分執行進程或存取檔案。

  • 修復:使用USER指令切換到非root用戶。


7.編寫 Dockerfile 的最佳實踐

若要建立乾淨、有效率且安全的 Dockerfile,請遵循以下業界認可的最佳實務:

1.固定影像版本

  • 避免對基礎映像使用latest標籤,因為它們可能會在發布新版本時引入不一致。
     FROM python:3.9-alpine

2.優化圖層

  • 組合命令以減少層數。每個RUN指令都會建立一個新圖層,因此最小化它們有助於最佳化圖片大小。
     RUN apt-get update && apt-get install -y curl && apt-get clean

3.使用.dockerignore文件

  • 透過建立.dockerignore文件,防止不必要的文件(例如.git 、日誌或大型資料集)包含在建置上下文中:
     node_modules
     *.log
     .git

4.保持影像輕量

  • 使用最小的基礎映像(例如alpine或特定於語言的精簡版本)來減少映像大小。
     FROM node:16-alpine

5.新增元資料

  • 使用LABEL指令加入有關圖像的元資料,例如版本、作者和描述:
     LABEL maintainer="[email protected]"
     LABEL version="1.0"

6.使用非root用戶

  • 以 root 身分執行容器存在安全風險。建立並切換到非root使用者:
     RUN adduser --disabled-password appuser
     USER appuser

7.清理臨時文件

  • 安裝後刪除臨時檔案以減小映像大小:
     RUN apt-get install -y curl && rm -rf /var/lib/apt/lists/*

8.要避免的常見錯誤

如果編寫不正確,Dockerfile 很快就會變得低效且不安全。以下是一些常見錯誤以及如何避免這些錯誤:

1.使用大型基礎鏡像

  • 問題:從大型基礎映像開始會增加建置時間和磁碟使用量。

  • 解決方案:使用輕量基礎映像,例如alpine或語言映像的精簡版本。

     FROM python:3.9-alpine

2.未能使用多階段建置

  • 問題:在最終映像中包含建置工具會不必要地增加大小。

  • 解決方案:使用多階段建置僅將所需的檔案複製到生產映像中。

     FROM golang:1.16 AS builder
     WORKDIR /app
     COPY . .
     RUN go build -o app

     FROM alpine:latest
     COPY --from=builder /app/app /app
     CMD ["/app"]

3.硬編碼的秘密

  • 問題:在 Dockerfile 中儲存敏感資料(例如 API 金鑰或密碼)存在安全風險。

  • 解決方案:使用環境變數或秘密管理工具:

     ENV DB_PASSWORD=${DB_PASSWORD}

4.安裝後不清理

  • 問題:保留快取檔案或安裝包會使映像膨脹。

  • 解決方案:在相同RUN指令中清理安裝殘留:

     RUN apt-get install -y curl && rm -rf /var/lib/apt/lists/*

5.不記錄 Dockerfile

  • 問題:缺乏註解使得其他人很難理解特定命令的用途。

  • 解決方案:加入有意義的註解來解釋指令:

     # Set working directory
     WORKDIR /usr/src/app

9.結論

Dockerfile 是建置高效能、安全容器的基石。透過掌握 Dockerfile 語法、了解最佳實務並避免常見陷阱,您可以簡化應用程式容器化流程,以實現跨環境的一致部署。

要點:

  • 最小的基礎鏡像開始,以減小尺寸並提高性能。

  • 利用多階段建構生產級映像。

  • 始終測試和除錯您的 Dockerfile 以確保可靠性。

  • 實施安全最佳實踐,例如非 root 使用者和秘密管理。

  • 使用.dockerignore排除不必要的文件,優化建置上下文。

行動專案:

  1. 嘗試為您的專案編寫基本和多階段 Dockerfile。

  2. 應用最佳實務並將除錯技術整合到您的工作流程中。

  3. 與您的團隊分享您的 Dockerfile 以促進協作和回饋。

透過遵循這份全面的指南,您不僅可以建立強大的 Dockerfile,還可以增強您作為 DevOps 專業人員的技能,為高效的 CI/CD 工作流程和可擴展系統做出貢獻。


👤作者

橫幅

加入我們的Telegram 社群||在 GitHub 上關注我以獲取更多 DevOps 內容!


原文出處:https://dev.to/prodevopsguytech/writing-a-dockerfile-beginners-to-advanced-31ie


共有 0 則留言