ข้ามไปเนื้อหาหลัก
Docker· ~18 นาที· อัปเดตล่าสุด

Dockerfile — สร้าง image ของตัวเอง (+ Lab)

เขียนสูตร build image พร้อมเข้าใจ layer และ cache

ปูพื้นฐาน: ถ้าเราอยากสร้าง Image ของเราเอง (เช่น เอาโค้ดที่เราเขียนไปทำเป็น Image) เราจะต้องเขียนไฟล์ที่ชื่อว่า Dockerfile ซึ่งเปรียบเสมือนสคริปต์ขั้นตอนการติดตั้งโปรแกรม

Dockerfile คือสูตรอาหาร

Dockerfile คือสูตรอาหาร — เขียนขั้นตอนทีละสเต็ปว่าจะประกอบ image ยังไง · แต่ละบรรทัดสร้าง layer หนึ่งชั้น ที่ Docker แคชไว้ให้ build ครั้งถัดไปเร็วขึ้น

แต่ละคำสั่ง = 1 layer · วางของเปลี่ยนน้อยไว้ล่าง (ฐาน) เพื่อใช้ cache

CMD ["node","server.js"]เปลี่ยนบ่อยสุด
COPY . .โค้ดแอป
RUN npm installdependency (แคชคุ้ม)
COPY package*.json ./ไฟล์ dependency
FROM node:20-alpinebase image

แก้แค่โค้ด → layer ล่างยังใช้ cache เดิม → build เร็ว

แต่ละคำสั่งใน Dockerfile = 1 layer (แคชได้) · เรียงจากที่เปลี่ยนน้อย (บน) ไปเปลี่ยนบ่อย (ล่าง) เพื่อใช้แคชคุ้มสุด
# 1) image ฐานที่มี Node.js อยู่แล้ว
FROM node:20-alpine

# 2) โฟลเดอร์ทำงานภายใน container
WORKDIR /app

# 3) ก๊อป dependency ก่อน (แยก layer เพื่อใช้ cache)
COPY package*.json ./
RUN npm install

# 4) ค่อยก๊อปโค้ดที่เหลือ (ส่วนที่เปลี่ยนบ่อย อยู่ล่าง)
COPY . .

EXPOSE 3000
CMD ["node", "server.js"]
Dockerfile — เว็บแอป Node.js
docker build -t myapp:1.0 .    # build จาก Dockerfile ในโฟลเดอร์นี้ (.)
docker run -d -p 3000:3000 myapp:1.0
docker images                 # เห็น myapp:1.0 ที่เพิ่งสร้าง
build แล้วรัน

สรุป Key Takeaways

  • Dockerfile = สูตร build image · แต่ละบรรทัด = 1 layer ที่แคชได้
  • docker build -t ชื่อ:tag . แล้ว docker run
  • วางของที่เปลี่ยนน้อย (dependency) ไว้บน เพื่อใช้ cache คุ้มสุด

คำถามที่พบบ่อย

ลำดับคำสั่งใน Dockerfile มีผลยังไง ทำไม copy โค้ดไว้ท้ายๆ

เพราะ layer cache — Docker แคชทีละชั้นจากบนลงล่าง ชั้นไหนเปลี่ยน ชั้นถัดลงไปต้อง build ใหม่หมด — โค้ดเราเปลี่ยนบ่อยสุดจึงควรอยู่ล่างสุด ส่วนติดตั้ง dependencies (ที่เปลี่ยนช้า) อยู่บน: COPY package.json → npm install → ค่อย COPY โค้ด — ท่านี้ทำให้ build ซ้ำเร็วขึ้นสิบเท่า

CMD กับ ENTRYPOINT ต่างกันยังไง

ENTRYPOINT = คำสั่งหลักที่ "ตายตัว" ส่วน CMD = ค่า default ที่ผู้รัน override ง่ายๆ ได้ท้าย docker run — ใช้คู่กันแบบ ENTRYPOINT ["myapp"] + CMD ["--help"]: รันปกติได้ help, ส่ง argument อื่นก็แทน CMD — ถ้าจำง่ายๆ: อยากให้ container ทำงานเหมือน binary ตัวหนึ่ง ใช้ ENTRYPOINT

COPY กับ ADD ใช้ตัวไหน

ใช้ COPY เป็นค่าเริ่มต้นเสมอ — ADD มีความสามารถแฝง (แตก tar อัตโนมัติ, โหลดจาก URL) ที่ทำให้พฤติกรรมคาดเดายาก — เป็นข้อแนะนำมาตรฐานใน best practices ของ Docker เอง

อ่านจบแล้วอย่าลืมทำเครื่องหมาย