Build, Tag และ Build Context
คำสั่ง docker build
หัวข้อที่มีชื่อว่า “คำสั่ง docker build”docker build อ่าน Dockerfile แล้วสร้าง image ออกมา syntax พื้นฐานคือ:
docker build [OPTIONS] PATHอาร์กิวเมนต์ PATH (โดยทั่วไปคือ .) เรียกว่า build context คือไดเรกทอรีที่ Docker ส่งไปให้ build daemon ไฟล์ที่อยู่ใน build context จะใช้ได้กับ instruction COPY ภายใน Dockerfile ส่วนไฟล์ที่อยู่นอก build context จะเข้าถึงไม่ได้
docker build .คำสั่งนี้ส่งไดเรกทอรีปัจจุบันเป็น build context หากไม่มี -t image ที่ได้จะไม่มีชื่อ — มีแค่ hex digest เท่านั้น คุณจึงแทบจะเพิ่ม -t เสมอ
การ tag ด้วย -t
หัวข้อที่มีชื่อว่า “การ tag ด้วย -t”แฟล็ก -t กำหนด name:tag ที่อ่านเข้าใจได้ให้กับ image:
docker build -t myapp:1.0 .รูปแบบเต็มของ tag คือ:
[registry/][owner/]name:tagตัวอย่าง:
myapp:1.0myapp:latestghcr.io/acme/myapp:1.0docker.io/library/node:22-alpineหากคุณละส่วน tag ไว้ Docker จะใช้ค่าเริ่มต้นเป็น :latest
การแสดงรายการ image ด้วย docker images
หัวข้อที่มีชื่อว่า “การแสดงรายการ image ด้วย docker images”docker imagesผลลัพธ์ที่คาดหวัง:
REPOSITORY TAG IMAGE ID CREATED SIZEmyapp 1.0 a3f2b1c9d4e7 2 minutes ago 145MBmyapp latest a3f2b1c9d4e7 2 minutes ago 145MBnode 22-alpine 1b2c3d4e5f60 3 weeks ago 52MBการ tag ซ้ำด้วย docker tag
หัวข้อที่มีชื่อว่า “การ tag ซ้ำด้วย docker tag”docker tag เพิ่มชื่อหรือ tag ใหม่ให้กับ image ที่มีอยู่แล้วโดยไม่คัดลอกตัว image ทั้งสองชื่อจะชี้ไปยัง image ID เดียวกัน
# Promote a build image to a release namedocker tag myapp:1.0 myapp:stabledocker tag myapp:1.0 ghcr.io/acme/myapp:1.0ความหมายของ latest
หัวข้อที่มีชื่อว่า “ความหมายของ latest”latest ไม่ใช่ tag วิเศษที่หมายถึง “ใหม่ล่าสุด” เป็นแค่สตริงเริ่มต้นที่ Docker ใช้เมื่อคุณละ tag ไว้ ไม่มีความหมายเชิง semantic version ใด ๆ ถ้าคุณ push myapp:1.0 และ myapp:latest แยกกัน ทั้งสองอาจชี้ไปยัง image layer ที่ต่างกันโดยสิ้นเชิงก็ได้
ใน production pipeline ให้ใช้ tag ที่ชัดเจนและมีความหมายเสมอ (เลขเวอร์ชัน, git SHA, วันที่) เพื่อให้คุณรู้แน่ชัดว่าสิ่งที่ deploy ไปคืออะไร
เร่งความเร็ว context ด้วย .dockerignore
หัวข้อที่มีชื่อว่า “เร่งความเร็ว context ด้วย .dockerignore”โดยปริยาย docker build . จะส่งไดเรกทอรีปัจจุบันทั้งหมดของคุณไปยัง daemon — รวมถึง node_modules/, .git/, test fixtures, และ secret ภายในเครื่อง ไฟล์ .dockerignore (syntax เดียวกับ .gitignore) จะกีดกัน path ออกจาก build context ซึ่ง:
- เร่งความเร็วการ build (มีข้อมูลต้องส่งน้อยลง)
- ป้องกันการเผลอ
COPYsecret เข้าไปใน image ของคุณ
node_modules/.git/.env*.logdist/coverage/ประกอบทุกอย่างเข้าด้วยกัน
หัวข้อที่มีชื่อว่า “ประกอบทุกอย่างเข้าด้วยกัน”# Build with a version tagdocker build -t myapp:1.0 .
# Also tag as latestdocker tag myapp:1.0 myapp:latest
# Inspect the resultdocker images myappผลลัพธ์ที่คาดหวัง:
REPOSITORY TAG IMAGE ID CREATED SIZEmyapp 1.0 a3f2b1c9d4e7 1 minute ago 145MBmyapp latest a3f2b1c9d4e7 1 minute ago 145MBฝึกลงมือทำ
หัวข้อที่มีชื่อว่า “ฝึกลงมือทำ”# syntax=docker/dockerfile:1
FROM alpine:3.20
LABEL maintainer="[email protected]"
WORKDIR /app
RUN echo "v1.0" > version.txt
CMD ["cat", "version.txt"]
# --- build, tag, and inspect ---
# docker build -t myapp:1.0 .
# docker tag myapp:1.0 myapp:latest
# docker images myapp
# docker run --rm myapp:1.0ข้อแลกเปลี่ยน
หัวข้อที่มีชื่อว่า “ข้อแลกเปลี่ยน”| ตัวเลือก | Benefit | Cost |
|---|---|---|
| alpine base image | image เล็ก, pull เร็ว | ใช้ musl libc ทำให้บาง native binary หรือ npm package compile ไม่ผ่านหรือพังตอน runtime |
| debian/full base image | มี tool ครบ, compatibility กับ glibc สูง | image ใหญ่กว่ามาก, push/pull ช้าลง |
ข้อผิดพลาดที่พบบ่อย
หัวข้อที่มีชื่อว่า “ข้อผิดพลาดที่พบบ่อย”- ลืม pin tag ของ image (ปล่อยให้เป็น
latestหรือไม่ใส่ tag เลย) ทำให้ build วันนี้กับพรุ่งนี้ได้ image คนละตัว - ไม่มีไฟล์
.dockerignoreทำให้ build context บวมและ build ช้าลง แถมเสี่ยง secret หลุดเข้าไปใน image - สั่ง
docker buildโดยไม่ใส่-tเลย ได้ image ที่ไม่มีชื่อ ต้องมาไล่หาด้วย image ID ทีหลัง
💡 ตัวอย่างจากของจริง
Docker Hub official image อย่าง
nodeหรือpostgrespublish หลาย tag พร้อมกัน (เช่น22,22-alpine,22-slim) และ build แบบ multi-arch (amd64/arm64) เพื่อให้ทีม production เลือก pin tag ที่เหมาะกับงานได้ตรงจุด