站長阿川

站長阿川私房教材:
學 JavaScript 前端,帶作品集去面試!

站長精心設計,帶你實作 63 個小專案,得到作品集!

立即開始免費試讀!

概述

這可能是一個突然的問題,但是您是否隨意編寫了 Dockerfile?

只需一點點聰明才智,您就可以使您的程式碼更輕巧、更易讀,因此這裡有一些技巧可以幫助您。

本文是手寫。

技巧 1:使用多階段建置

Docker 的多階段建置可讓您將最終映像拆分為用於建置和執行的映像,從而使最終映像緊湊。

讓我們以實際建立go容器為例,看看它能帶來什麼好處。

初學者的 Dockerfile

FROM golang:1.25
WORKDIR /app
COPY . .
RUN go build -o myapp .
CMD ["./myapp"]

專業的 Dockerfile

# Stage 1: Build
FROM golang:1.25 AS builder
WORKDIR /app
COPY . .
RUN go build -o myapp .

# Stage 2: Run
FROM alpine:3.22.1
WORKDIR /app
COPY --from=builder /app/myapp .
CMD ["./myapp"]

讓我們實際建立上面的兩個文件,看看它們的大小差異有多大。首先,使用main.gogo.mod建立一個 Go 應用程式。

主機程式

package main

import "fmt"

func main() {
    fmt.Println("Hello, Docker!")
}

go.mod

module myapp

go 1.21

建構每個

docker build -f Dockerfile.junior -t myapp-junior .
docker build -f Dockerfile.senior -t myapp-senior .

實際建構並進行比較後,差異竟高達80倍。這是在小型配置下完成的,所以差異大概就是這樣,但如果大量使用的話,差異似乎會更大。

isoda@shota-mac junior % docker images | grep myapp
myapp-junior                   latest    f1c396cf8580   41 seconds ago       888MB
myapp-senior                   latest    eab45bab740d   About a minute ago   10.8MB

提示 2:始終修復基礎鏡像的版本

如果您忽略了這一點,今天可以執行的建置明天可能就無法執行了。

NG

FROM golang:latest

即使今天使用上述方法建立成功,但如果明天更新最新版本會怎麼樣?

建置可能會突然失敗。

好的一個例子

FROM golang:1.25-alpine

要點如下:

  • 明確指定特定的 LTS 版本

  • 盡可能使用輕量級影像(例如 alpine 或 bullseye-slim)

指定版本有助於防止意外問題,也有助於減少鏡像大小。鏡像大小可以減少約四倍。

isoda@shota-mac junior % docker image ls | grep golang
golang                         latest        d7e6adee7899   7 days ago       855MB
golang                         1.25-alpine   6ea50bc9f564   7 days ago       211MB

技巧3:盡可能減少層數

接下來的一點是盡可能減少層數。這樣做有以下好處:

  • 影像尺寸縮小(不留下不必要的文件)

  • 提高快取效率(減少重建時間)

  • 更快的分發和部署(更少的層意味著更快的推送/拉取)

NG

FROM debian:bullseye
RUN apt-get -y update
RUN apt-get install -y python

好的一個例子

FROM debian:bullseye
RUN apt-get -y update && apt-get install -y python && rm -rf /var/lib/apt/lists/*

在這個例子中,我們沒有看到映像大小有任何減少,但對於較大的 Dockerfile 來說,差異將是顯著的。

isoda@shota-mac junior % docker images | grep myapp               
myapp-junior                   latest        c30825b58d07   19 seconds ago   216MB
myapp-senior                   latest        818501d91809   34 seconds ago   198MB

提示 4:使用.dockerignore

這允許您以類似於.gitignore的方式指定不應包含在圖像中的檔案。

例如,如果您有以下 Dockerfile:

COPY . /app

如果您的目錄包含以下不必要的檔案該怎麼辦?

您可以透過在.dockerignore中列出這些不必要的檔案來節省空間。

venv/
.git/
logs
node_modules
...etc

編寫.dockerignore很簡單。只需在專案根目錄中建立一個名為.dockerignore的文件,並列出不需要的文件。

node_modules 
.git 
*.log
Dockerfile
...etc

*如果您在建置時指定如下所示的選項,您可以檢查實際發送的文件,因此請嘗試一下。

docker build . --no-cache --progress=plain

第 5 部分:建置具有安全意識的 Dockerfile

以下是四個需要牢記的 Docker 安全最佳實踐:

  • 使用可靠且正確的基礎鏡像來減輕重量

  • 使用多階段建置

  • 影像定期重建

  • 檢查鏡像漏洞

我們將詳細解釋每一個。

使用可靠且正確的基礎鏡像來減輕重量

首先,使用可信賴的基礎影像非常重要。

Docker Hub 上有大量可用的映像,但建議使用Official ImageVerified Publisher

Docker 官方映像有以下標記:

此外,盡可能嘗試使用最小的影像( alpineslim )來減少攻擊面和漏洞。

使用多階段建置

如上所述,透過利用多階段建置,您可以確保最終圖像中不包含不必要的工具和檔案。

這有助於避免不必要工具中的漏洞並減少攻擊面。

影像定期重建

例如,如果您繼續使用幾年前建立的映像並且不重建它,即使發現並解決了該映像中使用的軟體中的漏洞,您仍將繼續使用未解決該漏洞的映像。

因此,請定期重建影像,如下所示:

docker build --no-cache -t myImage:myTag myPath/

* 使用--no-cache將阻止使用快取。 (使用此選項可確保已安裝新檔案。)

檢查鏡像漏洞

定期掃描漏洞並在發現任何漏洞時更新/重建影像也很重要。

最簡單的診斷工具是docker scout ,這是一個官方工具,目前可以免費掃描本地映像。

docker scout cves <image-name>

我實際執行了我建立的圖像並檢查了輸出。 (省略了一些部分)

    ✓ Image stored for indexing
    ✓ Indexed 356 packages
    ✓ Provenance obtained from attestation
    ✗ Detected 29 vulnerable packages with a total of 106 vulnerabilities

## Overview

                    │               Analyzed Image                
────────────────────┼─────────────────────────────────────────────
  Target            │  <image-name>:latest                       
    digest          │  XXXXXXXXXXXXX                               
    platform        │ linux/arm64                                 
    provenance      │ [email protected]:XXXXXXXXXXXXX/XXXXXXXXXXXXX.git      
                    │  XXXXXXXXXXXXXXXXXXXXXXXXXXX   
    vulnerabilities │    0C     1H     3M   102L                  
    size            │ 249 MB                                      
    packages        │ 356                                         

## Packages and Vulnerabilities

   0C     1H     0M    11L  XXXXXXXXXXXXX XXXXXXXXXXXXX
pkg:deb/debian/XXXXXXXXXXXXX
os_distro=XXXXXXXXXXXXX

    ✗ HIGH CVE-2025-55154
      https://scout.docker.com/v/CVE-2025-55154
      Affected range : >=8:7.1.1.43+dfsg1-1  
      Fixed version  : not fixed             

--- 略 ---

106 vulnerabilities found in 29 packages
  CRITICAL  0    
  HIGH      1    
  MEDIUM    3    
  LOW       102  

What's next:
    View base image update recommendations → docker scout recommendations XXXXXXXXXXXXX:latest

定期執行這些掃描並解決偵測到的任何漏洞。

概括

這裡介紹的技巧並不難實施,我認為你只要稍加註意就能將它們融入日常開發中。回顧起來,有五件事要考慮:

  • 利用多階段建置→輕量級鏡像並消除不必要的依賴

  • 基礎鏡像始終是固定版本→提高可重複性並防止意外的建置錯誤

  • 更少的層數→提高快取效率、建置速度和映像大小

  • 使用.dockerignore → 消除不必要的檔案並實現高效建置

  • 注重安全→選擇可靠的鏡像,定期重建,並檢查漏洞

透過簡單地一點一點地融入這些,您的影像將變得更輕、更快、更安全。

下次編寫 Dockerfile 時,請嘗試其中一個。


原文出處:https://qiita.com/shota0616/items/8adad18c983f4e8301c0


共有 0 則留言


精選技術文章翻譯,幫助開發者持續吸收新知。
站長阿川

站長阿川私房教材:
學 JavaScript 前端,帶作品集去面試!

站長精心設計,帶你實作 63 個小專案,得到作品集!

立即開始免費試讀!