- 1. สิ่งที่จะได้เรียนรู้
- 2. Architecture ของ Workshop
- 3. เครื่องมือที่ต้องใช้
- Part 1: ติดตั้ง SonarQube
- Part 2: สร้าง Project บน SonarQube
- Part 3: สร้างโปรเจกต์ตัวอย่าง
- Part 4: ติดตั้ง SonarScanner CLI
- Part 5: ตั้งค่า sonar-project.properties
- Part 6: Scan Source Code
- Part 7: อ่านผลการวิเคราะห์
- Part 8: เพิ่ม Unit Test และ Coverage
- Part 9: Quality Gate
- Part 10: ใช้ SonarScanner ผ่าน Docker
- Part 11: คำสั่งที่ควรรู้
- Part 12: Troubleshooting
- Part 13: แนวทางใช้งานจริง
- Part 14: Workshop Exercise
- Part 15: Best Practices
- สรุป
SonarQube เป็นแพลตฟอร์มสำหรับตรวจสอบ คุณภาพของ Source Code (Code Quality) และช่วยค้นหาปัญหาที่เกี่ยวข้องกับ Reliability, Security และ Maintainability ของซอฟต์แวร์ ส่วนการสั่งวิเคราะห์จาก Command Line มักใช้ SonarScanner CLI เพื่อส่งข้อมูลการวิเคราะห์จาก Source Code ไปยัง SonarQube Server
Workshop นี้จะสร้างสภาพแวดล้อมสำหรับทดลองใช้งาน SonarQube ด้วย Docker Compose และใช้ SonarScanner CLI วิเคราะห์โปรเจกต์ตัวอย่าง
#1. สิ่งที่จะได้เรียนรู้
เมื่อจบ Workshop จะสามารถ:
- รัน SonarQube Server ด้วย Docker Compose
- สร้าง Project บน SonarQube
- สร้าง Analysis Token
- ติดตั้งและใช้งาน SonarScanner CLI
- กำหนดค่า
sonar-project.properties - วิเคราะห์ Source Code ผ่าน Command Line
- อ่านผล Bugs, Vulnerabilities, Security Hotspots และ Code Smells
- ตรวจสอบ Code Coverage และ Duplications
- เข้าใจการทำงานของ Quality Gate
- เตรียมนำ SonarQube ไปใช้ร่วมกับ CI/CD
#2. Architecture ของ Workshop
Developer
|
| Source Code
v
SonarScanner CLI
|
| Analysis Result
v
SonarQube Server
|
+--> Reliability
+--> Security
+--> Maintainability
+--> Coverage
+--> Duplications
|
v
Quality Gate
SonarScanner ทำหน้าที่เป็น Scanner ฝั่งโปรเจกต์ ส่วน SonarQube Server ทำหน้าที่ประมวลผล จัดเก็บ และแสดงผลการวิเคราะห์
#3. เครื่องมือที่ต้องใช้
ควรเตรียมเครื่องมือดังนี้:
Docker
Docker Compose
Git
SonarScanner CLI
Node.js / npm # สำหรับโปรเจกต์ตัวอย่าง
ตรวจสอบ Docker:
docker --version
docker compose version
ตรวจสอบ Git:
git --version
#Part 1: ติดตั้ง SonarQube
#4. สร้างโฟลเดอร์ Workshop
mkdir sonarqube-workshop
cd sonarqube-workshop
โครงสร้างเริ่มต้น:
sonarqube-workshop/
└── docker-compose.yml
#5. สร้าง Docker Compose
สร้างไฟล์:
docker-compose.yml
ตัวอย่าง:
services:
sonarqube:
image: sonarqube:community
container_name: sonarqube
depends_on:
- db
ports:
- "9000:9000"
environment:
SONAR_JDBC_URL: jdbc:postgresql://db:5432/sonar
SONAR_JDBC_USERNAME: sonar
SONAR_JDBC_PASSWORD: sonar
volumes:
- sonarqube_data:/opt/sonarqube/data
- sonarqube_extensions:/opt/sonarqube/extensions
- sonarqube_logs:/opt/sonarqube/logs
db:
image: postgres:17
container_name: sonarqube-db
environment:
POSTGRES_USER: sonar
POSTGRES_PASSWORD: sonar
POSTGRES_DB: sonar
volumes:
- postgresql_data:/var/lib/postgresql/data
volumes:
sonarqube_data:
sonarqube_extensions:
sonarqube_logs:
postgresql_data:
สำหรับ Production ควรใช้รหัสผ่านที่ปลอดภัยและจัดการ Secret ด้วยกลไกที่เหมาะสม ไม่ควรใช้ค่าตัวอย่างใน Workshop
#6. Start SonarQube
รัน:
docker compose up -d
ตรวจสอบ Container:
docker compose ps
ดู Log:
docker compose logs -f sonarqube
เมื่อระบบพร้อม เปิด Browser:
http://localhost:9000
สำหรับการติดตั้งใหม่ ระบบอาจให้เปลี่ยนรหัสผ่านเริ่มต้นหลัง Login ครั้งแรก
#Part 2: สร้าง Project บน SonarQube
#7. สร้าง Project
เข้าสู่ SonarQube Dashboard แล้วสร้าง Project ใหม่
ตัวอย่างชื่อ:
Project Name: sonar-demo
Project Key: sonar-demo
Project Key เป็นค่าที่ SonarScanner ใช้ระบุว่า Analysis ที่ส่งขึ้น Server เป็นของ Project ใด
#8. สร้าง Analysis Token
สร้าง Token สำหรับใช้กับ Scanner เช่น:
sonar-demo-token
เมื่อสร้างแล้วให้เก็บ Token ไว้ในที่ปลอดภัย
ไม่ควรเขียน Token ลงใน:
sonar-project.properties
docker-compose.yml
source code
Git repository
ควรใช้ Environment Variable หรือ Secret Management ของ CI/CD
ตัวอย่าง Linux/macOS:
export SONAR_TOKEN="YOUR_TOKEN"
ตรวจสอบ:
echo $SONAR_TOKEN
Windows PowerShell:
$env:SONAR_TOKEN="YOUR_TOKEN"
Windows CMD:
set SONAR_TOKEN=YOUR_TOKEN
#Part 3: สร้างโปรเจกต์ตัวอย่าง
#9. สร้าง Node.js Project
สร้างโฟลเดอร์:
mkdir sonar-demo
cd sonar-demo
สร้าง Project:
npm init -y
สร้างโฟลเดอร์:
mkdir src
mkdir tests
โครงสร้าง:
sonar-demo/
├── src/
│ └── calculator.js
├── tests/
│ └── calculator.test.js
├── package.json
└── sonar-project.properties
#10. สร้าง Source Code
ไฟล์:
src/calculator.js
เพิ่ม Code:
function add(a, b) {
return a + b;
}
function divide(a, b) {
return a / b;
}
function unusedFunction() {
const password = "admin123";
return password;
}
module.exports = {
add,
divide
};
ตัวอย่างนี้จงใจใส่ Code ที่อาจนำไปสู่ Issue เพื่อใช้ศึกษาผลการวิเคราะห์
#Part 4: ติดตั้ง SonarScanner CLI
#11. ตรวจสอบ Scanner
หลังติดตั้ง SonarScanner CLI และเพิ่ม executable ลงใน PATH แล้ว ให้ตรวจสอบด้วย:
sonar-scanner --version
ควรเห็นข้อมูล Version ของ Scanner และ Runtime ที่ใช้งาน
วิธีติดตั้ง SonarScanner อาจแตกต่างกันตามระบบปฏิบัติการ จึงควรตรวจสอบคู่มือ SonarScanner CLI รุ่นปัจจุบันก่อนติดตั้ง
#Part 5: ตั้งค่า sonar-project.properties
#12. สร้าง Configuration
สร้างไฟล์:
sonar-project.properties
เพิ่ม:
sonar.projectKey=sonar-demo
sonar.projectName=Sonar Demo
sonar.projectVersion=1.0
sonar.sources=src
sonar.sourceEncoding=UTF-8
ในกรณี SonarQube Server อยู่ที่เครื่อง Local สามารถส่ง URL ผ่าน CLI หรือ Environment ได้
#13. Exclude Files
หากต้องการไม่ให้ Scanner วิเคราะห์บาง Directory:
sonar.exclusions=node_modules/**,coverage/**
ตัวอย่าง Configuration:
sonar.projectKey=sonar-demo
sonar.projectName=Sonar Demo
sonar.projectVersion=1.0
sonar.sources=src
sonar.exclusions=node_modules/**,coverage/**
sonar.sourceEncoding=UTF-8
#Part 6: Scan Source Code
#14. รัน SonarScanner
Linux/macOS:
sonar-scanner \
-Dsonar.host.url=http://localhost:9000 \
-Dsonar.token=$SONAR_TOKEN
PowerShell:
sonar-scanner `
-Dsonar.host.url=http://localhost:9000 `
-Dsonar.token=$env:SONAR_TOKEN
Windows CMD:
sonar-scanner ^
-Dsonar.host.url=http://localhost:9000 ^
-Dsonar.token=%SONAR_TOKEN%
หากสำเร็จ Scanner จะแสดงสถานะสำเร็จและ URL สำหรับดูผล Analysis
#15. ส่ง Parameter ผ่าน CLI
ไม่จำเป็นต้องใส่ทุกค่าไว้ใน sonar-project.properties
ตัวอย่าง:
sonar-scanner \
-Dsonar.projectKey=sonar-demo \
-Dsonar.projectName="Sonar Demo" \
-Dsonar.sources=src \
-Dsonar.host.url=http://localhost:9000 \
-Dsonar.token=$SONAR_TOKEN
หลักการคือ:
-Dproperty=value
เช่น:
-Dsonar.sources=src
#Part 7: อ่านผลการวิเคราะห์
#16. เปิด Dashboard
เข้า:
http://localhost:9000
เลือก Project:
sonar-demo
ผลที่ควรศึกษา ได้แก่:
#Reliability
ปัญหาที่อาจทำให้โปรแกรมทำงานผิดพลาด
#Security
ปัญหาที่อาจเกี่ยวข้องกับช่องโหว่ด้าน Security
#Security Hotspots
Code ที่ต้องได้รับการตรวจสอบในบริบทด้าน Security เพิ่มเติม
#Maintainability
ปัญหาที่ทำให้ Code ดูแลรักษายาก เช่น Code Smells
#Coverage
สัดส่วน Code ที่ถูก Execute ผ่าน Test
#Duplications
ปริมาณ Code ที่มีลักษณะซ้ำกัน
#Part 8: เพิ่ม Unit Test และ Coverage
#17. ติดตั้ง Jest
npm install --save-dev jest
ปรับ package.json:
{
"scripts": {
"test": "jest",
"coverage": "jest --coverage"
}
}
#18. สร้าง Unit Test
สร้าง:
tests/calculator.test.js
Code:
const calculator = require("../src/calculator");
test("1 + 2 should equal 3", () => {
expect(
calculator.add(1, 2)
).toBe(3);
});
test("10 / 2 should equal 5", () => {
expect(
calculator.divide(10, 2)
).toBe(5);
});
#19. Generate Coverage
รัน:
npm run coverage
จะได้ Directory:
coverage/
และไฟล์สำคัญ:
coverage/lcov.info
#20. เชื่อม Coverage กับ SonarQube
เพิ่มใน:
sonar-project.properties
ดังนี้:
sonar.javascript.lcov.reportPaths=coverage/lcov.info
Configuration ตัวอย่าง:
sonar.projectKey=sonar-demo
sonar.projectName=Sonar Demo
sonar.projectVersion=1.0
sonar.sources=src
sonar.tests=tests
sonar.exclusions=node_modules/**,coverage/**
sonar.javascript.lcov.reportPaths=coverage/lcov.info
sonar.sourceEncoding=UTF-8
จากนั้น:
npm run coverage
แล้ว Scan ใหม่:
sonar-scanner \
-Dsonar.host.url=http://localhost:9000 \
-Dsonar.token=$SONAR_TOKEN
Workflow จึงเป็น:
Source Code
|
v
Unit Test
|
v
Coverage Report
|
v
SonarScanner
|
v
SonarQube
#Part 9: Quality Gate
#21. Quality Gate คืออะไร
Quality Gate คือชุดเงื่อนไขที่ใช้ตัดสินว่า Code ผ่านมาตรฐานที่กำหนดหรือไม่
แนวคิดตัวอย่าง:
Code
|
v
SonarScanner
|
v
SonarQube Analysis
|
v
Quality Gate
|
+---- PASS ----> สามารถดำเนิน Pipeline ต่อ
|
+---- FAIL ----> หยุด/แจ้งเตือน Pipeline
Quality Gate เหมาะกับการนำไปใช้ใน CI/CD เพื่อป้องกัน Code ที่ไม่ผ่านมาตรฐานเข้าสู่ขั้นตอน Release หรือ Deployment
#Part 10: ใช้ SonarScanner ผ่าน Docker
#22. Scanner Container
หากไม่ต้องการติดตั้ง SonarScanner บน Host สามารถใช้ Scanner Image ได้
Linux/macOS ตัวอย่าง:
docker run --rm \
-e SONAR_HOST_URL="http://host.docker.internal:9000" \
-e SONAR_TOKEN="$SONAR_TOKEN" \
-v "$(pwd):/usr/src" \
sonarsource/sonar-scanner-cli
การเข้าถึง Host จาก Container แตกต่างกันได้ตาม OS และ Docker environment หาก Scanner และ SonarQube อยู่ใน Docker network เดียวกัน ควรใช้ชื่อ service/container ที่ resolve ได้ใน network นั้นแทน
#23. Docker Network
หากต้องการให้ Scanner เชื่อม SonarQube ผ่าน Docker Network โดยตรง สามารถตรวจสอบ Network ก่อน:
docker network ls
แล้วรัน Scanner โดยกำหนด Network ที่ SonarQube ใช้งาน เช่น:
docker run --rm \
--network sonarqube-workshop_default \
-e SONAR_HOST_URL="http://sonarqube:9000" \
-e SONAR_TOKEN="$SONAR_TOKEN" \
-v "$(pwd):/usr/src" \
sonarsource/sonar-scanner-cli
ชื่อ Network จริงขึ้นอยู่กับชื่อ Compose project
#Part 11: คำสั่งที่ควรรู้
Start:
docker compose up -d
ตรวจสอบสถานะ:
docker compose ps
ดู Log:
docker compose logs -f sonarqube
Stop:
docker compose stop
Start อีกครั้ง:
docker compose start
หยุดและลบ Container:
docker compose down
ลบ Container และ Volume:
docker compose down -v
down -vจะลบ Persistent Volume ของ Workshop ด้วย จึงอาจทำให้ข้อมูล SonarQube/PostgreSQL หาย
#Part 12: Troubleshooting
#24. Connection refused
ตัวอย่าง:
Connection refused
ตรวจสอบ:
docker compose ps
และ:
docker compose logs sonarqube
ตรวจสอบว่า SonarQube พร้อมรับ Connection ที่:
http://localhost:9000
#25. Unauthorized
หากพบ:
Unauthorized
ตรวจสอบ Token:
echo $SONAR_TOKEN
และตรวจสอบว่า Token มีสิทธิ์วิเคราะห์ Project
#26. Project Key ไม่ตรง
ตรวจสอบ:
sonar.projectKey=sonar-demo
ให้ตรงกับ Project Key บน SonarQube
#27. Coverage ไม่แสดง
ตรวจสอบก่อนว่า:
coverage/lcov.info
มีอยู่จริง
จากนั้นตรวจสอบ:
sonar.javascript.lcov.reportPaths=coverage/lcov.info
ควรรัน Coverage ก่อน Scanner:
npm run coverage
sonar-scanner
#Part 13: แนวทางใช้งานจริง
ในระบบจริง Workflow อาจเป็น:
Developer
|
v
Git Push / Pull Request
|
v
CI/CD Pipeline
|
+--> Install Dependencies
|
+--> Build
|
+--> Unit Test
|
+--> Generate Coverage
|
+--> SonarScanner
|
v
SonarQube
|
v
Quality Gate
/ \
PASS FAIL
| |
v v
Deploy Stop Pipeline
สามารถนำแนวคิดนี้ไปใช้กับ:
- GitHub Actions
- GitLab CI/CD
- Jenkins
- Azure Pipelines
- ระบบ CI/CD อื่นที่สามารถเรียก Scanner ได้
#Part 14: Workshop Exercise
#Exercise 1: เพิ่ม Code Smell
เพิ่ม Function ที่ซับซ้อนหรือมี Code ซ้ำ แล้ว Scan ใหม่
sonar-scanner \
-Dsonar.host.url=http://localhost:9000 \
-Dsonar.token=$SONAR_TOKEN
เปรียบเทียบจำนวน Issue ก่อนและหลังแก้ไข
#Exercise 2: เพิ่ม Test Coverage
เพิ่ม Function:
function multiply(a, b) {
return a * b;
}
จากนั้น Scan โดยยังไม่เพิ่ม Test และตรวจ Coverage
ต่อมาเพิ่ม Unit Test:
test("2 * 5 should equal 10", () => {
expect(
calculator.multiply(2, 5)
).toBe(10);
});
Generate Coverage และ Scan อีกครั้ง
npm run coverage
sonar-scanner \
-Dsonar.host.url=http://localhost:9000 \
-Dsonar.token=$SONAR_TOKEN
เปรียบเทียบ Coverage ก่อนและหลังเพิ่ม Test
#Exercise 3: Refactoring
เลือก Issue จาก SonarQube แล้วดำเนินการ:
1. อ่านรายละเอียด Issue
2. ตรวจสอบตำแหน่ง Source Code
3. Refactor Code
4. Run Unit Test
5. Generate Coverage
6. Run SonarScanner
7. ตรวจสอบ Issue อีกครั้ง
นี่เป็น Feedback Loop สำคัญของ Continuous Code Quality
#Part 15: Best Practices
#อย่าเก็บ Token ใน Git
ไม่ควรทำ:
sonar.token=my-secret-token
ควรใช้:
export SONAR_TOKEN="..."
หรือ Secret ของ CI/CD
#Run Test ก่อน Scan
Workflow ที่แนะนำ:
npm ci
npm test
npm run coverage
sonar-scanner
เพราะ Scanner สามารถนำ Coverage Report ไปประกอบการวิเคราะห์ได้
#ใช้ Quality Gate ใน CI/CD
ไม่ควรใช้ SonarQube เพียงเพื่อเปิด Dashboard ดูเป็นครั้งคราว แต่ควรนำ Quality Gate มาเป็นส่วนหนึ่งของ Software Delivery Pipeline
Commit
|
Test
|
Coverage
|
SonarQube
|
Quality Gate
|
Deploy
#สรุป
SonarQube และ SonarScanner CLI ช่วยสร้างกระบวนการตรวจสอบคุณภาพ Source Code แบบอัตโนมัติ โดย Scanner ทำหน้าที่วิเคราะห์/รวบรวมข้อมูลจาก Project และส่งผลไปยัง SonarQube Server เพื่อประเมินด้านต่าง ๆ เช่น:
Reliability
Security
Maintainability
Coverage
Duplications
Workshop ขั้นพื้นฐานสามารถเริ่มจาก:
Docker Compose
|
v
SonarQube + PostgreSQL
Source Code
|
v
Unit Test
|
v
Coverage
|
v
SonarScanner CLI
|
v
SonarQube
|
v
Quality Gate
เมื่อเข้าใจ Workflow นี้แล้ว ขั้นต่อไปคือการนำ Scanner เข้าไปอยู่ใน CI/CD เช่น GitHub Actions, GitLab CI/CD หรือ Jenkins เพื่อให้ทุก Commit หรือ Pull Request ได้รับการตรวจสอบคุณภาพ Code โดยอัตโนมัติ
#คำสั่งสรุปสำหรับ Workshop
# Start SonarQube
docker compose up -d
# ตรวจสอบ Container
docker compose ps
# Test + Coverage
npm run coverage
# Scan
sonar-scanner \
-Dsonar.host.url=http://localhost:9000 \
-Dsonar.token=$SONAR_TOKEN
# ดู Log
docker compose logs -f sonarqube
# Stop
docker compose down
#Workshop ต่อไปที่แนะนำ
หลังจาก Workshop นี้ สามารถต่อยอดเป็น:
SonarQube
+
GitHub Actions
+
Pull Request
+
Quality Gate
+
Docker Build
+
Deployment
เพื่อสร้าง Continuous Integration Pipeline ที่ตรวจสอบทั้ง Test + Coverage + Code Quality ก่อน Build และ Deploy ระบบ