loading...

ทำ Database เริ่มต้นอย่างง่ายกับ MariaDB Docker

mrchoke profile image MrChoke Originally published at Medium on ・5 min read

สำหรับ Dev ที่ทำการเขียน app แล้วมี database เริ่มต้นสำหรับการทำงาน เมื่อมาใช้ docker แรกๆ ก็จะลำบากหน่อยที่ต้องทำการสร้าง database สร้าง table เมื่อมีการ create docker container ซึ่งปกติผมก็ทำ manual ตลอด เลยบันทึกไว้สักหน่อย สำหรับมือใหม่จะได้ dev กันง่ายๆ

เอาแบบฉบับรวบรัดไม่อ้อมค้อม git pull ตัวอย่างมาศึกษาต่อยอดกันได้เลย

mrchoke/mariadb_docker_example

git pull [https://github.com/mrchoke/mariadb\_docker\_example](https://github.com/mrchoke/mariadb_docker_example)

เข้าไปใน mariadb_docker_example

cd mariadb\_docker\_example

ในนี้จะประกอบด้วย

  • docker-compose.xml
version: '2'
services:
 mariadb:
 image: mariadb:10
 hostname: mariadb
 volumes:
 - ./mariadb:/var/lib/mysql
 - ./schema:/docker-entrypoint-initdb.d
 ports:
 - 3306:3306
 environment:
 - TZ=Asia/Bangkok
 - MYSQL\_ROOT\_PASSWORD=123456
 - "MYSQL\_ROOT\_HOST=%"

ผม mount สอง volumes เข้าไป คือ data ของ mariadb และ อีกอันคือ schema อันนี้แหละที่ใช้ในการเริ่มต้นสร้าง database หรือ table ตามที่เราตั้งเอาไว้ และ ยังสามารถ seed ข้อมูลเข้าไปได้ด้วย

ส่วนของ ports ถ้าเราทำงานกับ container อื่นไม่จำเป็นต้อง bind ออกมาข้างนอกก็ได้ แต่ตัวอย่างนี้ผม run เดี่ยวๆ อาจจะเรียกจากข้างนอกเพื่อทดสอบเลย bind ออกมาด้วย

ส่วน environment ตรงนี้เราสามารถตั้งค่าต่างๆ เช่น Password , Host และอื่นๆ สามารถดูได้จาก

mariadb - Docker Hub

ซึ่งถ้าให้ docker container อื่นเข้ามาใช้ database ได้เราจำเป็นต้องตั้ง

- "MYSQL\_ROOT\_HOST=%"

หรือจะระบุชื่อ container หรือ ip container ไปก็ได้แต่ก็ต้องระวังถ้าเผลอเปลี่ยน หรือ restart ip อาจจะเปลี่ยนได้เช่นกัน

มาดูในส่วนของ Schema เริ่มต้นกันตัวอย่างผมทำไว้สอง file คือ

  • 001_test.sql
  • 002_mimetype.sql

ผมตั้งชื่อเป็นลำดับเพื่อให้มันทำงานตามลำดับชื่อ file นั่นเองแต่ก็ไม่จำเป็นก็ได้ ถ้าเรา check database exist ไว้ที่หัว file ทุก file

001_test.sql

CREATE DATABASE IF NOT EXISTS `data` CHARACTER SET utf8mb4 COLLATE utf8mb4\_unicode\_ci;

USE `data`;

CREATE TABLE IF NOT EXISTS `test`
(
 `id` int PRIMARY KEY AUTO\_INCREMENT,
 `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4\_thai\_520\_w2,
 `owner` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4\_thai\_520\_w2,
 `created_at` TIMESTAMP DEFAULT CURRENT\_TIMESTAMP,
 `updated_at` TIMESTAMP ON UPDATE CURRENT\_TIMESTAMP,
 INDEX (name)

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4\_unicode\_ci;

ตัวอย่าง file แรกผม check ว่ามี database เป้าหมายอยู่หรือไม่ถ้าไม่มีก็ให้สร้างซึ่งชื่อว่า data เมื่อสร้างเสร็จแล้วก็ให้สร้าง table ชื่อ test โดยมีโครงสร้างที่เราออกแบบไว้

002_mimetype.sql

USE `data`;

CREATE TABLE IF NOT EXISTS `mimetypes`
(
 `id` int PRIMARY KEY AUTO\_INCREMENT,
 `label` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4\_unicode\_ci,
 `mime_type` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4\_unicode\_ci,
 `file_extension` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4\_unicode\_ci,
 INDEX (label)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4\_unicode\_ci;

insert into mimetypes (label,mime\_type,file\_extension) values ( 'Unknown' , '\*/\*' , '' );
insert into mimetypes (label,mime\_type,file\_extension) values ( 'AutoCAD drawing files' , 'application/acad' , 'dwg' );
insert into mimetypes (label,mime\_type,file\_extension) values ( 'Andrew data stream' , 'application/andrew-inset' , 'ez' );
insert into mimetypes (label,mime\_type,file\_extension) values ( 'ClarisCAD files' , 'application/clariscad' , 'ccad' );
insert into mimetypes (label,mime\_type,file\_extension) values ( 'Text - Comma separated value', 'text/csv' , 'csv' );
insert into mimetypes (label,mime\_type,file\_extension) values ( 'MATRA Prelude drafting' , 'application/drafting' , 'drw' );
insert into mimetypes (label,mime\_type,file\_extension) values ( 'DXF (AutoCAD)' , 'application/dxf' , 'dxf' );
insert into mimetypes (label,mime\_type,file\_extension) values ( 'Filemaker Pro' , 'application/filemaker' , 'fm' );
insert into mimetypes (label,mime\_type,file\_extension) values ( 'Macromedia Futuresplash' , 'application/futuresplash' , 'spl' );
insert into mimetypes (label,mime\_type,file\_extension) values ( 'NCSA HDF data format' , 'application/hdf' , 'hdf' );
insert into mimetypes (label,mime\_type,file\_extension) values ( 'Image - IGES graphics format' , 'application/iges' , 'iges' );
insert into mimetypes (label,mime\_type,file\_extension) values ( 'Mac binhex 4.0' , 'application/mac-binhex40' , 'hqx' );
insert into mimetypes (label,mime\_type,file\_extension) values ( 'Mac Compactpro' , 'application/mac-compactpro' , 'cpt' );
insert into mimetypes (label,mime\_type,file\_extension) values ( 'Microsoft Word' , 'application/msword' , 'doc' );
insert into mimetypes (label,mime\_type,file\_extension) values ( 'Uninterpreted binary' , 'application/octet-stream' , 'bin' );
-- Open Documents MIME types
insert into mimetypes (mime\_type, file\_extension, label) values ('application/vnd.oasis.opendocument.text', 'odt', 'OpenDocument Text');
insert into mimetypes (mime\_type, file\_extension, label) values ('application/vnd.oasis.opendocument.text-template', 'ott', 'OpenDocument Text Template');
insert into mimetypes (mime\_type, file\_extension, label) values ('application/vnd.oasis.opendocument.text-web', 'oth', 'HTML Document Template');
insert into mimetypes (mime\_type, file\_extension, label) values ('application/vnd.oasis.opendocument.text-master', 'odm', 'OpenDocument Master Document');
insert into mimetypes (mime\_type, file\_extension, label) values ('application/vnd.oasis.opendocument.graphics', 'odg', 'OpenDocument Drawing');
insert into mimetypes (mime\_type, file\_extension, label) values ('application/vnd.oasis.opendocument.graphics-template', 'otg', 'OpenDocument Drawing Template');
insert into mimetypes (mime\_type, file\_extension, label) values ('application/vnd.oasis.opendocument.presentation', 'odp', 'OpenDocument Presentation');
insert into mimetypes (mime\_type, file\_extension, label) values ('application/vnd.oasis.opendocument.presentation-template', 'otp', 'OpenDocument Presentation Template');
insert into mimetypes (mime\_type, file\_extension, label) values ('application/vnd.oasis.opendocument.spreadsheet', 'ods', 'OpenDocument Spreadsheet');
insert into mimetypes (mime\_type, file\_extension, label) values ('application/vnd.oasis.opendocument.spreadsheet-template', 'ots', 'OpenDocument Spreadsheet Template');
insert into mimetypes (mime\_type, file\_extension, label) values ('application/vnd.oasis.opendocument.chart', 'odc', 'OpenDocument Chart');
insert into mimetypes (mime\_type, file\_extension, label) values ('application/vnd.oasis.opendocument.formula', 'odf', 'OpenDocument Formula');
insert into mimetypes (mime\_type, file\_extension, label) values ('application/vnd.oasis.opendocument.database', 'odb', 'OpenDocument Database');
insert into mimetypes (mime\_type, file\_extension, label) values ('application/vnd.oasis.opendocument.image', 'odi', 'OpenDocument Image');

-- Open XML formats for MS-Office
insert into mimetypes (mime\_type, file\_extension, label) values ('application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'xlsx', 'Microsoft Office Excel');
insert into mimetypes (mime\_type, file\_extension, label) values ('application/vnd.openxmlformats-officedocument.spreadsheetml-template', 'xltx', 'Microsoft Office Excel Template');
insert into mimetypes (mime\_type, file\_extension, label) values ('application/vnd.openxmlformats-officedocument.presentationml.presentation', 'pptx', 'Microsoft Office PowerPoint Presentation');
insert into mimetypes (mime\_type, file\_extension, label) values ('application/vnd.openxmlformats-officedocument.presentationml.slideshow', 'ppsx', 'Microsoft Office PowerPoint Slideshow');
insert into mimetypes (mime\_type, file\_extension, label) values ('application/vnd.openxmlformats-officedocument.presentationml-template', 'potx', 'Microsoft Office PowerPoint Template');
insert into mimetypes (mime\_type, file\_extension, label) values ('application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'docx', 'Microsoft Office Word');
insert into mimetypes (mime\_type, file\_extension, label) values ('application/vnd.openxmlformats-officedocument.wordprocessingml-template', 'dotx', 'Microsoft Office Word Template');

ส่วน schema ที่สองสร้าง table แล้วก็ใส่ข้อมูลเบื้องต้นลงไปด้วย สังเกตว่าที่หัว file ผมไม่ได้ check การสร้าง database ไว้เลยจำเป็นต้องตั้งชื่อ 001 002 ตามลำดับ ถ้าไม่อยากตั้งชื่อแบบนี้ก็ให้ตรวจการสร้าง database ไว้ก็ได้เช่นกัน

เมื่อเราออกแบบ schema เรียบร้อยแล้วก็สามารถเริ่มต้นทำงานได้เลยด้วยคำสั่ง

docker-compose up -d

อ้อ ถ้าใครยังไม่ได้ติดตั้ง docker-compose ให้ติดตั้งก่อนนะครับตาม link นี้

Install Docker Compose

ดูผลว่า run สำเร็จหรือเปล่าด้วยคำสั่ง

docker-compose logs -f

ถ้าสำเร็จก็จะมีบรรทัดสุดท้ายประมาณนี้

mariadb\_1 | 2019-03-13 14:40:43 0 [Note] mysqld: ready for connections.
mariadb\_1 | Version: '10.3.13-MariaDB-1:10.3.13+maria~bionic' socket: '/var/run/mysqld/mysqld.sock' port: 3306 mariadb.org binary distribution

ก็ให้ Ctrl + C ออกมา

ทดสอบ Database

มาทดสอบกันว่า database ที่เราสร้างไว้มีจริงอยู่หรือไม่ ทดสอบง่ายๆ โดยไม่ต้องเข้าไปใน container ด้วยคำสั่ง (เวลาสั่ง docker-compose พึงระลึกเสมอว่าต้องอยู่ที่เดียวกับ docker-compose.yml)

docker-compose exec mariadb mysqlshow -p data
  • docker-compose → คำสั่ง
  • exec → เหมือนกับ docker exec คือ สั่งให้ execute หรือ รันคำสั่งภายใน container
  • mariadb → ชื่อ service ที่ประกาศไว้ใน docker-compose.yml
  • mysqlshow → คือคำสั่งภายใน container
  • -p → เป็น option ของคำสั่ง mysqlshow คือบอกว่าต้องใส่ password (p → password)
  • data คือชื่อ database ที่เสราให้มันสร้างไว้นั่นเอง

ถ้าทุกอย่างทำงานถูกต้องก็ได้จะได้ประมาณนี้

แสดง table ที่อยู่ใน database data

รหัสผ่านคือ 123456 ตามที่ตั้งไว้ใน docker-compose.yml นะครับ

หรือถ้า check โครงสร้างของ mimetype และ test ก็สามารถสั่งดังนี้

docker-compose exec mariadb mysqlshow -p data mimetype


docker-compose exec mariadb mysqlshow -p data test

หรือถ้าจะเข้าใช้คำสั่ง mysql ก็สามารถสั่งได้ง่ายๆ ดังนี้

docker-compose exec mariadb mysql -p

การใช้คำสั่ง mysql

ถ้าจะติดต่อจาก app อื่นๆ ผ่านทาง localhost ก็สามารถเช่ือมต่อได้เลยผ่าน

localhost:3306

หรือเราจะสร้าง service เพิ่มขึ้นมาเช่น phpmyadmin ก็สามารถทำได้โดยเพิ่มใน docker-compose.yml เวลาติดต่อกันก็ใช้ ชื่อ service คุยกันได้เลยตัวอย่างเช่น

docker-compose.yml

version: '2'
services:
**mariadb** :
 image: mariadb:10
 hostname: mariadb
 volumes:
 - ./mariadb:/var/lib/mysql
 - ./schema:/docker-entrypoint-initdb.d
 environment:
 - TZ=Asia/Bangkok
 - MYSQL\_ROOT\_PASSWORD=123456
 - "MYSQL\_ROOT\_HOST=%"

**phpmyadmin** :
 image: phpmyadmin/phpmyadmin:latest
 hostname: phpmyadmin
 ports:
 **- 9999:80**
 environment:
 - PMA\_HOST= **mariadb**

ในตัวอย่างผมเพิ่ม service เข้ามาใหม่คือ phpmyadmin สังเกตว่าผมสามารถเอา ports ของ service mariadb ออกไปได้เลยเพราะเราจะให้ service คุยกันเองภายใน ส่วน service phpmyadmin ผมให้มัน bind port 80 ออกมาเป็น port 9999 เพื่อเราสามารถเข้าไปใช้งาน phpmyadmin ได้ทาง port นี้

ตรง environment ผมตั้งแต่บอกว่า host ของ database ชื่ออะไรแค่นั้นเองมันก็จะหาเองอัตโนมัติ ส่วนเราจะตั้งค่าอะไรได้บ้างลองอ่านได้ที่

Docker Hub

เมื่อเราแก้เสร็จแล้วก็สามารถสั่งรัน docker-compose ใหม่ได้เลย

docker-compose up -d

คราวนี้ลองเข้าผ่าน web browser โดยเรียก

http://localhost:9999

phpmyadmin

ให้ใส่ user root และ password 123456 ตามที่เราตั้งไว้ตอนแรก

จัดการ database ได้แล้ว

ถ้ามือใหม่จริงๆ อาจจะงงๆ บ้าง ก็ค่อยๆ ไล่ดูนะครับถ้าเข้าใจก็สามารถนำมาช่วยในการทำงานให้สะดวกสบายขึ้น

เมื่อเราไม่ใช้งานแล้วก็ให้ทำการปิด container ด้วยคำสั่ง

docker-compose down

ถ้าจะลบข้อมูล mysql ที่เรา mount ออกมาก็ลบ directory mariadb ทิ้งด้วย


Posted on by:

Discussion

markdown guide