วิธีการติดตั้ง MySQL ด้วย docker
การใช้งาน MySql Database ด้วย Docker จะมีประโยชน์ต่างๆ ดังนี้
- เราสร้าง development environment ขึ่้นมาได้อย่างรวดเร็ว
- สามารถนำไป deploy บน server ได้ง่ายขึ้น
- เปลี่ยน version ของ database ได้ง่าย
- ลบ และสร้างใหม่ได้อย่างรวดเร็ว
- สามารถขยายตัวได้ง่าย(scalability)
ซึ่งขั้นตอนของการทำงานกับ MySQL มีดังนี้
- เขียน Dockerfile เพื่อสร้าง MySQL container image
- Start MySQL Server
- 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 แบบนี้
|
|
หรืออาจเป็น container ตัวอื่นที่มี mysql command และเชื่อมต่ออยู่ใน network เดียวกัน โดยเราจะเพิ่ม –network หรือ -n เข้าไปแบบนี้
|
|
MySQL Workbench
เราสามารถใช้งาน MySQL Workbench เพื่อ connect ไปยัง database ด้วยขั้นตอนต่างๆ ดังนี้
- เปิด MySQL Workbench
- เลือก New Connection ที่มุมล่างซ้าย
- สร้าง Connection ด้วยการกำหนดค่าต่างๆ ดังนี้
- Connection Name: Mysql in docker
- Hostname: localhost
- Port: 3306
- Username: webapp
- Password: secure-password
- Default Schema: sample-db
- กดปุ่ม Test Connection
- หลังจากนั้นสามารถเข้าไปจัดการกับ MySQL ได้ตามอัธยาศัย
PhpMyAdmin
เราสามารถใช้ PhpMyAdmin container มาช่วยในการติดต่อกับ MySQL เราสามารถ start 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
|
|
data.sql เป็น script เริ่มต้นสำหรับการสร้างโครงสร้างและ master data ที่จำเป็นต้องใช้ในการ run application
ในบรรทัดที่ 10 เราจะแทนที่ชื่อ SOME_DATABASE เป็นคำว่า sample-db ที่เรากำหนดไว้ใน Environment Variable ที่ชื่อว่า MYSQL_DATABASE นั่นแสดงว่าเราสามารถเปลี่ยนชื่อ database(ที่เรา dump ออกมา) เป็นชื่อใหม่ได้
ตัวอย่าง ของไฟล์ data.sql อาจได้มาจาก dump ออกมาด้วย mysqldump
|
|
การจัดการกับ Volume
แน่นอนว่าการทำงานกับ container ที่มี data นั้นต้องสร้าง volume ขึ้นมาเพื่อไม่ให้ data ของเราถูกลบออกไปพร้อมกับ container ซึ่งการ mount volume เข้าไปใน mysql มีขั้นตอนดังนี้
-
สร้าง volume ขึ้นมาสำหรับเก็บ data
$ docker volume create datadir
-
ให้ 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 โดยเริ่มจาก
-
สร้าง volume ขึ้นมาสำหรับเก็บ configuration
$ docker volume create configdir
-
ให้ 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