Image và Cơ Chế Layer: Pull, Tag, Docker Hub
docker run ở Bài 3 dựa vào image. Bài này tìm hiểu image: nó đến từ đâu, tên được đọc thế nào, gồm những layer gì (nối tiếp Bài 2), và cách quản lý image trên máy. Registry ta dùng xuyên suốt là Docker Hub — registry mặc định của Docker.
Đọc tên một image
Một tên image đầy đủ có dạng:
[registry/][namespace/]repository[:tag]
docker.io / library / nginx : alpine
└────┬───┘ └───┬───┘ └──┬──┘ └──┬──┘
registry namespace tên tag
(mặc định) (mặc định)
Khi bạn gõ nginx:alpine, Docker tự điền phần mặc định thành docker.io/library/nginx:alpine:
- registry mặc định là
docker.io(Docker Hub). - namespace
librarylà nơi chứa các official image (image chính thức do Docker và các nhà phát hành duyệt). Image của người dùng/tổ chức thì namespace là tên họ, ví dụbitnami/postgresql. - tag mặc định là
latestnếu bạn không ghi.nginx=nginx:latest.
Về tag
latest: nó không có nghĩa "luôn là bản mới nhất" theo cách nhân được tự cập nhật. Nó chỉ là cái tag được dùng khi bạn không ghi tag nào. Một imagemyapp:latestcó thể đã cũ. Vì vậy trong môi trường thật, nên ghi tag cụ thể (phiên bản) thay vì dựa vàolatest— ý này quay lại ở Bài 5 và 9.
Pull: kéo image về từ Docker Hub
docker run tự pull nếu image chưa có. Nhưng bạn cũng pull tường minh được:
docker pull python:3.12-alpine
3.12-alpine: Pulling from library/python
d17f077ada11: Already exists
3124cc6c064b: Pull complete
74bec2074998: Pull complete
05b6ee55fad3: Pull complete
Digest: sha256:...
Để ý: image được tải về theo từng layer (nhớ Bài 2 — image là chuỗi layer). Dòng d17f077ada11: Already exists nghĩa là layer đó đã có sẵn trên máy nên không tải lại.
Layer dùng chung giữa các image
Đây là chỗ cơ chế layer phát huy. Pull thêm một image họ hàng:
docker pull python:3.13-alpine
d17f077ada11: Already exists
3070388042c6: Pull complete
...
Lại d17f077ada11: Already exists. Cả python:3.12-alpine lẫn python:3.13-alpine đều dựng trên cùng một layer base Alpine, nên layer đó chỉ được lưu một lần trên đĩa và dùng chung. Bạn càng dùng nhiều image cùng họ, càng tiết kiệm.
python:3.12-alpine python:3.13-alpine
│ │
┌────┴─────┐ ┌─────┴────┐
│ layer py3.12 │ │ layer py3.13 │ ← khác nhau
├──────────┤ ├──────────┤
│ layer Alpine (d17f077ada11) │ ← DÙNG CHUNG, lưu 1 lần
└─────────────────────────────────────┘
Xem image trên máy
docker images
REPOSITORY TAG SIZE
python 3.13-alpine 48.7MB
python 3.12-alpine ...
Cột SIZE là dung lượng image (gồm các layer của nó). Lưu ý: tổng dung lượng các image hiển thị lớn hơn dung lượng thật trên đĩa, vì các layer dùng chung bị tính trùng ở mỗi image. Muốn xem đĩa thật sự tốn bao nhiêu: docker system df.
Tag: đặt thêm tên cho một image
docker tag tạo một tên mới trỏ tới cùng một image (không copy gì cả):
docker tag python:3.12-alpine myapp:v1
docker images --format '{{.Repository}}:{{.Tag}} -> {{.ID}}'
myapp:v1 -> 2fdd31120aa2
python:3.12-alpine -> 2fdd31120aa2
Cùng một IMAGE ID (2fdd31120aa2) ứng với hai tên. Tag chỉ là một nhãn trỏ vào image; một image có thể mang nhiều tag. Bạn sẽ tag image của mình theo dạng username/repo:tag trước khi push lên Docker Hub.
Image ID và digest: hai cách định danh
- Image ID (
2fdd31120aa2...): định danh image trên máy bạn, tính từ nội dung cấu hình image. - Digest (
sha256:...): định danh image trên registry, không đổi. Pull theo digest đảm bảo lấy đúng image đó dù tag có bị đẩy đè:
docker pull python@sha256:<digest>
Trong môi trường cần độ tin cậy cao, người ta pin theo digest thay vì tag, vì tag có thể bị trỏ sang image khác.
Soi layer của image
Nối tiếp Bài 2, hai lệnh để nhìn vào ruột image:
docker history python:3.12-alpine
Cho thấy mỗi layer ứng với lệnh Dockerfile nào và nặng bao nhiêu — lệnh RUN cài đặt thường nặng, ENV/CMD là 0B.
docker image inspect python:3.12-alpine
Trả về JSON đầy đủ: danh sách layer (RootFS.Layers), biến môi trường, lệnh mặc định (Cmd), kiến trúc... Lấy riêng một phần bằng --format:
docker image inspect python:3.12-alpine --format '{{.Os}}/{{.Architecture}}'
Tìm image trên Docker Hub
docker search postgres
Liệt kê các image khớp trên Docker Hub kèm số sao. Tuy nhiên, để xem tag nào có sẵn và đọc tài liệu image, trang web Docker Hub (hub.docker.com) đầy đủ hơn dòng lệnh.
Mẹo chọn image: ưu tiên official image (namespace
library) và các bản-alpine/-slimcho nhẹ. Tránh image lạ không rõ nguồn — bạn đang chạy code của người khác.
🧹 Dọn dẹp
# xóa các tag/image của bài
docker rmi myapp:v1 python:3.12-alpine python:3.13-alpine
# xóa mọi image không gắn với container nào (dangling + unused)
docker image prune -a
docker image prune -a hỏi xác nhận rồi xóa image không dùng — rất hiệu quả để lấy lại đĩa. Kiểm tra dung lượng:
docker system df
Tổng kết
Image có tên dạng registry/namespace/repository:tag, mặc định trỏ về Docker Hub và tag latest. Image gồm các layer chỉ-đọc, và các layer giống nhau được dùng chung giữa nhiều image để tiết kiệm đĩa — thấy rõ qua dòng "Already exists" khi pull. tag chỉ là nhãn trỏ vào một image; digest mới là định danh cố định trên registry.
Tới giờ ta toàn dùng image người khác làm sẵn. Bài 5 ta tự dựng image của mình: viết Dockerfile, hiểu build cache hoạt động theo layer ra sao, và đóng gói một ứng dụng thật.