การติดตั้งและใช้งาน PHP Apache และ MySQL ด้วย Docker Compose

Web Development

การติดตั้งและใช้งาน PHP Apache และ MySQL ด้วย Docker Compose

ในบทความนี้ผมจะพาทุกท่านมาลองติดตั้งและใช้งาน PHP Apache และ MySQL บน Docker กัน โดยจะใช้สิ่งที่เรียกว่า Docker Compose มาช่วยในการจัดการ Container อีกที

เกือบ 2 ปีที่ผ่านมา

5 min read

ถึงแม้ว่าเทคโนโลยีอย่าง Docker จะถือกำเนิดขึ้นมาและถูกใช้งานกันได้อย่างแพร่หลายแล้ว ส่วนตัวผมเองก็พึ่งจะได้ลองหัดใช้ได้เมื่อไม่กี่วันเอง ต้นเหตุก็มาจากจำเป็นที่จะต้องใช้ PHP 😏 แต่ผมไม่อยากที่จะใช้เครื่องมือช่วยจำลอง Server อย่างเช่นพวก AppServ, Xampp, WampServer, MAMP หรืออะไรก็แล้วแต่ เพราะผมรู้สึกว่าอยากจะใช้เครื่องมือสักอย่าง ที่ไม่ต้องยึดติดกับ OS มากเกินไป ถึงแม้ว่าเครื่องมือเหล่านี้จะทำงานได้ Cross Platform ได้ก็เถอะ แต่การตั้งค่าบางอย่างของแต่ละ OS แทบจะไม่เหมือนกันเลย มันจะมีเครื่องมือไหนไหมนะที่ศึกษาครั้งเดียวแล้วใช้ได้ทุก Platform และนั่นก็ทำให้ผมได้รู้จัก Docker (แบบจริงๆ จังๆ เสียที)

และในบทความนี้ผมจะพาทุกท่านมาลองติดตั้งและใช้งาน PHP Apache และ MySQL บน Docker กัน โดยจะใช้สิ่งที่เรียกว่า Docker Compose มาช่วยในการจัดการ Container อีกที

รู้จัก Docker กันก่อน

เผื่อใครยังไม่รู้จัก Docker ขอแนะนำให้ศึกษาก่อนสักนิด สามารถหาอ่านเพิ่มเติมได้จาก

หรือถ้าใครอยากอ่านฉบับภาษาไทย 🇹🇭 ก็มีมาแนะนำเหมือนกัน

Docker Compose คืออะไร

Docker Compose คือเครื่องมือที่ช่วยในการจัดการ Container โดยจะใช้ไฟล์ YAML ในการตั้งค่าและจัดการทุกอย่างใน Container ซึ่งในส่วนนี้ผมอาจจะไม่ลงรายละเอียดมาก เข้าใจง่ายๆ แค่ว่าเป็นไฟล์ที่ไว้ช่วยเราติดตั้งและตั้งค่าต่างๆ ใน Container แทนการพิมพ์คำสั่งยาวๆ เมื่อพอจะเข้าใจบ้างแล้ว ก็ไปเริ่มติดตั้งกันเลย

ติดตั้ง Docker

โดย Docker จะรองรับทั้ง macOS, Windows และ Linux

หลังจากติดตั้งเสร็จ เปิด Terminal แล้วพิมพ์คำสั่งดังนี้

docker version

จะได้ผลลัพธ์ดังนี้ ถือว่าเราได้ติดตั้ง Docker แล้ว

Client:
 Cloud integration: v1.0.29
 Version:           20.10.21
 API version:       1.41
 Go version:        go1.18.7
 Git commit:        baeda1f
 Built:             Tue Oct 25 18:01:18 2022
 OS/Arch:           darwin/arm64
 Context:           default
 Experimental:      true
 
Server: Docker Desktop 4.15.0 (93002)
 Engine:
  Version:          20.10.21
  API version:      1.41 (minimum version 1.12)
  Go version:       go1.18.7
  Git commit:       3056208
  Built:            Tue Oct 25 17:59:41 2022
  OS/Arch:          linux/arm64
  Experimental:     false
 containerd:
  Version:          1.6.10
  GitCommit:        770bd0108c32f3fb5c73ae1264f7e503fe7b2661
 runc:
  Version:          1.1.4
  GitCommit:        v1.1.4-0-g5fd4c4d
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0

สร้าง folder สำหรับ project

เมื่อติดตั้ง Docker แล้ว ก็สร้าง folder สำหรับ project ขึ้นมา โดยในที่นี้ผมจะสร้าง folder และตั้งชื่อว่า docker-apache-php-mysql และเข้าไปใน folder นั้น

สร้าง Docker Compose

เมื่อได้ folder สำหรับเก็บ project แล้ว ก็จะมาสร้างไฟล์ docker compose กัน โดยเจ้า docker-compose เนี่ยจะเป็นไฟล์ที่เราจะใช้ในการตั้งค่า Container ที่เราต้องการใช้งาน โดยไฟล์ docker-compose จะสร้างได้แบบนี้ docker-compose.yml โดยนามสกุลจะเป็น .yml หรือ .yaml ก็ได้

Create docker-compose.yml file
Create docker-compose.yml file

รายละเอียดเพิ่มเติมเติมเกี่ยวกับ Docker Compose

ในการตั้งค่า docker-compose นั้น คุณจะต้องเลือก Docker version ที่คุณต้องการใช้ และ services และ containers ที่คุณต้องการใช้งาน

version: "3.8"
services:
  php-apache-environment:
    container_name:

ติตตั้ง PHP และ Apache

ในการติดตั้ง PHP Apache ใน container นั้น คุณจะต้องระบุ environments ดังนี้

  • Container Name : คือชื่อของ Container นั้นจะเป็นชื่อที่คุณต้องการให้ตั้งชื่อให้กับ Container นั้น อย่างเช่น container_name: php-apache
  • Container Image : คือ image ที่คุณต้องการใช้งาน ในที่นี้เราจะใช้ image ที่ชื่อว่า php:8.2-apache ซึ่งเป็น image ที่เป็น official image ของ PHP และเป็น image ที่มี Apache อยู่ในตัวเลย
  • Volume : คือ สิ่งที่จะตั้งค่าให้กับ directory ของ source code ของเรา ซึ่งถ้าเรามีไฟล์ .php ไฟล์นั้นก็จะต้องอยู่ใน directory นี้ด้วย เช่น แบบนี้
volumes:
  - ./php/src:/var/www/html/
  • หมายเลข Port : คือ port ที่เราต้องการจะ map กับ port ของ container นั้น โดยในที่นี้เราจะ map port ที่ 8080 ของเครื่องเรา (local) กับ port ที่ 80 ของ container นั้น ซึ่งเป็น port ที่ Apache ใช้งาน ดังนั้นเราจะตั้งค่าให้เป็นแบบนี้
ports:
  - "8080:80"

ซึ่งหมายความว่าเรากำลังตั้งค่า Apache server ให้ทำงานที่ port 80 และ map มาที่ port 8080 บนเครื่องเรา พอเวลาเรียกใช้งาน เราก็จะเข้าผ่าน port 8080

เราก็จะได้ docker-compose.yml หน้าตาแบบนี้

version: "3.8"
services:
  php-apache-environment:
    container_name: php-apache
    image: php:8.2-apache
    volumes:
      - ./php/src:/var/www/html/
    ports:
      - 8000:80

กลับมาที่ Terminal ทดลองรัน Container ด้วยคำสั่ง docker-compose up

run docker-compose up
run docker-compose up

เปิด Browser แล้วเข้าไปที่ http://localhost:8000 แล้วเราก็จะเห็นว่า ขึ้น 403 Forbidden แล้ว ซึ่งเป็นปกติ เพราะเรายังไม่ได้ทำการเขียนไฟล์ index.php ใน directory ของเรา

403 Forbidden
403 Forbidden

ทดลองเขียนอะไรลงไปในไฟล์ index.php สักหน่อย

index.php
index.php

แล้วลองเข้าไปดูที่ http://localhost:8000 อีกครั้ง

index.php
index.php

ติดตั้ง MySQL ใน Container

เมื่อมี PHP แล้วจะขาด MySQL ไปได้อย่างไรกัน ดังนั้นเราจะมาสร้าง Container เพื่อใช้งาน MySQL กัน มาที่ไฟล์ docker-compose.yml โดยเราจะสร้าง Service ขึ้นมาอีก 1 ตัว ให้ชื่อว่า db และกำหนดค่าต่างๆ จะมีรายละเอียดดังนี้

  • Container Name : ชื่อของ Container ผมจะตั้งชื่อว่า db
  • Image : ชื่อของ Image ที่เราต้องการใช้งาน โดยจะใช้ mysql
  • restart : ผมตั้งเป็น always เพื่อกำหนดให้ Service นี้มีการ restart ใหม่อัตโนมัติเมื่อเกิดการเปลี่ยนแปลงใดๆ บน Container นี้
  • Environment : กำหนดค่าต่างๆ ของ MySQL ที่เราต้องการใช้งาน โดยจะมีรายละเอียดดังนี้
    • MYSQL_ROOT_PASSWORD : กำหนดรหัสผ่านของ root user ของ MySQL
    • MYSQL_DATABASE : กำหนดชื่อของ Database ที่เราต้องการใช้งาน
    • MYSQL_USER : กำหนดชื่อของ User ที่เราต้องการใช้งาน
    • MYSQL_PASSWORD : กำหนดรหัสผ่านของ User ที่เราต้องการใช้งาน
  • Ports : ก็เหมือนตอนที่เราตั้งค่า Port ของ PHP แต่เราจะใช้ Port 3306 แทน ซึ่งเป็น Port ที่ MySQL ใช้งาน
db:
  container_name: db
  image: mysql
  restart: always
  environment:
    MYSQL_ROOT_PASSWORD: MYSQL_ROOT_PASSWORD
    MYSQL_DATABASE: MY_DATABASE
    MYSQL_USER: MYSQL_USER
    MYSQL_PASSWORD: MYSQL_PASSWORD
  ports:
    - "9906:3306"

เราต้องการเพิ่มเครื่องมือสำหรับ MySQL ภายใน Container ของ PHP เพื่อให้สามารถทำงานร่วมกันได้ ซึ่งเครื่องมือที่เราต้องการนั้นคือ mysqli ซึ่งเป็น PHP extension ที่ใช้ในการเชื่อมต่อกับ MySQL

กลับไปที่โฟลเดอร์ /php ของโปรเจคของเรา และสร้างไฟล์ Dockerfile ขึ้นมา และเพิ่มค่าต่างๆ ดังนี้

FROM php:8.0-apache
RUN docker-php-ext-install mysqli && docker-php-ext-enable mysqli
RUN apt-get update && apt-get upgrade -y
PHP Dockerfile
PHP Dockerfile

ที่นี่ เราจะได้สร้าง Image ของ PHP Apache และ Environment ที่จะติดตั้ง mysqli ซึ่งเป็น PHP extension ที่จะเชื่อมต่อ PHP Apache กับ MySQL server

ต่อมาเราต้องสร้างอิมเมจที่กำหนดเองนี้ภายใน Service php-apache-environment ในไฟล์ docker-compose.yml PHP Apache ยังขึ้นอยู่กับบริการ db เพื่อเชื่อมต่อกับ MySQL เราจำเป็นต้องกำหนดค่าโดยระบุการพึ่งพาอาศัย: สภาพแวดล้อม

version: "3.8"
services:
  php-apache-environment:
    container_name: php-apache
    build:
      context: ./php
      dockerfile: Dockerfile
    depends_on:
      - db
    volumes:
      - ./php/src:/var/www/html/
    ports:
      - 8000:80
  db:
    container_name: db
    image: mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: MYSQL_ROOT_PASSWORD
      MYSQL_DATABASE: MYSQL_DATABASE
      MYSQL_USER: MYSQL_USER
      MYSQL_PASSWORD: MYSQL_PASSWORD
    ports:
      - "9906:3306"

เสร็จแล้วรันคำสั่ง docker-compose up แล้วรอสักครู่ จะเห็นว่าเราได้สร้าง Container ขึ้นมา 2 ตัว คือ db และ php-apache-environment

docker-compose up
docker-compose up

หรือจะดูที่ Docker Desktop ก็ได้

Docker Desktop
Docker Desktop

จากเปิดไฟล์ index.php แล้วทดสอบเขียนคำสั่ง PHP ที่ใช้ mysqli เพื่อเชื่อมต่อกับ MySQL server ที่เราสร้างไว้

<?php
$host = 'db';
$user = 'MYSQL_USER';
$pass = 'MYSQL_PASSWORD';
 
$conn = new mysqli($host, $user, $pass);
if ($conn->connect_error) {
    die("Connection failed: " . $conn->connect_error);
} else {
    echo "Connected to MySQL server successfully!";
}
?>

เมื่อเราเปิดเว็บไซต์ที่ http://localhost:8000 จะเห็นว่าเราได้เชื่อมต่อกับ MySQL server ได้เรียบร้อยแล้ว

Connected to MySQL server successfully!
Connected to MySQL server successfully!

ติดตั้ง PHPMyAdmin

PHPMyAdmin ก็เป็นเครื่องมือที่เป็น GUI สำหรับการจัดการฐานข้อมูล MySQL ซึ่งก็เป็น Service อีกตัวที่เราจะเพิ่มเข้าไปใน docker-compose.yml โดยจะมีรายละเอียดการตั้งค่าดังนี้

  • image : เราจะใช้ image ของ phpmyadmin/phpmyadmin
  • ports : จะใช้ port 8080 ของเครื่องเรา
  • restart : ตั้งค่าให้ restart ทุกครั้งเมื่อมีการเปลี่ยนแปลง
  • environment
    • PMA_HOST: ตั้งค่าให้เชื่อมต่อกับ Service ชื่อ db
  • depends_on : ตั้งค่าให้รอการสร้าง Service ชื่อ db ก่อน
phpmyadmin:
  image: phpmyadmin/phpmyadmin
  ports:
    - "8080:80"
  restart: always
  environment:
    PMA_HOST: db
  depends_on:
    - db

จากนั้นก็รันคำสั่ง docker-compose up แล้วเปิดเว็บไซต์ที่ http://localhost:8080 จะเห็นว่าเราได้เข้าสู่หน้า Login ของ PHPMyAdmin แล้ว

PHPMyAdmin Login Page
PHPMyAdmin Login Page

โดย default ของ PHPMyAdmin จะใช้ username และ password ของ MySQL ซึ่งในที่นี้คือ root และ MYSQL_ROOT_PASSWORD ที่เราตั้งไว้

PHPMyAdmin Login Page
PHPMyAdmin Login Page

ลองนำข้อมูลเข้า MySQL

สร้าง database และ table และเพิ่มข้อมูลลงไปใน table นั้น ๆ จากนั้นเลือก database ที่เราสร้างไว้ แล้วให้เราเขียนคำสั่ง SQL ดังนี้

drop table if exists `USERS`;
create table USERS (
	id INT,
	first_name VARCHAR(50),
	last_name VARCHAR(50),
	gender VARCHAR(50)
);
insert into USERS (id, first_name, last_name, gender) values (1, 'Guenevere', 'Gresley', 'Female');
insert into USERS (id, first_name, last_name, gender) values (2, 'Torie', 'Blick', 'Female');
insert into USERS (id, first_name, last_name, gender) values (3, 'Waverley', 'Treagust', 'Male');
insert into USERS (id, first_name, last_name, gender) values (4, 'Kippy', 'Evershed', 'Male');
insert into USERS (id, first_name, last_name, gender) values (5, 'Vevay', 'Tolson', 'Female');

โดยเข้าไปที่ PHPMyAdmin แล้วเลือก database ที่เราสร้างไว้ แล้วกดปุ่ม SQL ที่ด้านบนขวา จากนั้นก็ใส่คำสั่ง SQL ที่เราเขียนไว้ลงไป แล้วกดปุ่ม Go

Insert SQL
Insert SQL

กด OK เพื่อยืนยันการนำข้อมูลเข้า

Confirm Insert SQL
Confirm Insert SQL

จะเห็นว่าข้อมูลถูกนำเข้าเรียบร้อยแล้ว

Insert Success
Insert Success
Show Data
Show Data

ทีนี้เราเอาข้อมูลมาแสดงที่หน้าเว็บกันหน่อย กลับมาที่ไฟล์ index.php โดยจะเพิ่มโค้ดดังนี้

<?php
$host = 'db';
$user = 'MYSQL_USER';
$pass = 'MYSQL_PASSWORD';
$db = 'MYSQL_DATABASE';
 
$conn = new mysqli($host, $user, $pass, $db);
if ($conn->connect_error) {
    die("Connection failed: " . $conn->connect_error);
} else {
    echo "Connected to MySQL server successfully!";
}
 
$sql = 'SELECT * FROM USERS';
 
if ($result = $conn->query($sql)) {
    while ($data = $result->fetch_object()) {
        $users[] = $data;
    }
}
 
echo "<ul>";
foreach ($users as $user) {
    echo "<li>";
    echo $user->first_name . " " . $user->last_name . " " . $user->gender;
    echo "</li>";
}
echo "</ul>";
 

Refresh หน้า http://localhost:8000/ เพื่อดูผลลัพธ์

Show Data
Show Data

ตอนนี้เราได้ทำการเชื่อมต่อ MySQL กับ PHP แล้ว และเราสามารถเอาข้อมูลจาก MySQL มาแสดงผลบนเว็บไซต์ได้แล้ว

Conclusion

เป็นยังไงบ้างครับ สำหรับการใช้ Docker Compose เพื่อสร้าง Container สำหรับ PHP และ MySQL คงไม่ถอดใจไปก่อนนะครับ 🤭 ซึ่งแน่นอนว่าในบทความนี้ จะมาแนะนำขั้นตอนการสร้าง Container เพื่อใช้งาน PHP กับ MySQL เท่านั้น อาจจะไม่ได้ลงในรายเอียดเกี่ยวกับ PHP หรือ MySQL มากนัก หรือแม้แต่รายละเอียดของ Docker เอง ก็อาจจะข้ามๆ หรือไม่ได้อธิบายบางจุดไปบ้าง ก็หวังว่าบทความนี้จะเป็นประโยชน์ให้กับคนที่อยากเริ่มต้นใช้ Docker และ PHP กับ MySQL นะครับ สำหรับบทความนี้ขอจบไว้เพียงเท่านี้ สวัสดีครับ.

Tags:

PHP Docker