ติดต้ัง Sql Server ด้วย Docker
การติดต้ัง SQL Server ลงใน docker จะมีวิธีการที่แตกต่างจากการติดต้ัง server ด้วย VM อยู่พอสมควรดังนั้นในบทความนี้เราจะพาคุณไปดูวิธีการติดตั้ง SQL Server แบบ step by step
ข้อดีของการใช้ docker
ก่อนจะเข้าสู่วิธีการติดต้ังเราต้องขายให้ได้ก่อนว่าทำไมเราถึงต้องใช้ docker
- สามารถเปลี่ยน version ของ SQL Server ได้งง่าย
- สามารถจำลอง database server บนเครื่อง dev ได้ง่าย
- เราสามารถจัดการกับ version ของ database ได้ง่ายขึ้น
- นำไป deploy ลงใน Kubernetes cluster ต่อได้
- สามารถนำเข้าไปใส่ใน CI/CD Pipeline ได้ง่าย
Docker กับ Database
การทำงานกับ database ใน docker นั้นเราต้องเข้าใจ 2 สิ่งนี้ก่อน
-
การทำงานของ docker นั้นจะแบ่งเป็น layer ซึ่งในการทำงานกับ database นั้นเราจะแยกออกเป็น 4 layers ดังนี้
- Database ตัวฐานข้อมูลที่เราจะนำมาใช้งาน เราจะใช้ไฟล์ SQL ในการนำเข้า
- SQL Server Engine เป็น database server ที่นำมาใช้งาน
- Engine Dependencies เครื่องมือหรือ services ต่างๆ ที่ติดตั้งเข้าไปเพิ่มเติม
- Base OS Image Database ไม่สามารถ run ได้ด้วยตัวเองต้องนำไปติดตั้งลงใน OS สำหรับ SQL Server ตอนนี้ official image จะใช้ Ubuntu เป็น base image
บน production เราต้องใช้ Linux-based container เพราะ Microsoft ไม่ support การใช้ windows-based container บน production อีกแล้ว
-
เราต้องใช้ Volume เพราะเราไม่สามารถเก็บข้อมูลไว้ใน container ได้ เนื่องจากเราต้องการให้ SQL Server ของเราสามารถลบทิ้งแล้วสร้างใหม่ได้ตลอดเวลา
สิ่งที่คุณต้องมีก่อนติดต้ัง
- Docker Desktop
- Azure Data Studio หรือ SQL Server Management Studio(SSMS)
ขั้นตอนการติดต้ัง SQL Server
การติดตั้ง SQL Server ลงใน docker container เราจะเริ่มจากการ run SQL Server container ด้วย docker run command ก่อน หลังจากนั้นเราจะเปลี่ยนจาก docker run command ไปเป็น service ใน docker compose
ขั้นตอนที่ 1. สร้าง SQL Server
ในตัวอย่างแรก เราจะใช้ docker image จาก microsoft โดยที่ใช
|
|
ความหมายของ parameters ที่เรากำหนดให้กับคำสั่ง docker run มีดังนี้
- บรรทัดที่ 1 เป็นการตั้งชื่อ container ว่า testdb และ run เป็น detach mode(เป็น background process)
- บรรทัดที่ 2 เป็นการเปิด port 1433(default port ของ SQL Server) ออกมาที่เครื่อง host
- บรรทัดที่ 3 เป็นการตั้ง password ของ user SA(System Administrator) ซึ่งต้องเป็นไปตาม password policy นี้
- บรรทัดที่ 4 เป็นการตอบตกลงยอมรับ License เหมือนกับตอนที่เรา install บน server ปกติที่เราต้องกดปุ่ม accept
- บรรทัดที่ 5 เป็นการระบุ image ของ SQL Server ที่เราจะนำมาใช้ ซึ่งจะมีให้เราเลือกใช้ตาม OS version ของ SQL Server
สำหรับคนที่ใช้ windows ตัวิย่าง docker command นี้จะต้อง run ใน powershell เพราะผมใช้ \ แต่ถ้าจะเอาไป run ใน command prompt คุณต้องลบ \ ออกแล้ววางไว้ในบรรทัดเดียวกัน
เราสามารถใช้งาน SQL Server ผ่านทาง docker แบบนี้ได้ก็จริงแต่ปัญหาที่เราต้องเจอคือ
- ยังไม่มี database และต้องนำเข้าด้วยมือหลังจาก container start ขึ้นมาแล้ว
- data ยังอยู่ภายใน container ซึ่งหมายความว่า เมื่อเราลบ container ทิ้ง data ทั้งหมดจะหายไปทันที ซึ่งไม่น่าจะดีแน่นอน
ดังนั้นในขึ้นตอนต่อไปเราจะมาไล่แก้ปัญหา 2 ข้อนี้
SQL Server Password Policy
การจะตั้ง password ของ user ใน SQL Server ต้องทำตามนี้
- password ต้องไม่มีชื่อของ user เป็นส่วนประกอบ
- password ต้องยาวเกิน 8 ตัวอักษร
- password ต้องประกอบไปด้วย
- ตัวพิทพิ์ใหญ่(Uppercase) A ถึง Z
- ตัวพิมพิ์เล็ก(Lowercase) a ถึง z
- ตัวเลข(Digits) 0-9
- อักขระพิเศษ เช่น exclamation point (!), dollar sign ($), number sign (#), หรือ percent (%)
ขั้นตอนที่ 2. สร้าง Docker Volume
เราจะต้องสร้าง volume ขึ้นมาเพื่อแยก data ออกไปอยู่ยอก container ถ้าเราสร้าง container ด้วย docker run เราจะใช้ paraneter -v แบบนี้
|
|
ในการ map volume เราจะ map ข้อมูล 3 ชุดด้วยกัน
- data เป็น folder ที่เก็บ data ใน container จะอยู่ที่ /var/opt/mssql/data
- log เป็น folder ที่จัดเก็บ log ของ sql server ใน container จะอยู่ที่ /var/opt/mssql/log
- secrets เป็น folder ที่จัดเก็บความลับต่างๆ เช่น keytab, certificates และ machine key ซึ่งใน container จะอยู่ที่ /var/opt/mssql/secrets
เนื่องจาก application ของจริงจะต้องมีหลาย services เช่น api, database และ log server เราจึงจะแปลงจาก docker command ไปเป็น docker compose เพื่อให้ง่ายต่อการนำไปใช้งาน ซึ่งเราจะได้ docker-compose.yml ออกมาแบบนี้
|
|
ขั้นตอนที่ 3 สร้าง Schema ของ Database
ขั้นตอนนี้เราต้องการให้สร้าง SQL Server ขึ้นมาแล้วมี database มาพร้อมสำหรับการใช้งานเลย เวลานำไปทำ Automate deploy หรือ Automated testing จะได้ง่าย
ในตัวอย่างนี้เราจะสร้าง database ชื่อ CarvedRock และใน databaes นี้จะมี table ชื่อ Product โดยจะตั้งชื่อไฟล์ว่า initializeDatabase.sql
CREATE DATABASE CarvedRock
GO
USE CarvedRock
GO
----------------------------------------------------------------------------
--- TABLE CREATION
----------------------------------------------------------------------------
CREATE TABLE [dbo].[Product](
[Id] [INT] NOT NULL,
[Name] [NVARCHAR](100) NOT NULL,
[Description] [NVARCHAR](MAX) NULL,
[Price] [NUMERIC](14, 2) NOT NULL,
[Category] [NVARCHAR](30) NOT NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
หลังจากนั้นเราจะนำ InitializeDatabase.sql เข้าไปใส่ไว้ใน dockerfile ที่เราจะตั้งชื่อว่า sql.dockerfile
FROM mcr.microsoft.com/mssql/server:2022-latest
ARG PROJECT_DIR=/tmp/devdatabase
RUN mkdir -p $PROJECT_DIR
WORKDIR $PROJECT_DIR
COPY sql/InitializeDatabase.sql ./
COPY sql/wait-for-it.sh ./
COPY sql/entrypoint.sh ./
COPY sql/setup.sh ./
USER root
RUN sh -c "chmod +x ./*.* && chown mssql ./*.*"
USER mssql
EXPOSE 1433
CMD ["/bin/bash", "entrypoint.sh"]
เราต้อง copy file เข้าไปใน /tmp เพื่อให้สามารถ execute ได้
ในตัวอย่างนี้เราจะต้องเขียน shell script เพื่อให้ IntialDatabase.sql ถูก execute เมื่อ SQL Server อยู่ในสถานะที่พร้อมใช้งานแล้ว โดยจะไล่ไปตามขั้นตอนดังนี้
-
entrypoint.sh จะถูก run เป็นตัวแรกเมื่อเราสร้าง container ใน shell script ตัวนี้จะทำ
- start SQL Server
- เรียก setup.sh เพื่อสร้าง CarvedRock database
- sleep และ wait เพื่อให้ process ทำงานเป็น background service
1
/opt/mssql/bin/sqlservr & ./setup.sh & sleep infinity & wait
-
setup.sh จะเป็น shell script ที่เขียนขึ้นมาเพื่อสร้าง database โดยมีเงื่อนไขว่าเราจะ import database เข้าไปได้ก็ต่อเมื่อ SQL Server อยู่ในสถานะพร้อมใช้งาน ดังนั้นเราจึงต้องใช้ wait-for-it ซึ่งเป็น opensource ที่ใช้ในการรอจนกว่า service ที่เราต้องการนั้นพร้อมใช้งาน
1 2 3 4
./wait-for-it.sh localhost:1433 --timeout=0 --strict -- sleep 10s && \ /opt/mssql-tools/bin/sqlcmd -S localhost \ -i InitializeDatabase.sql \ -U sa -P "$SA_PASSWORD"
หลังจากนั้นในบรรทัดที่ 2 เราจะใช้ sqlcmd ในการ import database เมื่อทำครบทั้ง 2 บรรทัดนี้แล้วเราจะได้ SQL Server ที่มี โครงสร้าง database พร้อมทั้ง data มาให้เราใช้งานเรียบร้อย
ขั้นตอนที่ 4 จัดการกับ SQL Server ด้วย Azure Data Studio
ขั้นตอนนี้เราสามารถใช้ SQL Server Management Studio(SSMS) หรือ Azure Data Studio ก็ได้ ในตัวอย่างนี้เราจะใช้ Azure Data Studio เพราะสามารถติดต้ังได้ทุก OS แต่ความสามารถก็อาจยังสู้กับ SQL Server Management Studio ไม่ได้
หลังจากนั้นกำหนดค่า
- Server เป็น localhost
- Authentication Type เป็น SQL Login
- Username เป็น sa
- Password เป็น $qlServerD0cker(เรากำหนดไว้ใน docker-compose.yml)
- Database เป็น CarvedRock (เป็น Optional ไม่ต้องใส่ก็ได้)
ถ้าทุกอย่างถูกต้องเรียบร้อยเราจะได้หน้าสำหรับจัดการกับ database
ข้อแนะนำ การเปลี่ยนแปลงโครงสร้างของ Database ควรจะทำใน InitializeDatabase.sql เพื่อให้ถูกจัดการ Version หรือใช้ Migration tools อย่าง Flyway หรือ Liquibase