ข้ามไปยังเนื้อหา

การรัน Containers

วัดบน Docker Desktop 4.81.0 / Engine 29.6.1 (macOS, linux/arm64), 2026-09-30

image คือ blueprint ส่วน container คือ instance ที่มีชีวิตและกำลังทำงานของ blueprint นั้น — process ที่ถูกแยกตัว มีมุมมอง filesystem, network และพื้นที่ process ของตัวเอง โดยทั้งหมดแชร์ kernel ของ host

คุณรันหลาย container จาก image เดียวกันได้ หยุดและเริ่มใหม่ ตรวจ log และลบทิ้งเมื่อเสร็จ การเข้าใจวงจรชีวิตนี้เป็นรากฐานของการทำงานกับ Docker ในแต่ละวัน

engine รายงานหนึ่งใน เจ็ด state ผ่าน docker inspect --format '{{.State.Status}}' (สรุปสี่ state แบบเดิม “created, running, stopped, removed” ตกหล่น state ที่คุณจะเจอตอน debug):

Stateความหมายไปถึงได้อย่างไร (พิสูจน์แล้ว)
createdcontainer มีอยู่แต่ process ยังไม่เคยถูก startdocker create, Status=created
runningprocess หลักกำลังทำงานdocker start / docker run
pausedprocess ถูกแช่แข็งด้วย cgroup freezer; หน่วยความจำยังถูกจองไว้docker pause → Status=paused Running=true Paused=true, ps แสดง Up … (Paused)
restartingrestart policy กำลังรอระหว่างความพยายามครั้งต่อไปหลัง exit--restart always กับคำสั่งที่ exit 1 → Status=restarting ExitCode=1, ps แสดง Restarting (1)
exitedprocess หลักจบแล้ว (หรือ docker stop) container, writable layer, log และ exit code ยังอยู่บนดิสก์docker stop → Status=exited ExitCode=137 สำหรับ sleep ที่เมิน SIGTERM
removingdocker rm กำลังทำงาน อยู่สั้นมากอยู่ใน status filter ของ docker container ls
deadcontainer ที่ “defunct”: การลบสำเร็จเพียงบางส่วนเพราะมีบางอย่างถือ resource ไว้ start ใหม่ไม่ได้ ลบได้อย่างเดียว (ตามเอกสาร) พบยาก — เราสร้างตามสั่งไม่ได้ตารางเดียวกันในเอกสาร

หลัง docker rm เสร็จจะไม่มี state ใดเหลืออีก: มันลบ container และ writable layer ของมัน แล้ว container ก็หายไปจากทุกที่

flowchart LR
  created["created"] -->|docker start| running["running"]
  running -->|docker pause| paused["paused"]
  paused -->|docker unpause| running
  running -->|process exits or docker stop| exited["exited"]
  exited -->|docker start| running
  running -->|crash with a restart policy| restarting["restarting"]
  restarting --> running
  exited -->|docker rm| removed["gone (removed)"]
  created -->|docker rm| removed
state ของ container และคำสั่งที่ใช้เปลี่ยนระหว่าง state

บรรทัด docker inspect จริงของ state ที่พิสูจน์แล้ว:

created Status=created Running=false Paused=false Restarting=false ExitCode=0
running Status=running Running=true Paused=false Restarting=false ExitCode=0
paused Status=paused Running=true Paused=true Restarting=false ExitCode=0
exited Status=exited Running=false Paused=false Restarting=false ExitCode=137
restarting Status=restarting Running=true Paused=false Restarting=true ExitCode=1

สังเกต Running=true ขณะ paused หรือ restarting: เมื่อต้องการ state ที่แน่นอนให้กรองด้วย .State.Status ไม่ใช่ .State.Running

docker run → created + running
docker stop → exited
docker start → running again (same container, same writable layer)
docker rm → removed (gone)
บทเรียนหัวข้อ
Lifecycledocker run, docker ps, docker stop/start/restart, docker rm, --rm, exit code
Exec & Logsdocker exec -it, docker logs, docker top, attach, การหมุนเวียน log
Ports & Envpublish port ด้วย -p, environment variable ด้วย -e / --env-file, ตั้งชื่อด้วย --name
Restart & Inspectrestart policy, docker inspect, docker stats, resource limit

คำสั่งที่คุณจะใช้บ่อยที่สุดในโมดูลนี้:

scripts/quick-demo.sh
#!/bin/sh
# Pull and run nginx in the background
docker run -d --name demo nginx:1.31-alpine
# List running containers
docker ps
# Stop it
docker stop demo
# Remove it
docker rm demo
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c0d6336221c2 nginx:1.31-alpine "/docker-entrypoint.…" 3 seconds ago Up 2 seconds 80/tcp demo

80/tcp ที่ไม่มีลูกศรหมายความว่า image ประกาศ port 80 (EXPOSE) แต่ไม่มีอะไรถูก publish ไปยัง host

# Pull and run nginx detached
docker run -d --name demo nginx:1.31-alpine
# Confirm it is running
docker ps
# Stop the container
docker stop demo
# Remove it
docker rm demo
# Confirm it is gone
docker ps -a

probe เช็คสุขภาพสำหรับสคริปต์ deploy ที่ AI เขียน:

🐛 หา bug ในโค้ดนี้

#!/bin/sh
# AI: "fail the deploy if the web container is not running"
if [ -z "$(docker ps -q --filter name=web)" ]; then
echo "web is down" >&2
exit 1
fi
echo "web is up"
เฉลย

--filter name= เป็นการจับคู่แบบ substring/regex บนชื่อ container ไม่ใช่การเทียบเท่ากัน ถ้า container web ตัวจริงหายไปแต่มี container ชื่อ webhook (หรือ web-old) รันอยู่ probe ก็ผ่าน ทำซ้ำได้โดยย่อชื่อจาก docker-b1-web / docker-b1-webhook (มีเฉพาะตัวที่สอง):

$ docker ps -q --filter name=web | wc -l
1
$ docker ps --filter name=web --format '{{.Names}}'
webhook
$ docker ps -q --filter 'name=^web$' | wc -l
0
$ docker inspect -f '{{.State.Running}}' web
error: no such object: web

ให้ anchor pattern หรือดีกว่านั้นคือถามถึง container ที่ตรงตัวและ state ของมัน:

scripts/check-web.sh
#!/bin/sh
set -eu
state=$(docker inspect -f '{{.State.Status}}' web 2>/dev/null || echo missing)
if [ "$state" != "running" ]; then
echo "web is $state" >&2
exit 1
fi
echo "web is up"

docker inspect กับ container ที่ไม่มีอยู่จะ exit ไม่เป็นศูนย์พร้อม no such object ซึ่ง || echo missing เปลี่ยนให้เป็น state แทนที่จะผ่านโดยบังเอิญ

container คือ แถวในฐานข้อมูลของ engine บวก process (ตอนรัน) บวก writable layer บนดิสก์ docker stop จบแค่ process; แถวและ layer อยู่ต่อจนกว่าจะ docker rm ความสับสนส่วนใหญ่ในโมดูลนี้ — “container ฉันหายไปไหน”, “ทำไมดิสก์เต็ม”, “ทำไมชื่อชนกัน” — มาจากการลืมว่าแถวอยู่ได้นานกว่า process

ทางเลือกข้อดีข้อเสีย
เก็บ container ที่ exit แล้วexit code, log และ writable layer ยังตรวจสอบได้สะสมดิสก์และครองชื่อ
--rmcontainer แบบใช้ครั้งเดียวที่ล้างตัวเองไม่เหลืออะไรให้ตรวจหลัง crash
docker pauseแช่แข็งโดยไม่เสีย memory state หรือ PIDหน่วยความจำยังถูกจองไว้; peer บน network เห็น service ค้าง
  • “container ที่หยุดแล้วถูกลบ” มันเป็น exited และ docker ps -a ยังแสดงอยู่พร้อม writable layer
  • “Running=true แปลว่า process กำลังทำงาน” container ที่ paused ก็รายงาน Running=true ให้ตรวจ .State.Status
  • “docker ps แสดงทุก container” แสดงเฉพาะที่รัน (และ paused/restarting) ใส่ -a เพื่อดูที่เหลือ
  • “docker ps --filter name=x หา container x” มันหาทุก container ที่ชื่อมี x หรือตรงกับ x
container เข้าสู่ state ใดทันทีหลัง 'docker stop'?
image กับ container ต่างกันอย่างไร?
หลัง 'docker stop' คุณ start container อีกครั้งได้ไหม?
หลัง docker pause web docker inspect และ docker ps รายงานอะไร?
probe ใช้ docker ps -q --filter name=web และผ่านทั้งที่ container web ถูกลบไปแล้ว เพราะอะไร?