PlusMagi's Blog By Pitt Phunsanit Docker,MariaDB การสร้างและจัดการ MariaDB Container แบบ Sidecar (ใช้งานร่วมกับ Network กลาง magi)

การสร้างและจัดการ MariaDB Container แบบ Sidecar (ใช้งานร่วมกับ Network กลาง magi)

ในสถาปัตยกรรมระบบแบบแยกส่วน (Decoupled Architecture) การแยกเซอร์วิสฐานข้อมูลออกมาทำงานเป็นอิสระจากเว็บแอปพลิเคชัน (เช่น แยก WordPress ออกจาก MariaDB) ช่วยให้การบริหารจัดการข้อมูล การสำรองข้อมูล และการแชร์ฐานข้อมูลร่วมกันระหว่างหลายโปรเจกต์ทำได้อย่างมีประสิทธิภาพ บทความนี้สรุปแนวทางการสร้าง MariaDB 13 Container เป็นบริการฐานข้อมูลกลาง โดยเชื่อมต่อผ่านเครือข่าย Docker Network ชื่อ magi และซิงก์ค่าคอนฟิกร่วมกับไฟล์ .env ส่วนกลาง


1. โครงสร้างโปรเจกต์ (Project Tree)

โครงสร้างไดเรกทอรีที่ได้รับการจัดระเบียบให้ถูกต้องที่ /Users/common/Docker/ จะคงเหลือเฉพาะไฟล์และโฟลเดอร์ที่จำเป็นต่อการทำงานจริง ดังนี้:

/Users/common/Docker/
├── .env                  <-- ไฟล์ตัวแปรสภาพแวดล้อมส่วนกลาง
└── db_mariadb_13/
    ├── build.sh          <-- สคริปต์เตรียมไดเรกทอรีและสร้าง init security script
    ├── docker-compose.yml
    ├── init-scripts/     <-- ไดเรกทอรี Mount ไปยัง /docker-entrypoint-initdb.d
    │   └── 01-init-security.sql
    └── data/             <-- Bind Mount เก็บข้อมูลดิบของ MariaDB (InnoDB & System Tables)

2. การกำหนดค่าไฟล์ .env ส่วนกลาง

ไฟล์ /Users/common/Docker/.env ใช้เป็นศูนย์กลางควบคุม Credential เพื่อให้ทุก Stack ในเครื่องอ้างอิงข้อมูลชุดเดียวกัน:

# ==========================================
# MariaDB & Application Credentials
# ==========================================
DB_ROOT_PASSWORD=your_secure_root_password
DB_DATABASE=WP71_DEV
WP_DB_NAME=WP71_DEV
DB_USER=app_user
DB_PASSWORD=your_app_password

3. การจัดเตรียมไฟล์ docker-compose.yml

ที่ตำแหน่ง db_mariadb_13/docker-compose.yml กำหนดให้ใช้งานอิมเมจ mariadb:13.0.2 พร้อมทั้งเชื่อมต่อเครือข่าย magi และแมปโฟลเดอร์ init-scripts เข้ากับ /docker-entrypoint-initdb.d แบบ Read-Only เพื่อให้รันคำสั่ง SQL ตอนเริ่มระบบรอบแรกสุด:

services:
  mariadb:
    image: mariadb:13.0.2
    container_name: db_mariadb_13
    restart: always
    env_file:
      - ../.env
    environment:
      MYSQL_ROOT_PASSWORD: '${DB_ROOT_PASSWORD}'
      MYSQL_DATABASE: '${WP_DB_NAME}'      # ให้ระบบสร้าง DB และผูกสิทธิ์ให้ User อัตโนมัติ
      MYSQL_USER: '${DB_USER}'
      MYSQL_PASSWORD: '${DB_PASSWORD}'
    ports:
      - "3306:3306"
    volumes:
      - ./data:/var/lib/mysql
      - ./init-scripts:/docker-entrypoint-initdb.d:ro
    networks:
      - magi  # ใช้เครือข่ายวงเดียวกันกับ PHP App เพื่อให้ติดต่อกันได้โดยตรง

networks:
  magi:
    external: true  # ดึงวงเน็ตเวิร์กกลาง 'magi' มาใช้งานร่วมกัน

4. สคริปต์ความปลอดภัยเริ่มต้น (init-scripts/01-init-security.sql)

ไฟล์นี้ทำหน้าที่กำหนดสิทธิ์และโครงสร้างผู้ใช้เริ่มต้น โดยจะสร้างผู้ดูแลระบบตัวแทน (เช่น db_admin) พร้อมสิทธิ์เทียบเท่า root และสร้างฐานข้อมูลพร้อมผู้ใช้สำหรับแอปพลิเคชัน:

-- 1. สร้าง Admin User ตัวแทน (db_admin) พร้อมสิทธิ์เทียบเท่า root
CREATE USER IF NOT EXISTS 'db_admin'@'%' IDENTIFIED BY 'your_secure_root_password';
GRANT ALL PRIVILEGES ON *.* TO 'db_admin'@'%' WITH GRANT OPTION;

-- 2. สร้าง Database และ User สำหรับแอปพลิเคชัน
CREATE DATABASE IF NOT EXISTS WP71_DEV CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER IF NOT EXISTS 'app_user'@'%' IDENTIFIED BY 'your_app_password';
GRANT ALL PRIVILEGES ON WP71_DEV.* TO 'app_user'@'%';

FLUSH PRIVILEGES;

5. สคริปต์อัตโนมัติเตรียมระบบ (build.sh)

สคริปต์ build.sh จะอ่านตัวแปรสภาพแวดล้อมจาก .env แล้วสร้างไฟล์ 01-init-security.sql ลงใน init-scripts/ ให้โดยอัตโนมัติ พร้อมตรวจความพร้อมของสิทธิ์ไดเรกทอรีและไฟล์ Compose:

#!/usr/bin/env bash
set -eo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
BASE_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)"
cd "${SCRIPT_DIR}"

DATA_DIR="${SCRIPT_DIR}/data"
INIT_DIR="${SCRIPT_DIR}/init-scripts"

echo "==> [1/4] Preparing directories..."
mkdir -p "${DATA_DIR}" "${INIT_DIR}"
chmod 755 "${DATA_DIR}" "${INIT_DIR}"

ENV_FILE="${BASE_DIR}/.env"
if [ -f "${ENV_FILE}" ]; then
    set -a
    source "${ENV_FILE}"
    set +a
    echo "==> [2/4] Loaded environment variables from central .env"
else
    echo "Error: Central .env file not found at ${ENV_FILE}" >&2
    exit 1
fi

echo "==> [3/4] Generating initialization security script..."
cat << EOF > "${INIT_DIR}/01-init-security.sql"
-- 1. สร้าง Admin User ตัวแทน (db_admin) พร้อมสิทธิ์เทียบเท่า root
CREATE USER IF NOT EXISTS 'db_admin'@'%' IDENTIFIED BY '${DB_ROOT_PASSWORD}';
GRANT ALL PRIVILEGES ON *.* TO 'db_admin'@'%' WITH GRANT OPTION;

-- 2. สร้าง Database และ User สำหรับแอปพลิเคชัน
CREATE DATABASE IF NOT EXISTS ${DB_DATABASE} CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER IF NOT EXISTS '${DB_USER}'@'%' IDENTIFIED BY '${DB_PASSWORD}';
GRANT ALL PRIVILEGES ON ${DB_DATABASE}.* TO '${DB_USER}'@'%';

FLUSH PRIVILEGES;
EOF

echo "==> [4/4] Checking docker-compose.yml configuration..."
if [ ! -f "${SCRIPT_DIR}/docker-compose.yml" ]; then
    echo "Error: docker-compose.yml not found in ${SCRIPT_DIR}" >&2
    exit 1
fi

echo "==> MariaDB build preparation completed successfully!"

6. การอ้างอิงโฮสต์ฐานข้อมูลฝั่งแอปพลิเคชัน

เมื่อโปรเจกต์ภายนอก (เช่น WordPress Stack) เข้าร่วมเครือข่าย magi จะสามารถเรียกใช้งานฐานข้อมูล MariaDB ผ่านชื่อคอนเทนเนอร์ได้โดยตรง:

DB_HOST=db_mariadb_13
DB_NAME=WP71_DEV
DB_USER=app_user
DB_PASSWORD=your_app_password

จุดเด่นของการออกแบบสถาปัตยกรรมนี้

  • External Network (magi): แยกเครือข่ายกลางเป็นอิสระ ช่วยให้คอนเทนเนอร์ในแต่ละโปรเจกต์ติดต่อกับฐานข้อมูลผ่านชื่อโฮสต์ db_mariadb_13 ได้ทันที
  • Automated Entrypoint Init: ใช้กลไกของไดเรกทอรี /docker-entrypoint-initdb.d รันการสร้างสิทธิ์และผู้ใช้แทนการรันคำสั่งแมนนวล
  • Local Bind Mount (./data): จัดเก็บไฟล์ข้อมูลฐานข้อมูลจริงไว้บนเครื่องโฮสต์ ทำให้ตรวจสอบและสำรองข้อมูลได้สะดวก
  • Centralized Environment (.env): รวมศูนย์ Credential ไว้ที่จุดเดียว ป้องกันปัญหาค่าคอนฟิกไม่ตรงกันระหว่างสแต็ก

ขั้นตอนการรันระบบ

  1. สร้าง Docker Network magi หากยังไม่ได้สร้างในเครื่อง:
    docker network create magi
  2. ลบไฟล์ SQL ที่ตกค้างหรือไม่ได้ถูกเรียกใช้งาน (ถ้ามี):
    rm -f /Users/common/Docker/db_mariadb_13/init.sql /Users/common/Docker/db_mariadb_13/init-scripts/init.sql
  3. เข้าไปยังโฟลเดอร์ MariaDB และสั่งรันสคริปต์เตรียมระบบ:
    cd /Users/common/Docker/db_mariadb_13 && ./build.sh
  4. สั่งเริ่มการทำงานของคอนเทนเนอร์:
    docker compose up -d
  5. ตรวจสอบสถานะคอนเทนเนอร์:
    docker ps
    คอนเทนเนอร์ db_mariadb_13 จะเริ่มทำงานและพร้อมให้บริการแก่แอปพลิเคชันทุกตัวในเครือข่าย magi ทันที

อ่านเพิ่มเติม

Tags: