แก้ไข Docker PHP ต่อ MySQL ไม่ได้


1. ทดสอบเชื่อมต่อฐานข้อมูลจากเซิร์ฟเวอร์เว็บ

ลองใช้สคริปต์ PHP แบบง่าย ๆ เชื่อมต่อกับฐานข้อมูลที่ host นี้ด้วย username และ password เดียวกัน เช่นสร้างไฟล์ testdb.php:

<?php
$mysqli = new mysqli('IP Database', 'ชื่อ', 'รหัสผ่าน', 'ชื่อ Database');

if ($mysqli->connect_error) {
    die('Connect Error (' . $mysqli->connect_errno . ') ' . $mysqli->connect_error);
}
echo 'Connection successful!';
$mysqli->close();
?>

อัพโหลดไฟล์นี้ไปที่เว็บโฮสต์เดียวกับ CMS

เข้า URL ของไฟล์นี้ผ่านเบราว์เซอร์

ถ้าเจอข้อความ Connection successful! แปลว่า MySQL รับการเชื่อมต่อได้

ถ้าเจอ error แปลว่ามีปัญหา

2. ตรวจสอบว่า MySQL Server อนุญาตการเชื่อมต่อจาก IP เว็บเซิร์ฟเวอร์หรือไม่

  • ฐานข้อมูลที่อยู่ที่ IP ต้องอนุญาตให้ผู้ใช้ เชื่อมต่อจาก IP ที่เว็บโฮสต์รัน CMS
  • บางครั้ง MySQL ถูกตั้งค่าให้รับแค่การเชื่อมต่อจาก localhost หรือ IP บางอย่างเท่านั้น
  • ถ้าเป็นไปได้ ล็อกอิน MySQL ด้วย root แล้วเช็คผู้ใช้:
SELECT user, host FROM mysql.user WHERE user='ชื่อผู้ใช้';

ถ้า host ไม่ได้กำหนดเป็น % (หมายถึงอนุญาตจากทุก IP) หรือ IP ของเว็บเซิร์ฟเวอร์ Joomla ต้องเพิ่มสิทธิ์:

GRANT ALL PRIVILEGES ON ชื่อdatabase.* TO 'ชื่อผู้ใช้'@'%' IDENTIFIED BY 'รหัสผ่าน';
FLUSH PRIVILEGES;

3. ตรวจสอบว่า MySQL Server ทำงานอยู่และรับการเชื่อมต่อผ่าน port 3306 หรือ port ที่ใช้อยู่

public $host = 'ip database:3307';  // ถ้าใช้พอร์ต 3307

ตัวอย่าง

ข้อความ Error นี้:

Warning: mysqli::mysqli(): (HY000/1130): Host '172.17.0.2' is not allowed to connect to this MariaDB server

หมายความว่า ฐานข้อมูล MariaDB/ MySQL ปฏิเสธการเชื่อมต่อจากไอพี 172.17.0.2 (ซึ่งน่าจะเป็น IP ของเว็บเซิร์ฟเวอร์ที่รัน PHP ของคุณ)

วิธีแก้ไข

1. อนุญาตให้ไอพี 172.17.0.2 เชื่อมต่อฐานข้อมูล

ต้องล็อกอินเข้าไปที่ฐานข้อมูล MariaDB ด้วย root หรือผู้ดูแลระบบ (ผ่าน command line หรือ phpMyAdmin ที่อนุญาต) แล้วเพิ่มสิทธิ์ให้ผู้ใช้จากไอพีนี้ หรือจากทุกไอพีก็ได้

ถ้าอนุญาตจากทุกไอพี (ไม่ปลอดภัยเท่าไหร่ แต่อำนวยความสะดวกทดสอบ):

GRANT ALL PRIVILEGES ON ชื่อฐานข้อมูล.* TO 'ชื่อผู้ใช้'@'172.17.0.2' IDENTIFIED BY 'รหัสผ่าน';
FLUSH PRIVILEGES;

หรือถ้าต้องการอนุญาตจากทุกที่:

GRANT ALL PRIVILEGES ON ชื่อฐานข้อมูล.* TO 'ชื่อผู้ใช้'@'%' IDENTIFIED BY 'รหัสผ่าน';
FLUSH PRIVILEGES;

เช็คผู้ใช้ใน MySQL/MariaDB ที่อนุญาต

SELECT user, host FROM mysql.user WHERE user='ชื่อผู้ใช้';

ถ้าผู้ใช้ ไม่มีรายการที่ host เป็น 172.17.0.2 หรือ % (ทุกที่) ต้องเพิ่มตามข้อ 1

3.รีสตาร์ท MariaDB (ถ้าจำเป็น)

sudo systemctl restart mariadb

หรือ

sudo service mysql restart

4. คำแนะนำเสริม

  • ถ้าเว็บเซิร์ฟเวอร์กับฐานข้อมูลอยู่ในเครื่องเดียวกัน หรือใช้ Docker/ VM ที่มี IP ภายในแบบนี้ (172.17.0.2) ต้องเพิ่มสิทธิ์ให้กับ IP นี้เสมอ
  • ระวังเรื่องความปลอดภัย ถ้าอนุญาตจากทุก IP (%) ควรใช้รหัสผ่านที่แข็งแรงและมี firewall ป้องกัน
,