Tag, Push & Pull
ชื่อ image แบบเต็ม
หัวข้อที่มีชื่อว่า “ชื่อ image แบบเต็ม”Docker image ทุกตัวมีชื่อแบบ fully-qualified ประกอบด้วยสี่ส่วน:
registry/namespace/repository:tag| ส่วน | ตัวอย่าง | ค่าเริ่มต้น |
|---|---|---|
| registry | docker.io | docker.io |
| namespace | acme | library (สำหรับ official image) |
| repository | api-server | — |
| tag | 2.1.0 | latest |
ดังนั้น nginx เป็นชื่อย่อของ docker.io/library/nginx:latest และ acme/api-server:2.1.0 หมายถึง docker.io/acme/api-server:2.1.0
สำหรับ GHCR (GitHub Container Registry) รูปแบบคือ:
ghcr.io/<github-owner>/<repository>:<tag>docker tag — เพิ่มชื่อให้ image
หัวข้อที่มีชื่อว่า “docker tag — เพิ่มชื่อให้ image”docker tag ไม่ได้คัดลอก image แต่เพิ่ม pointer ใหม่ที่ชี้ไปยัง layer ชุดเดิม:
# Build image ใน localdocker build -t api-server:2.1.0 .
# เพิ่มชื่อแบบ registry-qualified พร้อม pushdocker tag api-server:2.1.0 acme/api-server:2.1.0
# tag เป็น latest ด้วย (optional)docker tag api-server:2.1.0 acme/api-server:latestทั้ง acme/api-server:2.1.0 และ acme/api-server:latest ชี้ไปยัง image ID เดียวกัน — ไม่ใช้พื้นที่เพิ่ม
docker push — อัปโหลดไปยัง registry
หัวข้อที่มีชื่อว่า “docker push — อัปโหลดไปยัง registry”การ push ต้องผ่านการ authenticate (ดูบทเรียน Docker Hub) หลัง docker login:
docker push acme/api-server:2.1.0docker push acme/api-server:latestแต่ละ layer จะถูกอัปโหลดครั้งเดียวและ deduplicate บน registry หาก image อื่นมี layer เดียวกันอยู่แล้ว Docker จะข้าม layer นั้นไป
ตัวอย่าง output:
The push refers to repository [docker.io/acme/api-server]abc123def456: Pushed789ghijkl012: Layer already exists2.1.0: digest: sha256:deadbeef... size: 1234docker pull — ดาวน์โหลดจาก registry
หัวข้อที่มีชื่อว่า “docker pull — ดาวน์โหลดจาก registry”# Pull version ที่ระบุdocker pull acme/api-server:2.1.0
# Pull จาก GHCRdocker pull ghcr.io/acme/api-server:2.1.0หาก image มีอยู่ใน local แล้ว Docker จะตรวจสอบว่า digest ของ remote เปลี่ยนไปหรือไม่ และดาวน์โหลดเฉพาะ layer ที่อัปเดต
Semantic version tags และ latest
หัวข้อที่มีชื่อว่า “Semantic version tags และ latest”กลยุทธ์การ tag ที่ดีใช้ หลาย tag สำหรับ image เดียวกัน:
docker tag api-server:2.1.0 acme/api-server:2.1.0 # version แน่นอนdocker tag api-server:2.1.0 acme/api-server:2.1 # minor streamdocker tag api-server:2.1.0 acme/api-server:2 # major streamdocker tag api-server:2.1.0 acme/api-server:latest # latest (optional)ผู้ใช้สามารถ pin ที่ 2.1.0 เพื่อความเสถียร หรือติดตาม 2 สำหรับ update ที่ไม่ทำลาย backward compatibility latest เป็นแค่ alias สะดวก ไม่มี semantic อัตโนมัติ
ถือว่า pushed tag เป็น immutable
หัวข้อที่มีชื่อว่า “ถือว่า pushed tag เป็น immutable”เมื่อ tag ถูก push และระบบอื่นเริ่ม pull แล้ว ห้าม overwrite การ push 2.1.0 ซ้ำด้วย content ที่ต่างออกไปจะทำลาย reproducibility — ทีมอื่นอาจ pull image ที่ต่างจากของคุณแม้ชื่อ tag จะเหมือนกัน
แทนที่นั้น ให้สร้าง tag ใหม่เสมอ (2.1.1, 2.2.0) สำหรับ content ที่เปลี่ยนแปลง
ลองทำ: pull และรัน versioned public image
หัวข้อที่มีชื่อว่า “ลองทำ: pull และรัน versioned public image”ไม่สามารถ push ไป Docker Hub จาก Play with Docker ได้ (ไม่มี credentials) แต่สามารถฝึก docker pull, docker tag, และ docker run กับ public image ได้
# Pull a specific nginx version
docker pull nginx:1.27-alpine
# Add a local alias tag
docker tag nginx:1.27-alpine my-nginx:stable
# Check both tags point to the same image ID
docker images nginx
docker images my-nginx
# Run it to verify it works
docker run --rm -d --name test-nginx -p 8080:80 my-nginx:stable
curl http://localhost:8080
docker stop test-nginxข้อแลกเปลี่ยน
หัวข้อที่มีชื่อว่า “ข้อแลกเปลี่ยน”| ตัวเลือก | Benefit | Cost |
|---|---|---|
SHA digest tag (sha256:...) | Exact และ unambiguous บอกได้แน่นอนว่าเป็น content เดิม reproducible 100% | อ่านไม่รู้เรื่อง (ไม่ human-readable) สื่อสารหรือจำเวอร์ชันได้ยาก |
Semver tag (เช่น v1.2.3) | อ่านง่าย สื่อความหมายเวอร์ชันและ intent ชัดเจน | Mutable — ใครก็ push ทับ tag เดิมด้วย content ใหม่ได้ถ้าไม่มีการป้องกัน |
ข้อผิดพลาดที่พบบ่อย
หัวข้อที่มีชื่อว่า “ข้อผิดพลาดที่พบบ่อย”- Push และ deploy เฉพาะ
latesttag ทำให้ไม่มี version ที่ pin ไว้ให้ rollback กลับไปได้เมื่อเกิดปัญหา - Overwrite semver tag เดิมด้วย content ใหม่ แทนที่จะสร้าง tag ใหม่เสมอ
- ไม่ pin ด้วย SHA digest คู่กับ semver ทำให้ตรวจสอบไม่ได้ว่า tag ที่ deploy จริงยังเป็น content เดิมหรือถูกสลับไปแล้ว
💡 ตัวอย่างจากของจริง
หลายทีมที่ใช้ GitOps (เช่น Argo CD, Flux) จะ pin deployment manifest ด้วย SHA digest แทน semver tag เพื่อรับประกันว่า cluster รัน content เดียวกันทุกครั้ง แม้ tag เดิมจะถูก overwrite ในภายหลังก็ตาม