รัน MySQL บน Docker พร้อม Persistent Data ฝักไว้ไม่หาย

ทำไมต้องรัน MySQL บน Docker?

การรัน MySQL บน Docker ทำให้ติดตั้งง่าย ไม่ต้องแก้ config ระบบ เปลี่ยนเวอร์ชันได้ง่าย และ Backup/Restore ได้อย่างเป็นระบบระเบียบ

เริ่ม MySQL Container เร็วๆ

docker run -d \
  --name mysql_server \
  -e MYSQL_ROOT_PASSWORD=rootpassword \
  -e MYSQL_DATABASE=mydb \
  -e MYSQL_USER=myuser \
  -e MYSQL_PASSWORD=mypassword \
  -p 3306:3306 \
  -v mysql_data:/var/lib/mysql \
  mysql:8.0

อธิบาย Environment Variables

Variable ความหมาย
MYSQL_ROOT_PASSWORD รหัสผ่าน root (บังคับ)
MYSQL_DATABASE สร้าง Database เริ่มต้นอัตโนมัติ
MYSQL_USER สร้าง User เพิ่มเติม
MYSQL_PASSWORD รหัสผ่านของ User ที่สร้าง
MYSQL_ALLOW_EMPTY_PASSWORD อนุญาต empty password (ไม่แนะนำ)

Docker Compose สำหรับ MySQL

version: '3.8'
services:
  mysql:
    image: mysql:8.0
    container_name: mysql_server
    restart: unless-stopped
    environment:
      MYSQL_ROOT_PASSWORD: rootpassword
      MYSQL_DATABASE: mydb
      MYSQL_USER: myuser
      MYSQL_PASSWORD: mypassword
    ports:
      - "3306:3306"
    volumes:
      - mysql_data:/var/lib/mysql
      - ./init.sql:/docker-entrypoint-initdb.d/init.sql
    command: --default-authentication-plugin=mysql_native_password
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: 10s
      timeout: 5s
      retries: 5
      start_period: 30s

volumes:
  mysql_data:

Init Script สำหรับสร้างตารางเริ่มต้น

สร้างไฟล์ init.sql เพื่อให้ MySQL รัน SQL อัตโนมัติเมื่อ Start Container ครั้งแรก:

CREATE TABLE IF NOT EXISTS users (
  id INT AUTO_INCREMENT PRIMARY KEY,
  name VARCHAR(100) NOT NULL,
  email VARCHAR(100) UNIQUE NOT NULL,
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

INSERT INTO users (name, email) VALUES 
  ('Admin', '[email protected]');

เข้าใช้ MySQL จาก Terminal

# เข้า MySQL Shell
docker exec -it mysql_server mysql -u root -p

# หรือด้วย User เฉพาะ
docker exec -it mysql_server mysql -u myuser -p mydb

Backup และ Restore

# Backup
docker exec mysql_server mysqldump -u root -prootpassword mydb > backup.sql

# Restore
docker exec -i mysql_server mysql -u root -prootpassword mydb < backup.sql

เพิ่ม phpMyAdmin

  phpmyadmin:
    image: phpmyadmin:latest
    container_name: phpmyadmin
    restart: unless-stopped
    ports:
      - "8080:80"
    environment:
      PMA_HOST: mysql
      PMA_PORT: 3306
      MYSQL_ROOT_PASSWORD: rootpassword
    depends_on:
      - mysql

MySQL 8.0 vs MariaDB

ถ้าต้องการความเข้ากันได้กับเครื่องมือโคดสเก่าหรือต้องการความเบา ลองใช้ MariaDB แทน:

  mysql:
    image: mariadb:10.11
    environment:
      MARIADB_ROOT_PASSWORD: rootpassword
      MARIADB_DATABASE: mydb
      MARIADB_USER: myuser
      MARIADB_PASSWORD: mypassword

Best Practices

  • ไม่เปิด Port 3306 สู่ภายนอกหากไม่จำเป็น
  • ใช้ Volume เสมอเพื่อเก็บข้อมูลไว้สถาวร
  • ตั้ง healthcheck เสมอหากใช้ร่วมกับ Service อื่น
  • เก็บ Credentials ไว้ในไฟล์ .env ไม่เขียน hardcode ใน compose file
  • ตั้ง resource limits เพื่อป้องกัน Memory รั่ว