Docker 映像檔 (Images) 基礎

如果說容器 (Container) 是正在運行的程式,那麼映像檔 (Image) 就是該程式的靜態「快照」。理解映像檔的運作原理,是優化 Docker 效能與安全性的關鍵。

什麼是映像檔?

Docker 映像檔是一個包含執行應用程式所需的所有環境(程式碼、執行庫、環境變數、設定檔)的唯讀模板。

其最大的特色在於:分層儲存結構 (Layered File System)

映像檔的分層結構 (Layering)

Docker 映像檔是由一系列的「層 (Layer)」疊加而成的。每一層都代表了 Dockerfile 中的一條指令。

分層的好處:

  1. 資源共享:如果多個映像檔都基於 ubuntu:22.04,那麼這部分在磁碟上只需要儲存一份。
  2. 增量更新:當你修改了專案程式碼並重新建置時,Docker 只需要重新建置變動的那幾層,大大加快速度。
映像檔的所有層都是唯讀的。當容器啟動時,Docker 會在最上層加上一個可讀寫的「容器層 (Container Layer)」。所有對檔案的修改都發生在這一層,這被稱為 Copy-on-Write (CoW) 機制。

映像檔標記 (Tag)

一個映像檔的完整名稱通常包含兩部分:Repository:Tag

  • Repository (倉庫):映像檔的名稱(例如 nginx, python, mysql)。
  • Tag (標記):映像檔的版本(例如 1.25, 3.11-slim, latest)。
# 如果只寫 nginx,Docker 會自動補上 :latest
docker pull nginx
# 實際執行的是:
docker pull nginx:latest

強烈建議: 在生產環境中,永遠不要使用 :latest,因為它隨時會指向新的版本,可能導致部署環境不一致。請指定明確的版本號,如 node:18.16-alpine

常用映像檔管理指令

搜尋映像檔

除了在 Docker Hub 網站搜尋,也可以用指令:

docker search python

下載映像檔

docker pull python:3.11-slim

查看本地映像檔

docker images

# 輸出範例:
# REPOSITORY   TAG         IMAGE ID       CREATED        SIZE
# python       3.11-slim   a1b2c3d4e5f6   2 days ago     120MB

查看分層歷史

想知道這個映像檔是怎麼做出來的:

docker history python:3.11-slim

標記與修改標籤

這不會複製映像檔,只是給同一個 Image ID 多取一個別名。

# docker tag [來源] [目標]
docker tag python:3.11-slim my-python:v1

刪除映像檔

docker rmi my-python:v1

映像檔的備份與遷移

雖然通常我們會透過 Registry (如 Docker Hub) 來傳輸映像檔,但有時在封閉網路環境中,需要將映像檔存成檔案:

匯出為 .tar 檔:

docker save -o my-image.tar nginx:latest

從檔案匯入:

docker load -i my-image.tar

總結:映像檔的最佳實踐

  1. 選擇輕量的基礎映像檔:例如使用 -alpine-slim 版本,可以顯著減少磁碟空間並降低安全漏洞風險。
  2. 善用分層快取:在撰寫 Dockerfile 時,將不常變動的指令(如安裝套件)放在上面,常變動的人(如複製程式碼)放在下面。
  3. 定期清理:使用 docker image prune 清除不再使用的「懸空」映像檔 (dangling images)。

掌握了映像檔後,你就能更精準地控制你的應用程式環境。