Logs & Exec
เมื่อ container ทำงานผิดปกติ เครื่องมือสองตัวที่ต้องรู้จักคือ docker logs สำหรับดูสิ่งที่ container พิมพ์ออกมา และ docker exec สำหรับเข้าไปตรวจสอบข้างในโดยตรง สองอย่างนี้ครอบคลุมปัญหา debug ส่วนใหญ่ที่นักพัฒนาเจอ
ภาพจำสำคัญบทนี้
docker logs = ดู output ของ container | docker exec -it [name] sh = เข้าไปข้างใน | ดู logs ก่อนเสมอ ค่อย exec ถ้าต้องการ | exec ต้องการ container running เท่านั้น
ส่วนที่ 1
Logs & Exec คืออะไร และเหตุใดต้องมีทั้งสองอย่าง
เมื่อ container ทำงานอยู่ มีสองอย่างที่เราต้องการได้ยินจากมัน อย่างแรกคือสิ่งที่มัน "พูดออกมา" เช่น error message, request log หรือข้อความ startup อย่างที่สองคือการเข้าไปข้างใน container เพื่อดูว่า environment เป็นอย่างไร ไฟล์อยู่ที่ไหน process อะไรกำลังทำงาน docker logs ทำหน้าที่แรก ส่วน docker exec ทำหน้าที่ที่สอง ทั้งสองทำงานเสริมกัน ไม่ใช่ทดแทนกัน
ประเด็นที่ 1
docker logs = ดูสิ่งที่ container "พูดออกมา" ทาง stdout/stderr เหมือนนั่งอ่าน diary ของ container
ประเด็นที่ 2
docker exec = เปิด terminal เข้าไปข้างใน container ที่กำลัง running เหมือน SSH เข้าไปดูตรง ๆ
ประเด็นที่ 3
ใช้ทั้งสองร่วมกัน: logs บอกว่ามีปัญหา exec ช่วยค้นหาสาเหตุและตรวจสอบ environment
ส่วนที่ 2
สถานการณ์จริง: container รันแล้วเปิดเว็บไม่ได้
นี่คือสถานการณ์ที่เกิดขึ้นบ่อยที่สุด: เรารัน container แล้ว docker ps บอกว่ากำลัง running แต่เปิด browser ไปที่ localhost แล้วไม่มีอะไรขึ้น หรือขึ้น error ขั้นตอนการ debug ที่ถูกต้องคือ ดู logs ก่อนเสมอ เพราะ 80% ของเวลา log บอกสาเหตุได้ทันที
- ขั้นที่ 1: ตรวจสอบว่า container running จริงด้วย docker ps
- ขั้นที่ 2: ดู log ด้วย docker logs [name] เพื่อหา error message
- ขั้นที่ 3: ถ้า log ไม่ชัดเจนพอ ให้ exec เข้าไปตรวจ environment ข้างใน
- ขั้นที่ 4: ตรวจสอบ port mapping ว่า -p ถูกต้องหรือไม่
ส่วนที่ 3
ทำไมการดู logs จึงสำคัญ
Logs คือหลักฐานที่ container ทิ้งไว้ ทุก container ที่ออกแบบมาอย่างถูกต้องจะพิมพ์สถานะและ error ออกมาทาง stdout หรือ stderr Docker เก็บ output เหล่านี้ไว้ให้เราดูได้ตลอดเวลา แม้ container จะหยุดทำงานไปแล้ว การดู log ก่อน exec เป็น practice ที่ดีเพราะเร็วกว่า ไม่รบกวน process ที่กำลังรัน และมักแก้ปัญหาได้โดยไม่ต้องเข้าไปข้างใน
- logs ช่วยหา error ที่เกิดตอน startup เช่น port ชน, ไฟล์ config ไม่ถูกต้อง, env var ขาด
- logs แสดง request/response ของ web server เพื่อดูว่า traffic เข้ามาหรือไม่
- logs บอก exit code เมื่อ container หยุดทำงาน เพื่อแยกแยะว่า crash หรือ stop ปกติ
- ดู logs ได้แม้ container stopped แล้ว ซึ่ง exec ทำไม่ได้เพราะต้องรันอยู่
ส่วนที่ 4
คำสั่ง docker logs พื้นฐาน
docker logs ดึง output ทั้งหมดที่ container เคยพิมพ์ออกมาทาง stdout และ stderr ตั้งแต่เริ่มรันจนถึงปัจจุบัน เหมาะสำหรับดูภาพรวมหรือหา error ที่เกิดขึ้นก่อนหน้านี้
แสดง log ทั้งหมดตั้งแต่ container เริ่มรัน ทั้ง stdout (ปกติ) และ stderr (error) รวมกัน
ส่วนที่ 5
docker logs -f — ติดตาม log แบบต่อเนื่อง (tail)
flag -f ย่อมาจาก --follow คือการ "ติดตาม" log แบบ real-time เหมือนกับคำสั่ง tail -f บน Linux terminal จะค้างอยู่และแสดง log ใหม่ทันทีที่ container พิมพ์ออกมา กด Ctrl+C เพื่อหยุดดู (container ยังทำงานต่อ) ใช้เมื่อต้องการดูว่าเกิดอะไรขึ้นในขณะที่ส่ง request หรือทดสอบ feature บางอย่าง
terminal จะค้างอยู่และแสดง log ใหม่ทุกครั้งที่ container พิมพ์ออกมา กด Ctrl+C เพื่อออกจากโหมดนี้
ส่วนที่ 6
options สำคัญของ docker logs
นอกจาก -f ยังมี options อื่นที่ช่วยกรองและจัดการ log ได้อย่างมีประสิทธิภาพ โดยเฉพาะเมื่อ log มีจำนวนมาก
| Option | ความหมาย | ตัวอย่าง |
|---|---|---|
| -f / --follow | ติดตาม log แบบ real-time จนกว่าจะกด Ctrl+C | docker logs -f my-nginx |
| --tail N | แสดง log เฉพาะ N บรรทัดสุดท้าย ไม่ดึงทั้งหมด | docker logs --tail 50 my-nginx |
| --since | แสดง log ตั้งแต่เวลาที่กำหนด เช่น 10m, 2h, หรือ timestamp | docker logs --since 10m my-nginx |
| -t / --timestamps | เพิ่ม timestamp หน้าแต่ละบรรทัดของ log | docker logs -t my-nginx |
| --until | แสดง log จนถึงเวลาที่กำหนด ใช้คู่กับ --since เพื่อดู time range | docker logs --until 1h my-nginx |
ส่วนที่ 7
ตัวอย่างจริง: อ่าน error จาก log ของ container
ตัวอย่างด้านล่างแสดง workflow ในการดู log เพื่อหาสาเหตุที่ container ไม่ทำงานตามที่คาดหวัง สังเกต output ที่ได้รับและวิธีตีความ
ลองรันตามเพื่อเห็น nginx startup log จริง และทดสอบ -f โดยเปิด terminal คู่ขนาน
ส่วนที่ 8
คำสั่ง docker exec คืออะไร
docker exec คือการรัน command เพิ่มเติมใน container ที่กำลัง running อยู่ เหมือนการเปิด terminal เพิ่มขึ้นมาอีกช่องหนึ่งภายใน container เดียวกัน process ที่รันอยู่เดิมไม่ได้รับผลกระทบ ข้อสำคัญ: container ต้องอยู่ในสถานะ running เท่านั้น ถ้า container stopped จะ exec ไม่ได้ ต้องใช้ docker start ก่อน
-it = interactive + tty (ใช้เสมอเมื่อต้องการ shell) / sh = เปิด shell ภายใน container
ส่วนที่ 9
exec กับ bash vs sh — เลือกอันไหน
ปัญหาที่พบบ่อยคือพิมพ์ bash แล้วได้ error "bash not found" เพราะ image ขนาดเล็กอย่าง Alpine ไม่ได้ติดตั้ง bash ไว้ ให้ใช้ sh แทน ส่วน image ที่ใช้ Debian/Ubuntu เป็นฐาน เช่น ubuntu, node, python มักมี bash ให้ใช้
Alpine Linux ใช้ sh เพราะไม่มี bash / Ubuntu/Debian มี bash / ถ้าไม่แน่ใจให้ลอง sh ก่อนเสมอ
ส่วนที่ 10
หลัง exec เข้าไปแล้วสามารถทำอะไรได้บ้าง
เมื่อเข้าไปใน container shell ได้แล้ว เราสามารถทำได้ทุกอย่างเหมือนอยู่ใน Linux terminal ทั่วไป แต่มีขอบเขตอยู่ภายใน container เท่านั้น การเปลี่ยนแปลงใด ๆ ที่ทำข้างในจะหายไปเมื่อ container ถูก remove
- ตรวจสอบ environment variable ด้วย printenv หรือ env เพื่อดูว่า config ถูกส่งเข้ามาครบหรือไม่
- ดูไฟล์ config ที่ container ใช้งานจริง เช่น cat /etc/nginx/nginx.conf
- ตรวจสอบ process ที่กำลังรันด้วย ps aux หรือ top
- ทดสอบ network ภายใน container ด้วย curl หรือ wget
- ดูขนาดและ permission ของไฟล์ด้วย ls -la
- ตรวจสอบ disk usage ด้วย df -h
ส่วนที่ 11
ตัวอย่างจริง: exec เพื่อตรวจ environment และไฟล์
ตัวอย่างด้านล่างแสดงคำสั่งที่ใช้บ่อยที่สุดหลังจาก exec เข้าไปใน container เหมาะสำหรับ debug ปัญหาที่เกิดจาก config ผิดหรือ env var ขาด
คำสั่งเหล่านี้ช่วย debug ปัญหา config ผิด, env var ขาด, process crash ภายใน container ได้ตรงจุด
ส่วนที่ 12
เปรียบเทียบ docker logs กับ docker exec
ทั้งสองคำสั่งเป็นเครื่องมือ debug แต่ใช้ต่างกัน ตารางด้านล่างเปรียบเทียบให้เห็นชัดว่าเมื่อไรควรเลือกอะไร
| ด้าน | docker logs | docker exec |
|---|---|---|
| วัตถุประสงค์ | ดูสิ่งที่ container พิมพ์ออกมา (stdout/stderr) | รัน command เพิ่มใน container ที่กำลังทำงาน |
| container ต้อง running? | ไม่ — ดูได้แม้ stopped | ใช่ — container ต้อง running เท่านั้น |
| รบกวน process เดิม? | ไม่รบกวนเลย | ไม่รบกวน แต่ใช้ทรัพยากรเพิ่ม |
| เหมาะกับ | ดู error, startup log, request log | ตรวจ env, ไฟล์ config, process ภายใน |
| ใช้ก่อน | ใช้ก่อนเสมอ — เร็วกว่าและปลอดภัยกว่า | ใช้เมื่อ log ไม่เพียงพอหรือต้องตรวจเพิ่ม |
ส่วนที่ 13
workflow แนะนำ: ดู logs ก่อน ค่อย exec ถ้าต้องการ
นี่คือลำดับที่แนะนำเมื่อ container มีปัญหา ทำตามลำดับนี้จะแก้ได้เร็วที่สุดและปลอดภัยที่สุด
ส่วนที่ 14
ข้อควรระวังในการใช้ docker exec
exec เป็นเครื่องมือที่ทรงพลังและต้องใช้ด้วยความระมัดระวัง โดยเฉพาะกับ container ใน production environment
- อย่าแก้ไขไฟล์ใน production container โดยตรง — การเปลี่ยนแปลงหายไปเมื่อ container restart และทำให้ environment ไม่ reproducible
- exec เข้าไปได้ก็ไม่ได้แปลว่าควรทำเสมอ — ใน production ควรใช้ logs เป็นหลัก และ exec เฉพาะกรณีเร่งด่วน
- ระวัง rm -rf ภายใน container — ถ้าลบไฟล์สำคัญ container อาจ crash ได้
- exec ต้องการ container running — ถ้า container crash และ restart loop เราอาจ exec ไม่ได้เพราะ container ไม่ stable
- ข้อมูลที่แก้ใน container ไม่ sync กลับไปที่ image — ต้อง rebuild image เพื่อให้การแก้ไขถาวร
ส่วนที่ 15
สถานการณ์จริงในการ debug container
ตัวอย่างสามสถานการณ์ที่เกิดขึ้นบ่อยในงานจริง แสดงให้เห็นว่า logs และ exec ช่วยแก้ปัญหาได้อย่างไร
ประเด็นที่ 1
Web app เปิดไม่ได้: docker logs บอกว่า "Address already in use" → port ชน → แก้ด้วยการเปลี่ยน -p หรือหยุด process ที่ใช้ port นั้น
ประเด็นที่ 2
App ไม่เชื่อมต่อ database: docker exec เข้าไปแล้ว printenv เพื่อตรวจ DATABASE_URL → พบว่า env var ไม่ถูกต้อง → แก้ที่ docker run -e หรือ .env file
ประเด็นที่ 3
Container restart loop: docker logs --tail 30 เพื่อดู error ล่าสุดก่อน crash → พบ OOM error → เพิ่ม memory limit ด้วย --memory flag
ส่วนที่ 16
สรุปท้ายบท — จำแค่นี้ก็พอสำหรับการเริ่มต้น
docker logs และ docker exec เป็นเครื่องมือ debug คู่แรกที่นักพัฒนาทุกคนต้องรู้จัก ใช้ logs ก่อนเสมอ แล้วค่อย exec เมื่อต้องการข้อมูลเพิ่ม
- docker logs [name] = ดู output ทั้งหมดของ container ตั้งแต่เริ่มรัน
- docker logs -f [name] = ติดตาม log แบบ real-time กด Ctrl+C เพื่อหยุด
- docker logs --tail N [name] = ดูเฉพาะ N บรรทัดสุดท้าย
- docker exec -it [name] sh = เข้าไปใน container shell เพื่อตรวจสอบข้างใน
- ดู logs ก่อนเสมอ → exec เมื่อต้องการข้อมูลเพิ่ม → แก้ที่ Dockerfile/config ไม่ใช่แก้ใน container
- exec ต้องใช้กับ running container เท่านั้น / logs ใช้ได้แม้ container stopped
ส่วนที่ 17
แบบฝึกหัด 3 ข้อ — กดเพื่อดูแนวเฉลย
ลองทำแบบฝึกหัดด้านล่างด้วยตัวเองก่อน จากนั้นกดที่แต่ละข้อเพื่อดูแนวเฉลย แต่ละข้อใช้เวลาไม่เกิน 5 นาที