บทนำและแนวคิด — ภาพรวมโมดูล
ทำไมต้อง Docker?
หัวข้อที่มีชื่อว่า “ทำไมต้อง Docker?”นักพัฒนาทุกคนเคยได้ยินประโยคนี้: “บนเครื่องผมมันรันได้นะ” แอปทำงานได้สมบูรณ์ตอนพัฒนา แต่พังบน staging หรือ production เพราะ OS ต่างกัน library คนละเวอร์ชัน หรือขาด environment variable Docker ลดช่องว่างนั้นด้วยการแพ็กแอปพร้อมทุกอย่างที่ต้องใช้ — runtime, dependency และ configuration — ให้เป็นหน่วยเดียวที่พกพาได้ เรียกว่า container
สิ่งที่ได้จาก Docker:
- สภาพแวดล้อมสม่ำเสมอ — image เดียวกันให้ userland เดียวกันทั้งบน laptop, CI server และ cloud VM (kernel ข้างใต้ยังเป็นของ host ดู Containers vs VMs)
- การแยกตัว (Isolation) — แต่ละ container มีมุมมอง filesystem และ process ของตัวเอง แอปจึงไม่รบกวนกัน
- ความเร็ว — ไม่ต้อง boot guest OS วัดจริงด้านล่าง:
docker runแบบ warm เสร็จในราว 1 ใน 4 วินาที - Reproducibility —
Dockerfileคือสูตรที่แม่นยำ build จาก base image ที่ pin เวอร์ชันและ input เดียวกันจะได้ผลเดียวกัน
โมดูลนี้ครอบคลุมอะไร
หัวข้อที่มีชื่อว่า “โมดูลนี้ครอบคลุมอะไร”| บทเรียน | สิ่งที่คุณจะได้เรียนรู้ |
|---|---|
| หน้านี้ | ปัญหาที่ Docker แก้ container แรก ตัวเลขเวลาจริง |
| What is Docker? | สถาปัตยกรรม: client, daemon, image, registry — พิสูจน์ผ่าน socket จริง |
| Containers vs VMs | การแชร์ kernel, namespace, cgroup — พิสูจน์ด้วย uname, /proc และ memory.max |
| Install & Verify | ติดตั้ง Docker ตรวจสอบการติดตั้ง และกลุ่ม docker |
| Your First Container | container แบบ interactive + detached, docker ps, docker stop และ timeout 10 วินาที |
เวอร์ชันที่ใช้ในคอร์สนี้
หัวข้อที่มีชื่อว่า “เวอร์ชันที่ใช้ในคอร์สนี้”ทุกคำสั่งและทุก output ในคอร์สนี้รันบนเครื่องเดียวกัน เมื่อ 2026-09-30:
| Component | เวอร์ชัน (จาก docker version / docker compose version) |
|---|---|
| Docker Desktop | 4.81.0 (macOS, Apple Silicon, linux/arm64) |
| Docker Engine | 29.6.1 (API 1.55, ขั้นต่ำ 1.40) |
| containerd / runc | v2.2.5 / 1.3.6 |
| Buildx / BuildKit | v0.35.0-desktop.2 / v0.31.1 |
docker compose plugin | v5.3.0 (ไม่มี binary docker-compose แยก และไม่มี “Compose v2” อีกแล้ว) |
output ที่วางไว้คือผลจริงจากเครื่อง Mac นี้ ส่วนที่ Linux Engine ทำงานต่างออกไปจะมี callout บอก ขนาด image เป็นขนาดของ arm64 ส่วน amd64 จะต่างเล็กน้อย
container แรกของคุณ
หัวข้อที่มีชื่อว่า “container แรกของคุณ”วิธีที่เร็วที่สุดในการยืนยันว่า Docker ทำงานได้คือ image ทางการ hello-world Docker จะดึง image จาก Docker Hub หากยังไม่มีในเครื่อง สร้าง container พิมพ์ข้อความ แล้วจบการทำงาน
docker run hello-worldลองรันตอนนี้ด้วย playground ด้านล่าง:
docker run hello-world“เร็ว” แค่ไหน? วัดจริง
หัวข้อที่มีชื่อว่า ““เร็ว” แค่ไหน? วัดจริง”จับเวลารัน container ที่ไม่ทำอะไรเลย (true จบทันที) 3 ครั้ง โดยมี image อยู่แล้ว บน Mac เครื่องนี้ (wall clock รวมเวลา start CLI และการเดินทางเข้า VM):
$ docker run --rm alpine:3.24 true # 0.25 s$ docker run --rm alpine:3.24 true # 0.24 s$ docker run --rm alpine:3.24 true # 0.25 sและ cold start จริง ๆ — image ไม่อยู่ในดิสก์ จึงรวมเวลา pull จาก Docker Hub (สั่ง docker rmi hello-world ก่อน):
$ docker run --rm hello-world # 4.21 s (ส่วนใหญ่คือ pull ผ่านเครือข่าย)$ docker run --rm hello-world # 0.25 s (warm)ดังนั้นคำว่า “มิลลิวินาที” ในโฆษณาหมายความว่า การสร้าง namespace กับ cgroup แล้ว exec process นั้นถูกมาก และไม่มี kernel ให้ boot สิ่งที่คุณรอจริง ๆ คือการ pull (ครั้งแรก) และเวลา start ของแอปคุณเอง VM ต้อง boot guest kernel และ init system ทั้งชุดก่อนที่ process ของคุณจะเริ่ม ความต่างตรงนั้นคือประเด็น ไม่ใช่ตัวเลขที่แน่นอน
ส่วนต่าง ๆ รันที่ไหนบน Mac
หัวข้อที่มีชื่อว่า “ส่วนต่าง ๆ รันที่ไหนบน Mac”flowchart LR
subgraph MAC["macOS (เครื่อง Mac ของคุณ)"]
cli["docker CLI (darwin/arm64)"]
sock["~/.docker/run/docker.sock"]
end
subgraph VM["Docker Desktop Linux VM (kernel linuxkit)"]
engine["dockerd + containerd + runc"]
c1["container ของคุณ (linux/arm64)"]
end
cli --> sock --> engine --> c1 Reading AI-generated code
หัวข้อที่มีชื่อว่า “Reading AI-generated code”AI assistant มักเขียนสคริปต์ตรวจ “Docker พร้อมหรือยัง” ที่ดูสมเหตุสมผล สคริปต์นี้เจอได้บ่อยตอนต้นของสคริปต์ CI และ setup:
🐛 หา bug ในโค้ดนี้
#!/bin/sh# AI: "verify that Docker is installed and running before the build"if docker --version; thenecho "Docker is ready"docker build -t myapp:ci .fiเฉลย
docker --version ถาม binary ของ client เท่านั้นว่าเวอร์ชันอะไร จึงสำเร็จแม้ไม่มี daemon ให้เชื่อมต่อ พิสูจน์โดยชี้ CLI ไปที่ socket ที่ไม่มีอยู่:
$ DOCKER_HOST=unix:///nonexistent.sock docker --versionDocker version 29.6.1, build 8900f1d$ echo $?0$ DOCKER_HOST=unix:///nonexistent.sock docker version --format '{{.Server.Version}}'failed to connect to the docker API at unix:///nonexistent.sock; check if the path is correct and if the daemon is running: dial unix /nonexistent.sock: connect: no such file or directory$ echo $?1สคริปต์จะพิมพ์ “Docker is ready” แล้วค่อยล้มที่ docker build พร้อม log ที่ชวนสับสน ให้ถาม server แทน — ทั้ง docker info และ docker version --format จะ exit ด้วยค่าไม่ใช่ศูนย์เมื่อเข้าถึง daemon ไม่ได้:
#!/bin/shset -euif ! docker info >/dev/null 2>&1; then echo "Docker daemon is not reachable (is Docker Desktop running?)" >&2 exit 1fiecho "Docker is ready: $(docker version --format '{{.Server.Version}}')"Mental Model
หัวข้อที่มีชื่อว่า “Mental Model”มอง Docker เป็นสามชั้นซ้อนกัน: client ที่แปลคำสั่งเป็น API call, engine ที่เป็นเจ้าของ image, container, network และ volume, และ Linux kernel ที่แยก process จริง ๆ container ไม่ใช่คอมพิวเตอร์เครื่องเล็ก แต่เป็น process ธรรมดาของ Linux ที่ kernel ถูกสั่งให้แสดงมุมมอง filesystem, network และ process table แบบส่วนตัวให้ มันจึง start ในราว 1 ใน 4 วินาที และเร็วกว่า process ที่อยู่ข้างในไม่ได้
Trade-offs
หัวข้อที่มีชื่อว่า “Trade-offs”| ทางเลือก | ข้อดี | ข้อเสีย |
|---|---|---|
| ใช้ container แทนการติดตั้งบน host | image เดียวกันทุกที่ สร้าง/ทิ้ง environment สะอาด ๆ ได้ | ต้องดูแล engine, image และ registry |
| Docker Desktop บน Mac/Windows | ตัวติดตั้งเดียวได้ CLI, engine, Compose, Buildx | engine อยู่ใน VM: ใช้ RAM เพิ่ม, file sharing มี overhead, IP ของ bridge เข้าจาก host ไม่ได้ |
| Pull จาก Docker Hub ตอนรันครั้งแรก | ไม่ต้องตั้งค่า | cold start เสียเวลาหลายวินาทีและนับรวมใน pull rate limit |
Common Misconceptions
หัวข้อที่มีชื่อว่า “Common Misconceptions”- “container start ในมิลลิวินาที” การตั้งค่า isolation ถูกจริง แต่วัดปลายทาง-ปลายทางได้ 0.25 วินาทีเมื่อ warm และ 4.21 วินาทีเมื่อ cold เวลา start ของแอปคุณเองมักเป็นตัวหลัก
- “Docker รับประกันพฤติกรรมเหมือนกันทุกที่” image เหมือนกัน แต่ kernel, สถาปัตยกรรม CPU (
arm64ที่นี่) และการตั้งค่าของ host ไม่เหมือน image ที่มีแต่amd64จะรันผ่าน emulation บน Apple Silicon - “
docker --versionพิสูจน์ว่า Docker ใช้งานได้” มันพิสูจน์แค่ว่าติดตั้ง client แล้ว ให้ใช้docker info