Building a High Availability Multi-site WordPress with Docker Swarm and MariaDB Cluster

ทความโดย ผศ.ดร.ณัฐโชติ พรหมฤทธิ์
อาจารย์ประจำภาควิชาคอมพิวเตอร์
รองผู้อำนวยการฝ่ายพัฒนาองค์กร สำนักดิจิทัลเทคโนโลยี
มหาวิทยาลัยศิลปากร

WordPress เป็น Open Source Software แบบ Content Management Systems (CMS) ยอดฮิต สำหรับการสร้างเว็บไซต์ บล็อก หรือเว็ปแอพลิเคชั่น ซึ่งปัจจุบันมี Market Share ประมาณ 65%

ข้อมูลจาก https://w3techs.com/

ด้วยความที่ WordPress เป็น CMS ที่มี Community ขนาดใหญ่ และมี Market Share สูง เราจึงมองมันเป็นตัวเลือกแรกๆ ในการนำมาบริหารจัดการ Website แบบ Multi-site ซึ่งผู้ดูแลระบบสามารถ Login เข้ามาที่หลังบ้านเพื่อ Add Site, Config Theme และ Plug-in ทั้งแบบใช้งานฟรี และต้องจ่ายเงิน ได้แบบง่าย ๆ ในที่เดียว

ในตอนเริ่มต้น ขณะที่มีการใช้งานไม่มาก เราอาจจะสามารถรัน WordPress App และ Database Server ได้บน VM เพียง 2 VM (Ubuntu Server 20.04, 2 VCPU, RAM 8GB, SSD 100GB) แต่เมื่อมีการขยายจำนวน Site มากขึ้น (อาจถึงหลักร้อย หรือหลักพัน Site) ที่แต่ละ Site มี Engagement จำนวนมาก การจะรันมันบนเพียง 2 VM จึงอาจไม่เพียงพอ

ทางเลือกหนึ่งในการแก้ปัญหา คือ การ Scale Out เพื่อกระจายโหลดทั้ง WordPress App และ Database Server ให้สามารถรองรับการใช้งานได้มากขึ้น

การ Scale Out นอกจากจะช่วยในเรื่องของการรองรับโหลดที่มีมากขึ้นแล้ว ประโยชน์ที่สำคัญประการหนึ่ง คือ จะทำให้ระบบสามารถทำงานได้เกือบตลอดเวลา (High Availability) แม้ว่าจะมี WordPress App หรือ Database Server บางตัวที่ไม่สามารถให้บริการได้

เพื่อจะทำให้ WordPress App สามารถ Online ได้เกือบตลอดเวลา เราจะใช้ความสามารถของ Docker Swarm ในการนําเอา Server จากหลาย ๆ VM มาช่วยกันทํางานโดยใช้ความพยายามในการ Config ไม่มากนัก

Container ต่างๆ ที่รันอยู่บน Swarm Cluster

โดยในการ Scale Out Database Server เราจะ Config Cluster แบบที่มีการทำ Replication ระหว่าง Master และ Slave Database ซึ่งแยกกันต่างหากจาก WordPress App ที่จะรันอยู่บน Swarm ครับ

Multi-site WordPress Architecture

ในเบื้องต้น เราจะทำ POC (Proof of Concept) Multi-site WordPress ตามสถาปัตยกรรมที่ได้ออกแบบ ดังภาพด้านล่าง

จากภาพ Traffic ด้านหน้าที่มาจาก Internet (Web Browser) จะเป็น HTTPS ซึ่งวิ่งมาที่ pocpersonal.su.ac.th จะถูก Route ให้ไปยัง WordPress Container ที่รันอยู่บน Swarm Cluster ทำให้ผู้เข้าชมสามารถเข้าถึง Content ใน Site ต่างๆ ได้จาก Replication Container ตัวหนึ่งตัวใดจากทั้งหมด 4 ตัว

ซึ่งทั้ง WordPress Theme, Plug-in, การ Config และ Content ของแต่ละ Site รวมทั้ง SSL Certificate จะมีการจัดเก็บลงใน Folder wp-data-cluster บน NFS Server, MariaDB Cluster (ที่มีการทำ Replication ระหว่าง Master และ Slave Database เพื่อให้เกิดการทำงานทดแทนกันได้เมื่อ Database Server ตัวหนึ่งตัวใดพัง) และ Folder certs บน NFS Server ครับ

อย่างไรก็ตาม ในกรณีที่ Database Server ทุกตัว Down เราจะกู้คืนมันตาม Version ที่ต้องการ ได้จาก Backup File ที่จัดเก็บไว้ใน Folder backup บน NFS Server

รวมทั้งการกู้คืน Theme, Plug-in และการ Config ต่างๆ จะถูกนำมาจาก Folder wp-backup บน NFS Server เช่นกัน

ทั้งนี้ในการ Read/Write ข้อมูลใน Database Server ของ WordPress App จะมีการใช้ Database Proxy และ Load Balancer (Maxscale Container) ที่รันบน Swarm Cluster เป็นตัวกลาง แทนที่จะ Connect กับ Master หรือ Slave Database Server โดยตรง

Config NFS และ Mount wp-data-cluster,  backup และ certs

สมมติว่าเรามี SSD Space ขนาด 500 GB ที่ /srv/PersonalWeb บน VM 1 (172.27.5.39, 192.168.10.39) เพื่อจะจัดเก็บไฟล์ต่างๆ สำหรับ WordPress App รวมทั้ง Backup Database ในแต่ละวัน เราจะต้องติดตั้ง NFS Server, Config Folder wp-data-cluster, certs และ backup ซึ่งอยู่ใน /srv/PersonalWeb และ Mount แต่ละ Folder ใน /srv/PersonalWeb กับ wp-data, certs และ backup ที่อยู่บน NFS Client ดังต่อไปนี้

.
├── backup
├── certs
└── wp-data-cluster
Folder wp-data-cluster, cert และ backup ใน /srv/PersonalWeb

Config NFS Server

  • Remote ไปที่ VM1 (172.27.5.39)
ssh [email protected]
  • เปลี่ยนสิทธิ์เข้าใช้ระบบเป็น Admin โดยใช้คำสั่ง sudo su
sudo su
  • ติดตั้ง NFS Server โดยใช้คำสั่งต่อไปนี้
apt install nfs-kernel-server
  • สร้าง Folder wp-data-cluster และกำหนดสิทธิ์การเข้าใช้งาน
mkdir -p /srv/PersonalWeb/wp-data-cluster && chown nobody:nogroup /srv/PersonalWeb/wp-data-cluster && chmod 777 /srv/PersonalWeb/wp-data-cluster
  • Config และ Restart NFS Server
echo "/srv/PersonalWeb/wp-data-cluster *(rw,sync,no_subtree_check)" >> /etc/exports
exportfs -a && systemctl restart nfs-kernel-server
  • ดูสถานะของ NFS Server
service nfs-kernel-server status
  • สร้าง Folder certs และกำหนดสิทธิ์การเข้าใช้งาน
mkdir -p /srv/PersonalWeb/certs && chown nobody:nogroup /srv/PersonalWeb/cert && chmod 777 /srv/PersonalWeb/certs
  • Config และ Restart NFS Server
echo "/srv/PersonalWeb/certs *(rw,sync,no_subtree_check)" >> /etc/exports
exportfs -a && systemctl restart nfs-kernel-server
  • Copy SSL Certificate (server.crt และ server.key) ของ pocpersonal.su.ac.th ไปยัง Folder certs
  • สร้าง Folder backup และกำหนดสิทธิ์การเข้าใช้งาน
mkdir -p /srv/PersonalWeb/backup && chown nobody:nogroup /srv/PersonalWeb/backup && chmod 777 /srv/PersonalWeb/backup
  • Config และ Restart NFS Server
echo "/srv/PersonalWeb/backup *(rw,sync,no_subtree_check)" >> /etc/exports
exportfs -a && systemctl restart nfs-kernel-server

**เราสามารถ Stop NFS Server โดยใช้คำสั่งด้านล่าง ถ้าต้องการ

service nfs-kernel-server stop

Config NFS Client และ Mount wp-data และ cert ที่ Swarm Node และ backup ที่ MariDB Master

  • Remote ไปที่ VM2 (172.27.5.43 : Swarm Node1)
ssh [email protected]
  • เปลี่ยนสิทธิ์เข้าใช้ระบบเป็น Admin โดยใช้คำสั่ง sudo su
sudo su
  • ติดตั้ง NFS Client โดยใช้คำสั่งต่อไปนี้
apt install nfs-common
  • แล้วไปที่ Root Home
cd ~
  • สร้าง Folder wp-cluster ด้วยคำสั่ง mkdir
mkdir wp-cluster
  • ไปยัง Folder wp-cluster สร้าง wp-data แล้วกำหนดสิทธิ์การเข้าถึง wp-data กับ Wordpress Coutainer ดังนี้
mkdir wp-data
chown -R 1001:1001 wp-data
  • ใน wp-cluster ให้สร้าง Folder cert
mkdir certs

โดยภายใต้ wp-cluster จะมีโครงสร้างดังต่อไปนี้

.
├── certs
└── wp-data
  • Mount Folder /srv/PersonalWeb/wp-data-cluster ใน VM1 (192.168.10.39) กับ wp-data ใน VM2
mount 192.168.10.39:/srv/PersonalWeb/wp-data-cluster wp-data
  • Mount Folder /srv/PersonalWeb/certs ใน VM1 (192.168.10.39) กับ certs ใน VM2
mount 192.168.10.39:/srv/PersonalWeb/certs certs
  • Remote ไปที่ VM3 (172.27.5.44 : Swarm Node2), VM4 (172.27.5.45 : Swarm Node3) และ VM5 (172.27.5.42 : Swarm Node4) ติดตั้ง NFS Client แล้วไปที่ Root Home สร้าง Folder wp-cluster และ Folder ย่อย (wp-data และ certs) ดังภาพด้านล่าง
.
├── certs
└── wp-data

แล้ว Mount Folder /srv/PersonalWeb/wp-data-cluster และ /srv/PersonalWeb/certs ใน VM1 (192.168.10.39) กับ wp-data และ certs

**เราสามารถ Unmount wp-data หรือ certs ได้โดยใช้คำสั่งด้านล่าง

sudo umount -f -l wp-data

sudo umount -f -l cert
  • Remote ไปที่ VM6 (172.27.5.35 : MariDB Master)
ssh [email protected]
  • เปลี่ยนสิทธิ์เข้าใช้ระบบเป็น Admin โดยใช้คำสั่ง sudo su
sudo su
  • ติดตั้ง NFS Client โดยใช้คำสั่งต่อไปนี้
apt install nfs-common
  • ไปที่ Root Home
cd ~
  • สร้าง Folder mariadb_master
mkdir mariadb_master
  • ไปที่ mariadb_master สร้าง Folder mariadb และ backup ใน mariadb
mkdir mariadb && cd mariadb && mkdir backup
  • Mount Folder /srv/PersonalWeb/backup ใน VM1 (192.168.10.39) กับ backup ใน VM6
mount 192.168.10.39:/srv/PersonalWeb/backup backup

โดยภายใต้ mariadb_master จะมีโครงสร้างดังต่อไปนี้

.
└── mariadb
    └── backup

Config MariaDB Master and Daily Backup

  • ที่ Folder mariadb_master สร้าง ไฟล์ และ Folder เพิ่มเติม ดังโครงสร้างด้านล่าง
.
├── .env
├── docker-compose.yml
├── mariadb/
│   └── backup/
└── sql/
    └── master/
        └── users.sql
  • แก้ไขไฟล์ .env ตามตัวอย่างด้านล่าง
MARIADB_ROOT_PASSWORD=xxx
  • แก้ไขไฟล์ docker-compose.yml
version: '2'
services:
    master:
        image: mariadb:10.3
        container_name: mariadb_master
        restart: always
        environment:
            - TZ=Asia/Bangkok
            - MARIADB_ROOT_PASSWORD=${MARIADB_ROOT_PASSWORD}
        volumes:
            - ./sql/master:/docker-entrypoint-initdb.d
        command: mysqld --log-bin=mariadb-bin --binlog-format=ROW --server-id=3000 --log-slave-updates
        ports:
            - "3306:3306"
    
    mysql-cron-backup:
        container_name: mysql-cron-backup-pw
        image: fradelg/mysql-cron-backup
        restart: always
        depends_on:
           - master
        volumes:
           - ./mariadb/backup:/backup
        environment:
           - TZ=Asia/Bangkok
           - MYSQL_HOST=master
           - MYSQL_USER=root
           - MYSQL_PASS=${MARIADB_ROOT_PASSWORD}
           - MAX_BACKUPS=7
           - INIT_BACKUP=1
           # Every day at 03:00
           - CRON_TIME=0 3 * * *
           # Make it small
           - GZIP_LEVEL=9
  • แก้ไขไฟล์ users.sql
RESET MASTER;

SET GLOBAL max_connections=1000;
SET GLOBAL gtid_strict_mode=ON;

CREATE USER 'maxuser'@'%' IDENTIFIED BY 'maxpwd';
GRANT ALL ON *.* TO 'maxuser'@'%' WITH GRANT OPTION;

CREATE DATABASE wordpress;
  • ไปที่ mariadb_master แล้วรัน Container ด้วย docker-compose และกลับไปที่ Terminal โดยใช้ parameter -d
docker-compose up -d
  • ดู Container ที่กำลังรันทั้งหมดที่ docker-compose.yml ดูแล
docker-compose ps

Config MariaDB Slave1

  • Remote ไปที่ VM7 (172.27.5.36 : MariDB Slave1)
ssh [email protected]
  • เปลี่ยนสิทธิ์เข้าใช้ระบบเป็น Admin โดยใช้คำสั่ง sudo su
sudo su
  • แล้วไปที่ Root Home
cd ~
  • สร้าง Project ชื่อ mariadb_slave1 โดยภายใน Folder จะมีไฟล์ และ Folder ต่างๆ ดังนี้
.
├── .env
├── docker-compose.yml
└── sql
    └── slave
        └── replication.sql
  • แก้ไขไฟล์ .env
MARIADB_ROOT_PASSWORD=xxx
  • แก้ไขไฟล์ docker-compose.yml
version: '2'
services:
    slave1:
        image: mariadb:10.3
        container_name: mariadb_slave1
        restart: always
        environment:
           - TZ=Asia/Bangkok
           - MARIADB_ROOT_PASSWORD=${MARIADB_ROOT_PASSWORD}
        volumes:
            - ./sql/slave:/docker-entrypoint-initdb.d
        command: mysqld --log-bin=mariadb-bin --binlog-format=ROW --server-id=3001 --log-slave-updates
        ports:
            - "3306:3306"
  • แก้ไขไฟล์ replication.sql
RESET MASTER;

SET GLOBAL max_connections=1000;
SET GLOBAL gtid_strict_mode=ON;

CHANGE MASTER TO MASTER_HOST='192.168.10.35', MASTER_PORT=3306, MASTER_USER='maxuser', MASTER_PASSWORD='maxpwd', MASTER_USE_GTID=slave_pos;
START SLAVE;
  • ไปที่ mariadb_slave1 แล้วรัน Container ด้วย docker-compose และกลับไปที่ Terminal โดยใช้ parameter -d
docker-compose up -d
  • ดู Container ที่กำลังรันทั้งหมดที่ docker-compose.yml ดูแล
docker-compose ps

Config MariaDB Slave2

  • Remote ไปที่ VM8 (172.27.5.37 : MariDB Slave2)
ssh [email protected]
  • เปลี่ยนสิทธิ์เข้าใช้ระบบเป็น Admin โดยใช้คำสั่ง sudo su
sudo su
  • แล้วไปที่ Root Home
cd ~
  • สร้าง Project ชื่อ mariadb_slave2 โดยภายใน Folder มีไฟล์ และ Folder ต่างๆ ดังนี้
.
├── .env
├── docker-compose.yml
└── sql
    └── slave
        └── replication.sql
  • แก้ไขไฟล์ .env
MARIADB_ROOT_PASSWORD=xxx
  • แก้ไขไฟล์ docker-compose.yml
version: '2'
services:
    slave2:
        image: mariadb:10.3
        container_name: mariadb_slave2
        restart: always
        environment:
           - TZ=Asia/Bangkok
           - MARIADB_ROOT_PASSWORD=${MARIADB_ROOT_PASSWORD}
        volumes:
            - ./sql/slave:/docker-entrypoint-initdb.d
        command: mysqld --log-bin=mariadb-bin --binlog-format=ROW --server-id=3002 --log-slave-updates
        ports:
            - "3306:3306"
  • แก้ไขไฟล์ replication.sql
RESET MASTER;

SET GLOBAL max_connections=1000;
SET GLOBAL gtid_strict_mode=ON;

CHANGE MASTER TO MASTER_HOST='192.168.10.35', MASTER_PORT=3306, MASTER_USER='maxuser', MASTER_PASSWORD='maxpwd', MASTER_USE_GTID=slave_pos;
START SLAVE;
  • ไปที่ mariadb_slave2 แล้วรัน Container ด้วย docker-compose และกลับไปที่ Terminal โดยใช้ parameter -d
docker-compose up -d
  • ดู Container ที่กำลังรันทั้งหมดที่ docker-compose.yml ดูแล
docker-compose ps
  • ทดลอง Connect ไปที่ MariaDB Slave2 ด้วย root User
mysql -h 192.168.10.37 -P 3306 -u root -ppassword
  • แสดง Database ทั้งหมดด้วยคำสั่ง show databases; แล้วพิมพ์ exit เพื่อออกมาที่ Command Line
show databases;

ทดสอบการทำ Replication ระหว่าง MariaDB Master และ MariaDB Slave

  • Remote ไปที่ MariDB Cluster Node ตัวหนึ่งตัวใดก็ได้ เช่น
ssh [email protected]
  • Connect ไปที่ MariaDB Master ด้วย root User
mysql -h 192.168.10.35 -P 3306 -u root -ppassword

แสดง Database ทั้งหมดด้วยคำสั่ง show databases;

show databases;
  • สร้าง Database ใหม่ชื่อ apple ด้วยคำสั่ง create database
create database apple;
  • แสดง Database ทั้งหมดด้วยคำสั่ง show databases; แล้วพิมพ์ exit เพื่อออกมาที่ Command Line
show databases;
  • Connect ไปที่ MariaDB Slave2 ด้วย root User
mysql -h 192.168.10.37 -P 3306 -u root -ppassword
  • แสดง Database ทั้งหมดด้วยคำสั่ง show databases;
show databases;

จากภาพด้านบน เราจะเห็น Database ชื่อ apple ใน MariaDB Slave2 ที่เกิดจากการทำ Replication กับ MariaDB Master ครับ

Config Database Proxy (Maxscale) บน Swarm Cluster

  • Remote ไปที่ VM2 (172.27.5.43 : Swarm Node1)
ssh [email protected]
  • เปลี่ยนสิทธิ์เข้าใช้ระบบเป็น Admin โดยใช้คำสั่ง sudo su
sudo su
  • แล้วไปที่ Root Home
cd ~
  • สร้าง Project ชื่อ maxscale โดยภายใน Folder มีไฟล์ และ Folder ต่างๆ ดังนี้
.
├── docker-compose.yml
└── maxscale.cnf.d/
    └── maxscale.cnf
  • แก้ไขไฟล์ docker-compose.yml
version: '2'
services:
    maxscale:
        image: mariadb/maxscale
        volumes:
            - ./maxscale.cnf.d:/etc/maxscale.cnf.d
        ports:
            - "4006:4006"  # readwrite port
            - "4008:4008"  # readonly port
            - "8989:8989"  # REST API port
  • แก้ไขไฟล์ maxscale.cnf
[server1]
type=server
address=192.168.10.35
port=3306
protocol=MariaDBBackend

[server2]
type=server
address=192.168.10.36
port=3306
protocol=MariaDBBackend

[server3]
type=server
address=192.168.10.37
port=3306
protocol=MariaDBBackend

# Monitor for the servers
# This will keep MaxScale aware of the state of the servers.
# MySQL Monitor documentation:
# https://github.com/mariadb-corporation/MaxScale/blob/2.3/Documentation/Monitors/MariaDB-Monitor.md

[MariaDB-Monitor]
type=monitor
module=mariadbmon
servers=server1,server2,server3
user=maxuser
password=maxpwd
monitor_interval=2000
auto_failover=true
auto_rejoin=true

# Service definitions
# Service Definition for a read-only service and a read/write splitting service.

# ReadConnRoute documentation:
# https://github.com/mariadb-corporation/MaxScale/blob/2.3/Documentation/Routers/ReadConnRoute.md

[Read-Only-Service]
type=service
router=readconnroute
servers=server1,server2,server3
user=maxuser
password=maxpwd
router_options=master,slave

# ReadWriteSplit documentation:
# https://github.com/mariadb-corporation/MaxScale/blob/2.3/Documentation/Routers/ReadWriteSplit.md

[Read-Write-Service]
type=service
router=readwritesplit
servers=server1,server2,server3
user=maxuser
password=maxpwd
# master_failure_mode=fail_on_write

# Listener definitions for the services
# Listeners represent the ports the services will listen on.

[Read-Only-Listener]
type=listener
service=Read-Only-Service
protocol=MySQLClient
port=4008

[Read-Write-Listener]
type=listener
service=Read-Write-Service
protocol=MySQLClient
port=4006
  • สร้าง Swarm Manager Node
docker swarm init --advertise-addr 172.27.5.43:2377
  • สร้าง Docker Config สำหรับ Maxscale โดยไปที่ Folder maxscale.cnf.d แล้วพิมพ์คำสั่งดังต่อไปนี้
cat maxscale.cnf | docker config create maxscale_config -
  • ตรวจสอบ maxscale_config ที่สร้างขึ้นมา
docker config inspect --pretty maxscale_config
  • Deploy Maxscale Container ด้วยคำสั่ง docker service create บน Swarm Cluster จาก maxscale_config
docker service create --name maxscale \
--replicas=1 \
--publish published=4006,target=4006 \
--publish published=4008,target=4008 \
--publish published=8989,target=8989 \
--config source=maxscale_config,target=/etc/maxscale.cnf \
mariadb/maxscale
  • ตรวจสอบ Maxscale Service ด้วยคำสั่ง docker service ps
docker service ps maxscale
  • ตรวจสอบ Manager Token สำหรับการ Add Manager Node
docker swarm join-token manager
  • ตรวจสอบ Worker Token สำหรับการ Add Worker Node
docker swarm join-token worker
  • Remote ไปที่ VM3 (172.27.5.44 : Swarm Node2) และ VM4 (172.27.5.45 : Swarm Node3) เปลี่ยนสิทธิ์เข้าใช้ระบบเป็น Admin โดยใช้คำสั่ง sudo su แล้ว Joint Manager Node กับ Swarm Cluster ด้วยคำสั่ง docker swarm join --token manager_token
docker swarm join --token manager_token 172.27.5.43:2377
  • Remote ไปที่ VM5 (172.27.5.42 : Swarm Node4) เปลี่ยนสิทธิ์เข้าใช้ระบบเป็น Admin โดยใช้คำสั่ง sudo su แล้ว Joint Worker Node กับ Swarm Cluster ด้วยคำสั่ง docker swarm join --token worker_token
docker swarm join --token worker_token 172.27.5.43:2377
  • กลับมาที่ VM2 (172.27.5.43 : Swarm Node1)
ssh [email protected]
  • เปลี่ยนสิทธิ์เข้าใช้ระบบเป็น Admin โดยใช้คำสั่ง sudo su
sudo su
  • ตรวจสอบสถานะ Swarm Node ทั้งหมดด้วยคำสั่ง docker node ls
docker node ls
  • Scale Maxscale Container จาก 1 Container เป็น 4 Container บน Swarm Cluster
docker service scale maxscale=4
  • ตรวจสอบสถานะ maxscale Service ด้วยคำสั่ง docker service ps
docker service ps maxscale
  • Remote ไปยัง maxscale Container ด้วยคำสั่ง docker exec -it  container_id (ดู container_id ด้วยคำสั่ง docker ps)
docker exec -it container_id /bin/bash
  • ตรวจสอบสถานะของ MariaDB Cluster ด้วยคำสั่ง maxctrl และ list servers แล้วพิมพ์ exit
maxctrl
list servers

เราจะเห็น MariaDB Cluster ทั้ง 3 Node ทั้งที่เป็น Master และ Slave

Config Wordpress App บน Swarm Cluster

  • พิมพ์ exit เพื่อออกมาที่ Command Line แล้วไปที่ root Home ด้วยคำสั่ง cd ~
cd ~
  • ไปที่ wp-cluster สร้างไฟล์ docker-compose.yml ตามโครงสร้างต่อไปนี้
.
├── certs/
├── docker-compose.yml
└── wp-data/
  • แก้ไขไฟล์ docker-compose.yml ซึ่งมีการ Config Wordpress แบบ Multisite ด้วยคำสั่ง WORDPRESS_ENABLE_MULTISITE=yes
version: '3'
services:     
  wordpress:
    image: bitnami/wordpress-nginx:latest
    ports:
      - '80:8080'
      - '443:8443'
    volumes:
      - ./wp-data:/bitnami/wordpress
      - ./certs:/certs
    environment:
      - WORDPRESS_DATABASE_HOST=192.168.10.3
      - WORDPRESS_DATABASE_PORT_NUMBER=4006
      - WORDPRESS_DATABASE_USER=maxuser
      - WORDPRESS_DATABASE_PASSWORD=maxpwd
      - WORDPRESS_DATABASE_NAME=wordpress

      - WORDPRESS_USERNAME=xxx
      - WORDPRESS_PASSWORD=xxx

      - [email protected]
      - WORDPRESS_ENABLE_MULTISITE=yes

      - WORDPRESS_MULTISITE_HOST=pocpersonal.su.ac.th
      - WORDPRESS_MULTISITE_NETWORK_TYPE=subfolder

      - WORDPRESS_SMTP_HOST=smtp.office365.com
      - WORDPRESS_SMTP_PORT=587
      - [email protected]
      - WORDPRESS_SMTP_PASSWORD=xxx
networks:
  default:
    external:
      name:
        pw_swarm
  • Deploy Wordpress Container บน Swarm Cluster ด้วยคำสั่ง docker stack deploy
docker stack deploy --compose-file docker-compose.yml pw
  • แสดง pw Stack ด้วยคำสั่ง docker stack services
docker stack services pw

จากภาพด้านบน เราจะเห็นชื่อ pw_wordpress Service ที่เกิดจากการ Deploy ด้วยคำสั่ง docker stack service pw ครับ

  • ดูสถานะของ pw_wordpress Service ด้วยคำสั่ง docker service ps pw_wordpress
docker service ps pw_wordpress
  • Scale WordPress Container จาก 1 Container เป็น 4 Container บน Swarm Cluster
docker service scale pw_wordpress=4
  • ดูสถานะของ pw_wordpress Service ด้วยคำสั่ง docker service ps pw_wordpress อีกครั้ง
docker service ps pw_wordpress
`

เราจะเห็น WordPress Container ที่ถูก Deploy กระจายอยู่บน Swarm Node ต่างๆ 4 Node

**ในการ Update Plug-in บางครั้งเราจำเป็นต้องมีการ Down และ Up Contain ใหม่ เพื่อให้ WordPress App ทำงานได้อย่างปกติ ด้วยคำสั่ง docker service update ดังตัวอย่างต่อไปนี้

docker service update --force pw_wordpress

การสร้าง Cron Jobs เพื่อ Backup wp-data-cluster

  • Remote ไปที่ VM1 (172.27.5.39)
ssh [email protected]
  • เปลี่ยนสิทธิ์เข้าใช้ระบบเป็น Admin โดยใช้คำสั่ง sudo su
sudo su
  • ไปที่ /srv/PersonalWeb/ ด้วยคำสั่ง cd /srv/PersonalWeb/
cd /srv/PersonalWeb/

สร้างไฟล์ backup.sh และ Folder wp-backup ตามโครงสร้าง ดังต่อไปนี้

.
├── backup.sh
├── backup/
├── certs/
├── wp-data-cluster/
└── wp-backup/
ไฟล์ และ Folder ต่างๆ ใน /srv/PersonalWeb
  • แก้ไขไฟล์ backup.sh เพื่อ zip Folder wp-data-cluster แล้วเก็บลงใน wp-backup รวมทั้งลบไฟล์ Backup ที่มีอายุมากกว่า 7 วัน
#!/bin/bash
DATE=$(date +%d-%m-%Y)
BACKUP_DIR="/srv/PersonalWeb/wp-backup"

tar -zcvpf $BACKUP_DIR/wp-$DATE.tar.gz /srv/PersonalWeb/wp-data-cluster

# Delete files older than 7 days #
find $BACKUP_DIR/* -mtime +7 -exec rm {} \;
  • เปลี่ยนสิทธิ์ backup.sh ให้สามารถ Execute ได้ด้วยคำสั่ง chmod +x
chmod +x backup.sh
  • เพิ่มการ Daily Backup Folder wp-data-cluster ใน Cron Jobs ด้วยคำสั่ง crontab -e
crontab -e
  • แก้ไขไฟล์ crontab ให้รันไฟล์ backup.sh เพื่อทำ Daily Backup ทุก ๆ ตี 3 ตามตัวอย่างด้านล่าง พิมพ์ Ctrl+X แล้วกด Save ออกมาที่ Command Line
* 3 * * * /srv/PersonalWeb/backup.sh >/dev/null 2>&1
  • ตรวจสอบไฟล์ crontab ด้วยคำสั่ง crontab -l
crontab -l
  • ตรวจสอบสถานะของ Cron Jobs ด้วยคำสั่ง sudo systemctl status cron.service แล้วพิมพ์ Ctrl+C เพื่อออกมาที่ Command Line
sudo systemctl status cron.service
  • ในแต่ละวัน wp-data-cluster จะถูก zip เก็บไว้ใน Folder wp-backup ดังภาพด้วยล่าง