คำตอบสั้น ๆ: ติดตั้ง WordPress และ MariaDB ด้วย Docker Compose เก็บข้อมูลใน Volume แล้วเปิดใช้งานผ่าน Nginx Reverse Proxy พร้อม HTTPS แบบที่ใช้งานจริงได้
คู่มือนี้อธิบาย Docker Compose ทีละขั้นตอน พร้อมคำสั่งที่ใช้ได้จริงและปัญหาที่พบบ่อย
การรัน WordPress ด้วย Docker Compose ช่วยให้ทั้งเว็บไซต์และฐานข้อมูลถูกกำหนดไว้ในไฟล์เดียว ย้ายเครื่อง ทำซ้ำ หรืออัปเดตเวอร์ชันได้ง่าย และไม่ต้องติดตั้ง PHP หรือ MariaDB ลงบนระบบปฏิบัติการโดยตรง เหมาะกับผู้ที่ต้องการแยกเว็บไซต์หลายตัวออกจากกัน หรือทำเครื่องทดสอบที่หน้าตาเหมือนเครื่องจริง
บทความนี้สร้างระบบจาก Image ทางการสองตัว คือ wordpress (Apache + PHP) และ mariadb เก็บข้อมูลใน Named Volume ผูกพอร์ตไว้เฉพาะ localhost แล้วให้ Nginx บนเครื่องทำ Reverse Proxy พร้อม HTTPS ซึ่งเป็นรูปแบบที่ใช้งานจริงได้
สิ่งที่ต้องเตรียม
- Linux Server ที่ติดตั้ง Docker Engine และ Docker Compose Plugin แล้ว ดู ติดตั้ง Docker และ Docker Compose บน Ubuntu
- RAM อย่างน้อย 1 GB (แนะนำ 2 GB ขึ้นไป) และพื้นที่ดิสก์ว่างหลาย GB สำหรับ Image และข้อมูล
- โดเมนที่ชี้ A Record มายัง IP ของเซิร์ฟเวอร์แล้ว เช่น
example.comดู ชี้โดเมนไปยังเซิร์ฟเวอร์ด้วย A Record หรือเปลี่ยน Name Server - Nginx บนเครื่องสำหรับทำ Reverse Proxy (ติดตั้งด้วย
sudo apt install nginxบน Ubuntu)
ขั้นตอนที่ 1: สร้างโฟลเดอร์โปรเจกต์และไฟล์ .env
sudo mkdir -p /opt/wordpress
cd /opt/wordpress
เก็บรหัสผ่านไว้ในไฟล์ .env แยกจากไฟล์ Compose เพื่อไม่ให้หลุดไปกับการแชร์คอนฟิก สร้างรหัสผ่านสุ่มด้วย
openssl rand -base64 24
รันสองครั้งเพื่อได้รหัสผ่านสองชุด แล้วสร้างไฟล์
sudo nano /opt/wordpress/.env
DB_NAME=wordpress
DB_USER=wpuser
DB_PASSWORD=ใส่รหัสผ่านชุดแรก
DB_ROOT_PASSWORD=ใส่รหัสผ่านชุดที่สอง
จำกัดสิทธิ์ให้อ่านได้เฉพาะ root
sudo chmod 600 /opt/wordpress/.env
หมายเหตุ: หลีกเลี่ยงตัวอักษร
$ในรหัสผ่านที่ใส่ใน.envเพราะ Compose จะตีความเป็นตัวแปร ถ้าจำเป็นต้องใช้ ให้เขียนเป็น$$
ขั้นตอนที่ 2: เขียนไฟล์ compose.yaml
sudo nano /opt/wordpress/compose.yaml
services:
db:
image: mariadb:11.4
restart: unless-stopped
environment:
MARIADB_DATABASE: ${DB_NAME}
MARIADB_USER: ${DB_USER}
MARIADB_PASSWORD: ${DB_PASSWORD}
MARIADB_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
volumes:
- db_data:/var/lib/mysql
healthcheck:
test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
interval: 10s
timeout: 5s
retries: 5
wordpress:
image: wordpress:php8.3-apache
restart: unless-stopped
depends_on:
db:
condition: service_healthy
environment:
WORDPRESS_DB_HOST: db
WORDPRESS_DB_NAME: ${DB_NAME}
WORDPRESS_DB_USER: ${DB_USER}
WORDPRESS_DB_PASSWORD: ${DB_PASSWORD}
volumes:
- wp_data:/var/www/html
- ./uploads.ini:/usr/local/etc/php/conf.d/uploads.ini:ro
ports:
- "127.0.0.1:8080:80"
volumes:
db_data:
wp_data:
จุดสำคัญของไฟล์นี้
- ระบุเวอร์ชัน Image (
mariadb:11.4ซึ่งเป็นรุ่น LTS และwordpress:php8.3-apache) ไม่ใช้latestเพื่อไม่ให้เวอร์ชันหลักของฐานข้อมูลเปลี่ยนเองตอนดึง Image ใหม่ WORDPRESS_DB_HOST: dbใช้ชื่อ Service เป็นชื่อโฮสต์ Compose สร้าง Network ภายในให้ทั้งสอง Service คุยกันได้ โดยไม่ต้องเปิดพอร์ตฐานข้อมูลออกนอกเครื่องhealthcheckใช้สคริปต์healthcheck.shที่มากับ Image MariaDB ทำให้ WordPress เริ่มหลังฐานข้อมูลพร้อมจริง ลดปัญหา Error ตอนเปิดเครื่องครั้งแรก127.0.0.1:8080:80เปิดพอร์ตเฉพาะภายในเครื่อง เพราะพอร์ตที่ Docker เปิดจะข้าม UFW ได้ ถ้าเขียนแค่8080:80คนภายนอกจะเข้าพอร์ต 8080 ได้โดยตรง- Named Volume
db_dataและwp_dataเก็บข้อมูลไว้แม้ลบ Container
ขั้นตอนที่ 3: ปรับขนาดไฟล์อัปโหลด
ค่าเริ่มต้นของ PHP ใน Image จำกัดขนาดไฟล์อัปโหลดไว้ต่ำ สร้างไฟล์ที่ Mount ไว้ในขั้นตอนก่อน
sudo nano /opt/wordpress/uploads.ini
upload_max_filesize = 64M
post_max_size = 64M
memory_limit = 256M
max_execution_time = 120
ต้องสร้างไฟล์นี้ก่อนสั่ง up ถ้าไม่มีไฟล์ Docker จะสร้างเป็นโฟลเดอร์ชื่อ uploads.ini แทนและ PHP จะไม่อ่านค่า
ขั้นตอนที่ 4: เริ่มระบบ
cd /opt/wordpress
sudo docker compose up -d
ครั้งแรกจะดาวน์โหลด Image ใช้เวลาสักครู่ จากนั้นตรวจสถานะ
sudo docker compose ps
ควรเห็น Service db มีสถานะ Up ... (healthy) และ wordpress เป็น Up ถ้าต้องการดูรายละเอียด ใช้ sudo docker compose logs -f
ทดสอบจากตัวเครื่อง
curl -I http://127.0.0.1:8080
ผลที่ถูกต้องคือ HTTP/1.1 302 Found พร้อม Location: .../wp-admin/install.php แปลว่า WordPress ต่อฐานข้อมูลได้และรอติดตั้ง