Coding Gun

วิธีการติดตั้ง MySQL ด้วย docker

การใช้งาน MySql Database ด้วย Docker จะมีประโยชน์ต่างๆ ดังนี้

ซึ่งขั้นตอนของการทำงานกับ MySQL มีดังนี้

  1. เขียน Dockerfile เพื่อสร้าง MySQL container image
  2. Start MySQL Server
  3. Import SQL file เข้าไปใน Container

เขียน Dockerfile เพื่อสร้าง MySQL container image

ในการทำงานกับ MySQL container เราจำเป็นต้องใช้ Dockerfile ในการ custom MySQL image เพื่อสร้าง MySQL container และนำ data ไปใส่ไว้ข้างใน

ตัวอย่าง Dockerfile สำหรับ MySQL

FROM mysql:latest

RUN chown -R mysql:root /var/lib/mysql/

ENV MYSQL_DATABASE=sample-db
ENV MYSQL_USER=webapp
ENV MYSQL_PASSWORD=secure-password

EXPOSE 3306

MySQL Environment Variables

เราสามารถใช้ Environment Variables เพื่อกำหนด configuration เบื้องต้นของ MySQL ลองมาดูกันว่า Environment Variables ที่คุณต้องรู้จักมีอะไรบ้าง

MYSQL_ROOT_PASSWORD

เป็นตัวแปรที่กำหนด password ของ root user

MYSQL_DATABASE

เป็นตัวแปรที่ระบุชื่อของ database ที่เราจะสร้างขึ้นมาตอนที่เราสร้าง container และถ้าเรากำหนด MYSQL_USER และ MYSQL_PASSWORD mysql จะกำหนดสิทธิของ user ให้มีสิทธิทุกอย่างใน database(GRANT ALL) ที่เราได้กำหนดไว้ในตัวแปรนี้

MYSQL_USER, MYSQL_PASSWORD

ตัวแปร 2 ตัวนี้เป็นตัวแปรที่เราควรจะกำหนดไว้ เพราะเราไม่ควรใช้ root user ในการทำงาน เราควรตั้ง user และ password นี้เพื่อในการทำงาน

เราต้องกำหนดทั้ง MYSQL_USER และ MYSQL_PASSWORD mysql ถึงจะสร้าง user ใหม่

MYSQL_ALLOW_EMPTY_PASSWORD

ตัวแปรตัวนี้จะกำหนดว่าเราสามารถปล่อยให้ password ของ root เป็นค่าว่างได้หรือไม่ ถ้าเรากำหนดค่าเป็น yes password ของ root จะเป็นค่าว่าง

Password ของทุกๆ user ไม่ควรเป็นค่าว่าง(Empty) ไม่แนะนำให้กำหนดเป็น yes

MYSQL_RANDOM_ROOT_PASSWORD

ถ้าเรากำหนดตัวแปรนี้เป็น yes(หรือกำหนดเป็นค่าอะไรก็ได้ที่ไม่ใช่ค่าว่าง) mysql จะทำการ random password ของ root ขึ้นมาโดยใช้ pwgen

เราสามารถเข้าไปดู password ได้จากหน้าจอ(stdout) ตอนที่ mysql boot ขึ้นมาโดยจะเขียนว่า GENERATED ROOT PASSWORD: …..

MYSQL_ONETIME_PASSWORD

ถ้าเรากำหนดตัวแปรนี้เป็น yes(หรือกำหนดเป็นค่าอะไรก็ได้ที่ไม่ใช่ค่าว่าง) จะเป็นการกำหนดให้ password นั้นสามารถใช้ได้ครั้งเดียว นั่นคือคุณต้องเปลี่ยน password หลังจาก login ครั้งแรก

ไม่มีผลกับ user ที่เราสร้างขึ้นมาด้วย MYSQL_USER เพราะเราต้องตั้ง password เข้ามาด้วย MYSQL_PASSWORD

นี่ก็เป็นตัวแปรต่างๆ ที่เราสามารถกำหนดเข้าไปใน Dockerfile ได้

2. Start MySQL container

เมื่อได้ Dockerfile เรียบร้อยแล้วเราก็สร้าง MySQL Container ขึ้นมาด้วยตำสั่ง

$ docker build -t webapp-db .
$ docker run -d -p 3306 webapp-db

ติดต่อ MySQL

หลังจากที่เราสร้าง MySQL ขึ้นมาแล้ว เราจะสามารถ connect เข้าไปจัดการ mysql ได้ด้วยเครื่องมือต่างๆเหล่านี้

ใช้ Shell ใน MySQL container

เราสามารถใช้ shell ใน mysql container โดยทำการ connect เข้าไปตอนที่เรา run container แบบนี้

1
2
3
4
$ docker run -it \
  --rm mysql mysql \
  -h some-mysql \
  -u example-user -p

หรืออาจเป็น container ตัวอื่นที่มี mysql command และเชื่อมต่ออยู่ใน network เดียวกัน โดยเราจะเพิ่ม –network หรือ -n เข้าไปแบบนี้

1
2
3
4
5
$ docker run -it \
  --network some-network \
  --rm mysql mysql \
  -h some-mysql \
  -u example-user -p

MySQL Workbench

เราสามารถใช้งาน MySQL Workbench เพื่อ connect ไปยัง database ด้วยขั้นตอนต่างๆ ดังนี้

  1. เปิด MySQL Workbench
  2. เลือก New Connection ที่มุมล่างซ้าย
  3. สร้าง Connection ด้วยการกำหนดค่าต่างๆ ดังนี้
    • Connection Name: Mysql in docker
    • Hostname: localhost
    • Port: 3306
    • Username: webapp
    • Password: secure-password
    • Default Schema: sample-db
  4. กดปุ่ม Test Connection
  5. หลังจากนั้นสามารถเข้าไปจัดการกับ MySQL ได้ตามอัธยาศัย

PhpMyAdmin

เราสามารถใช้ PhpMyAdmin container มาช่วยในการติดต่อกับ MySQL เราสามารถ start PhpMyAdmin ขึ้นมาด้วยคำสั่ง

1
2
3
$ docker run --name phpmyadmin -d \
  --link mysql_db_server:db 
  -p 8080:80 phpmyadmin

เราอาจใช้ –network หรือ –link ในการเชื่อมต่อกับ MySQL container ทั้ง container ของ PhpMyAdmin และ MySQL ต้องอยู่ใน network เดียวกัน

หรือเราอาจใช้ docker compose ในการจัดการ network แบบในตัวอย่างนี้ก็ได้

Adminer

Adminer เป็นเครื่องมือที่ใช้ในการจัดการกับ php ที่เล็กและเบากว่า PhpMyAdmin มาก นอกจากความเบาแล้ว Adminer เรายังไม่สามารถเชื่อมต่อไปยัง MySql ที่อยู่ server อื่นๆได้ง่าย เราสามารถใช้งาน Adminer โดยใช้ docker compose ได้แบบนี้

# ไฟล์ docker-compose.yml
version: '3.1'

services:
  db:
    image: mysql
    restart: always
    environment:
      MYSQL_USER: webapp
      MYSQL_PASSWORD: secure-password

  adminer:
    image: adminer
    restart: always
    ports:
      - 8080:8080

เข้าไปใน path ที่มีไฟล์ docker-compose.yml แล้ว run คำสั่ง

$ docker-compose up -d

3. Import SQL file เข้าไปใน Container

การทำงานกับ database ที่อยู่ใน container จะมีขั้นตอนที่มากกว่าการ run application ใน container ตรงที่ database จะต้องมี script สำหรับ import ข้อมูลเข้าไปใน database เพราะเราต้องการทั้ง service ของ database และ data ทั้งคู่ ซึ่งใน MySQL ค่อนข้างง่ายเพราะเราสามารถ import ไฟล์ที่มีนามสกุล .sql เข้าไปใน container ได้เลย

ในการทำงานกับ MySQL container เราจะใส่ script ที่เราต้องการ execute ไว้ใน /docker-entrypoint-initdb.d ไฟล์ที่มีนามสกุล .sh หรือ .sql จะถูก execute ตอนที่สร้าง container และจะเรียงลำดับการ execute จากชื่อของ script นั้นตามตัวอักษร

ตัวอย่าง นี้เราจะ copy ไฟล์ data.sql เข้าไปใน container

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
FROM mysql:latest

RUN chown -R mysql:root /var/lib/mysql/

ENV MYSQL_DATABASE=sample-db
ENV MYSQL_USER=webapp
ENV MYSQL_PASSWORD=secure-password

COPY data.sql /etc/mysql/data.sql
RUN sed -i 's/OLD_DATABASE/'$MYSQL_DATABASE'/g' /etc/mysql/data.sql
RUN cp /etc/mysql/data.sql /docker-entrypoint-initdb.d

EXPOSE 3306

data.sql เป็น script เริ่มต้นสำหรับการสร้างโครงสร้างและ master data ที่จำเป็นต้องใช้ในการ run application

ในบรรทัดที่ 10 เราจะแทนที่ชื่อ SOME_DATABASE เป็นคำว่า sample-db ที่เรากำหนดไว้ใน Environment Variable ที่ชื่อว่า MYSQL_DATABASE นั่นแสดงว่าเราสามารถเปลี่ยนชื่อ database(ที่เรา dump ออกมา) เป็นชื่อใหม่ได้

ตัวอย่าง ของไฟล์ data.sql อาจได้มาจาก dump ออกมาด้วย mysqldump

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
-- MySQL dump 10.13  Distrib 8.0.26, for Linux (x86_64)
USE OLD_DATABASE

DROP TABLE IF EXISTS `Customers`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `Customers` (
  `CustomerName` varchar(255) DEFAULT NULL,

-- Dump completed on 2022-07-28  1:56:09

การจัดการกับ Volume

แน่นอนว่าการทำงานกับ container ที่มี data นั้นต้องสร้าง volume ขึ้นมาเพื่อไม่ให้ data ของเราถูกลบออกไปพร้อมกับ container ซึ่งการ mount volume เข้าไปใน mysql มีขั้นตอนดังนี้

  1. สร้าง volume ขึ้นมาสำหรับเก็บ data

    $ docker volume create datadir
    
  2. ให้ mount เข้าไปใน container ด้วย parameter -v

    1
    2
    3
    
    $ docker run --name some-mysql \
      -v datadir:/var/lib/mysql \
      -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:8.2.0
    

และไม่เพียงแต่ data เท่านั้นที่เราไม่อยากให้ถูกลบหายไป configuration เองก้เช่นเดียวกัน ลองคิดคูว่าถ้าเราต้องแก้ configuration ใหม่ทุกครั้งที่สร้าง container ใหม่เป็นเรื่องที่ไม่สนุกแน่นอน ดังนั้นเราจึงต้องนำ configuration ออกมาไว้ใน volume โดยเริ่มจาก

  1. สร้าง volume ขึ้นมาสำหรับเก็บ configuration

    $ docker volume create configdir
    
  2. ให้ mount configuration file เข้าไปใน container ด้วย parameter -v

    1
    2
    3
    4
    
    $ docker run --name some-mysql \
      -v datadir:/var/lib/mysql \
      -v configdir:/etc/mysql/conf.d \
      -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag:8.2.0
    

อ่านต่อเพิ่มเติมได้ที่

Phanupong Permpimol
Follow me