在微服務和雲端運算的時代,Docker 已經成為應用程式開發和部署中不可或缺的工具。容器化允許開發人員將應用程式及其依賴項打包成一個可攜式單位,確保可預測性、可擴展性和快速部署。然而,容器的效率在很大程度上取決於您的 Dockerfile 是如何優化編寫的。
在本文中,我們將探討創建 Dockerfile 的最佳實踐,幫助您構建輕量級、快速且安全的容器。
Dockerfile 是一個文本文件,包含一組指令以組裝 Docker 映像。每條指令執行特定的操作,例如安裝套件、複製文件或定義啟動命令。正確使用 Dockerfile 指令對於構建高效的容器至關重要。
基本映像是您 Docker 映像的基礎。選擇輕量級的基本映像可以大幅減少最終映像的大小並最小化攻擊面。
Alpine Linux:一個流行的最小映像,約為 5 MB 大小。
FROM alpine:latest
優點:小型、安全、下載快速。
缺點:可能需要額外配置;某些套件可能缺失或因使用 musl 而行為不同於 glibc。
Scratch:一個空映像,適合可以編譯靜態二進位檔的語言(如 Go、Rust)。
FROM scratch
COPY myapp /myapp
CMD ["/myapp"]
每條 RUN
、COPY
和 ADD
指令都會為您的映像添加一個新層。合併命令有助於減少層數和整體映像大小。
低效:
RUN apt-get update
RUN apt-get install -y python
RUN apt-get install -y pip
高效:
RUN apt-get update && apt-get install -y \
python \
pip \
&& rm -rf /var/lib/apt/lists/*
Docker 使用層緩存來加速構建。指令的順序會影響緩存的效率。
首先複製依賴文件:在複製其餘源代碼之前,先複製變更頻率較低的文件(如 package.json
或 requirements.txt
)。
COPY package.json .
RUN npm install
COPY . .
最小化早期層中的變更:早期層的變更會使所有後續層的緩存失效。
安裝套件後移除臨時文件和緩存以減少映像大小。
RUN pip install --no-cache-dir -r requirements.txt
永遠不要在 Dockerfile 中包含敏感數據(密碼、API 金鑰)。
刪除不必要的文件:安裝後清理緩存、日誌和臨時文件。
RUN apt-get clean && rm -rf /var/lib/apt/lists/*
最小化安裝的套件:僅安裝您需要的套件。
RUN apt-get install -y --no-install-recommends package
使用優化工具:如 Docker Slim 的工具可以自動優化您的映像。
.dockerignore
文件讓您能排除構建上下文中的文件和目錄,減少發送到 Docker 守護進程的數據量並保護敏感信息。
示範 .dockerignore:
.git
node_modules
Dockerfile
.dockerignore
多階段構建允許您使用中間映像並僅將必要的工件複製到最終映像中。
Go 應用程序的示例:
# 構建階段
FROM golang:1.16-alpine AS builder
WORKDIR /app
COPY . .
RUN go build -o myapp
# 最終映像
FROM alpine:latest
WORKDIR /app
COPY --from=builder /app/myapp .
CMD ["./myapp"]
為了增強安全性,避免以根用戶身份運行應用程式。
RUN adduser -D appuser
USER appuser
# 使用基於 Alpine Linux 的官方 Node.js 映像
FROM node:14-alpine
# 設置工作目錄
WORKDIR /app
# 複製套件文件並安裝依賴
COPY package*.json ./
RUN npm ci --only=production
# 複製其餘的應用程式代碼
COPY . .
# 創建非根用戶並切換到該用戶
RUN addgroup appgroup && adduser -S appuser -G appgroup
USER appuser
# 開放應用程式端口
EXPOSE 3000
# 定義運行應用的命令
CMD ["node", "app.js"]
固定版本:使用基礎映像和套件的特定版本以確保構建可重現性。
FROM node:14.17.0-alpine
保持更新:定期更新依賴項和基本映像,以包括安全補丁。
使用元數據:添加 LABEL
指令來提供映像元數據。
LABEL maintainer="[email protected]"
設置適當的權限:確保文件和目錄擁有適當的權限。
避免以 Root 身份使用:始終切換到非根用戶來運行應用程式。
創建高效的 Docker 映像既是一門藝術,也是一門科學。通過遵循編寫 Dockerfile 的最佳實踐,您可以顯著改善容器的性能、安全性和可管理性。持續更新您的知識,並隨時了解容器化生態系統中的新工具和方法。記住,優化是一個持續過程,總有改進的空間。
原文出處:https://dev.to/idsulik/dockerfile-best-practices-how-to-create-efficient-containers-4p8o