เจอปัญหาเวลาจะ start docker โดยเฉพาะเวลาที่จะ start พวก MySQL services.

ซึ่ง Error นี้มันมาจากการที่ port ที่เราต้องการ ถูกจอง โดยที่ยังไม่มีใครใช้จริงๆซะด้วย
เท่าที่ check เป็นเพราะ hyper-V ของ Windows อยู่ๆก็อยากสำรองไว้ ไม่รู้ทำไม
ทั้งๆที่เพิ่ง restart เครื่องไม่นานด้วย
วิธีแก้ปัญหาแบบง่ายๆก็คือปิด network ของ hyper-V ทิ้งไป บังคับให้มันคาย port ที่จองไว้ออกมา
โดยเราต้องใช้ cmd ที่เป็น Administrator mode แล้วสั่ง
net stop winnat

จากนั้นค่อย start MySQL services

จากนั้นค่อย
net start winnat
ข้อมูลจาก Gemini
ซึ่งหลักๆแล้วที่จะมีปัญหานี้ก็น่าจะมีแค่ OS Windows เท่านั้น
สาเหตุส่วนใหญ่มักเกิดจาก Windows Hyper-V หรือ WSL2 ทำการจองช่วงพอร์ต (Port Exclusion Range) เอาไว้เพื่อใช้งานภายใน ทำให้แอปพลิเคชันอื่น (รวมถึง Docker) เข้าไปใช้งานพอร์ตในช่วงนั้นไม่ได้ แม้ว่าพอร์ตนั้นจะดูเหมือน “ว่าง” อยู่ก็ตามครับ
วิธีแก้ไขและตรวจสอบ มีขั้นตอนดังนี้ครับ:
1. ตรวจสอบว่าพอร์ต 3306 ถูกจองโดยระบบหรือไม่
เปิด PowerShell (Run as Administrator) แล้วใช้คำสั่งนี้เพื่อดูว่าพอร์ตที่ต้องการอยู่ใน “ช่วงที่ถูกจอง” หรือไม่:
PowerShell
netsh int ipv4 show excludedportrange protocol=tcp
หากพอร์ต 3306 อยู่ในช่วงพอร์ตที่แสดงขึ้นมา แสดงว่าคุณโดน Windows จองไปแบบ “กั๊ก” ไว้ครับ
2. วิธีการ Release พอร์ต (Quick Fix)
วิธีที่ง่ายที่สุดและมักได้ผลคือการ Restart บริการเครือข่าย เพื่อคืนค่าพอร์ตที่ถูกจองแบบสุ่ม (Dynamic ports) ครับ:
- ปิด Docker Desktop
- เปิด PowerShell (Admin) แล้วรันคำสั่ง:PowerShell
net stop winnat net start winnat - ลองรัน
docker-compose up -dอีกครั้ง
3. การแก้ปัญหาในระยะยาว (Permanent Fix)
ถ้าคุณไม่อยากเจอปัญหานี้ซ้ำซาก คุณควรกันพอร์ตที่ต้องใช้บ่อยๆ (เช่น 3306, 8080, 5432) ออกจากช่วงที่ Windows จะจองไปใช้เอง:
- ปิดการใช้งาน Hyper-V ชั่วคราว (อาจต้อง Restart เครื่อง)
- จองพอร์ตไว้ให้ตัวเอง:PowerShell
netsh int ipv4 add excludedportrange protocol=tcp startport=3306 numberofports=1 store=persistent - หลังจากนั้น Windows จะไม่เอาพอร์ต 3306 ไปใช้ในระบบสุ่มของมันอีกครับ
4. ตรวจสอบว่ามีโปรแกรมอื่นใช้พอร์ต 3306 อยู่หรือไม่
บางทีคุณอาจจะมี MySQL Server ที่ติดตั้งแบบ Installer ปกติ (Native) รันค้างอยู่ในเครื่อง:
- ใช้คำสั่งตรวจสอบว่าใครกำลังคาพอร์ตนี้อยู่:PowerShell
netstat -ano | findstr :3306 - ถ้าเจอเลข PID (ตัวเลขขวาสุด) ให้ไปเช็คใน Task Manager แล้วปิด Process นั้นทิ้งก่อนครับ
PowerShell
# รันใน PowerShell (Admin) net stop winnat docker-compose up -d net start winnat
การสั่ง net stop winnat มีผลกระทบโดยตรงต่อระบบ Network ของ Windows ครับ เพราะมันคือการหยุดการทำงานของ Windows Native Address Translation (WinNAT)
เพื่อให้คุณตัดสินใจได้ง่ายขึ้นว่าควรทำตอนไหน ผมสรุปผลกระทบที่อาจเกิดขึ้นดังนี้ครับ:
1. บริการที่ “จะใช้งานไม่ได้” ชั่วคราว (ขณะที่ Stop อยู่)
- Docker & WSL2: คอนเทนเนอร์ที่กำลังรันอยู่จะสูญเสียการเชื่อมต่อกับเครือข่ายภายนอก (Internet) และเครื่อง Host จะเข้าถึง Service ภายใน Container ไม่ได้ชั่วคราว
- Virtual Machines (Hyper-V): VM ที่ตั้งค่า Network แบบ Internal หรือ Default Switch จะออกอินเทอร์เน็ตไม่ได้
- Windows Sandbox: จะใช้งานอินเทอร์เน็ตภายใน Sandbox ไม่ได้
- Mobile Hotspot: หากคุณแชร์เน็ตจากคอมพิวเตอร์ให้เครื่องอื่นผ่าน Wi-Fi ฟีเจอร์นี้จะหยุดทำงาน
2. บริการที่ “ไม่ได้รับผลกระทบ”
- แอปพลิเคชันทั่วไป: Chrome, Line, Zoom หรือ Browser ต่างๆ ที่รันบน Windows โดยตรง (Native) ยังคงใช้งานอินเทอร์เน็ตได้ตามปกติ
- File Sharing (SMB): การแชร์ไฟล์ภายในวง LAN เดียวกันมักจะไม่ได้รับผลกระทบ
แนะนำขั้นตอนที่ปลอดภัย (Best Practice)
เนื่องจากคุณกำลังเจอปัญหาพอร์ตถูกจองโดย Windows การทำ net stop winnat ควรทำเป็น “จังหวะสั้นๆ” เท่านั้นครับ:
- สั่ง Stop:
net stop winnat(เพื่อคลายการจองพอร์ตของ Windows) - รัน Docker:
docker-compose up -d(เพื่อให้ Docker แย่งชิงพอร์ต 3306 มาจองไว้ก่อน) - สั่ง Start ทันที:
net start winnat(เพื่อให้ระบบ Network อื่นๆ กลับมาทำงานปกติ)
ข้อควรระวัง: หากคุณรันคำสั่งเหล่านี้ผ่าน Remote Desktop (RDP) หรือกำลังดาวน์โหลดไฟล์สำคัญใน WSL2 ควรทำในช่วงที่ไม่มีการรับส่งข้อมูลหนักๆ เพราะการตัดต่อ Service นี้อาจทำให้การเชื่อมต่อในส่วนของ Virtual Layer หลุดได้ครับ
โดยรวมแล้ว “ไม่อันตราย” ต่อตัวระบบปฏิบัติการครับ เป็นวิธีที่ Developer สาย Windows นิยมใช้แก้ปัญหา Port Conflict กันเป็นปกติครับ