เพื่อให้เครื่องมือทั้งหมดสามารถทำงานสอดประสานกันได้อย่างไร้รอยต่อ เราจำเป็นต้องดำเนินการตั้งค่าในแต่ละส่วนเพิ่มเติม ดังนี้
วัตถุประสงค์
เพื่อทำให้ "โรงงาน" (Jenkins) มีกุญแจสำหรับไขเข้า "โกดัง" (Nexus) โดยเพิ่ม Username/Password ของ Nexus เข้าไปใน Jenkins Credentials (ชนิด Username with password)
นอกจากนี้ต้องเพิ่ม SonarQube Scanner เพื่อรองรับการทดสอบระบบ Pipeline
ตลอดจนต้องทำการตั้งค่า System อีกหนึ่งจุด เพื่อให้ Jenkins คุยกับ SonarQube Server ได้สำเร็จ
เพื่อให้ "โรงงาน" ส่ง Code มาสแกนได้โดยอัตโนมัติ
เพื่อให้ Jenkins รู้ว่าโค้ดที่สแกน "ผ่าน" หรือ "ไม่ผ่าน" (Quality Gate)
การทดสอบการ Build และ Push ไปยัง Nexus
เพื่อให้ระบบบางส่วนมีความพร้อมสามารถรองรับการทำงานสอดประสานกันอย่างไร้รอยต่อ ดังนี้
pipeline {
agent any
environment {
REGISTRY_URL = 'registry.panmodel.com'
IMAGE_NAME = 'test-nexus-integration'
IMAGE_TAG = "${env.BUILD_NUMBER}"
}
stages {
stage('Preparation') {
steps {
sh "echo 'FROM alpine:latest\nCMD [\"echo\", \"Hello from RTAF Software Factory\"]' > Dockerfile"
echo "สร้าง Dockerfile จำลองสำเร็จ"
}
}
stage('Build Image') {
steps {
script {
echo "กำลังเริ่ม Build Image: ${REGISTRY_URL}/${IMAGE_NAME}:${IMAGE_TAG}"
// เติม def เพื่อป้องกัน Memory Leak ตามคำแนะนำใน Log ของ Jenkins
def appImage = docker.build("${REGISTRY_URL}/${IMAGE_NAME}:${IMAGE_TAG}")
}
}
}
stage('Push to Nexus') {
steps {
script {
// ใช้ ID 'nexus-docker-auth' ที่เตรียมไว้ในระบบ Credentials
docker.withRegistry("https://${REGISTRY_URL}", 'nexus-docker-auth') {
echo "กำลัง Push Image ไปยัง Nexus..."
// ดัน Image ขึ้นไปยังโรงงาน Nexus ของเรา
sh "docker push ${REGISTRY_URL}/${IMAGE_NAME}:${IMAGE_TAG}"
sh "docker tag ${REGISTRY_URL}/${IMAGE_NAME}:${IMAGE_TAG} ${REGISTRY_URL}/${IMAGE_NAME}:latest"
sh "docker push ${REGISTRY_URL}/${IMAGE_NAME}:latest"
}
}
}
}
}
post {
success {
echo "ยินดีด้วยครับ! โรงงานผลิตและส่งของเข้าโกดัง Nexus สำเร็จแล้ว"
}
failure {
echo "การส่งของผิดพลาด ตรวจสอบ Realms หรือสิทธิ์ของ User ใน Nexus อีกครั้งนะครับ"
}
}
}
ผลลัพธ์ที่คาดหวัง คือ Jenkins Pipeline ควรแสดงข้อความ Success เพื่อแสดงว่าสามารถ docker push ไปยัง registry.panmodel.com ได้สำเร็จ รวมถึง ใน docker-internal ของ Nexus จะเห็นโฟลเดอร์ test-nexus-integration ปรากฏขึ้นมา มีทั้งส่วนของ manifests และ tags ครบถ้วนตามที่เราสั่งใน Jenkinsfile
เป็นการนำ Jenkinsfile ไปวางไว้ที่โปรเจกต์ของ GitLab (Root of Project) เพื่อทำการเชื่อมต่อ "สายพานการผลิต" (GitLab -> Jenkins -> SonarQube -> Nexus) เข้าด้วยกัน โดยทำผ่าน GitLab เพื่อให้ Jenkins มองเห็นและดึงไปใช้งานโดยอัตโนมัติ ตามขั้นตอนดังนี้
pipeline {
agent any
environment {
// 1. ใช้ ID 'jenkins-token' ให้ตรงกับที่สร้างไว้ใน System
SONAR_TOKEN = credentials('jenkins-token')
// 2. ใช้ ID 'gitlab-jenkins-creds' สำหรับดึงโค้ด
GITLAB_CREDS = credentials('gitlab-jenkins-creds')
// 3. หากยังไม่ได้สร้าง 'nexus-docker-auth' ให้สร้างใน Jenkins ก่อน
NEXUS_CREDS = credentials('nexus-docker-auth')
}
stages {
stage('1. Checkout') {
steps {
// ดึงโค้ดจาก GitLab
checkout scm
}
}
stage('2. SonarQube Analysis') {
steps {
script {
// 1. ให้ Jenkins ไปหาเองว่าโปรแกรม Scanner ติดตั้งไว้ที่โฟลเดอร์ไหน
def scannerHome = tool 'SonarScanner'
// 2. ใช้ชื่อ Server ให้ตรงกับที่ตั้งใน Manage Jenkins > System
withSonarQubeEnv('SonarQube-Server-Name') {
// 3. รันโปรแกรมจากเครื่องตัวเอง แล้วสั่งให้ส่งข้อมูลไปที่ Server (https://sonar.panmodel.com)
sh "${scannerHome}/bin/sonar-scanner \
-Dsonar.projectKey=my-factory-app \
-Dsonar.sources=. \
-Dsonar.host.url=https://sonar.panmodel.com \
-Dsonar.login=${SONAR_TOKEN}"
}
}
}
}
stage('3. Quality Gate') {
steps {
timeout(time: 5, unit: 'MINUTES') {
// รอผล Webhook จาก https://ci.panmodel.com/sonarqube-webhook/
waitForQualityGate abortPipeline: true
}
}
}
stage('4. Build & Push to Nexus') {
steps {
script {
// สั่ง Build Docker Image และส่งไปเก็บที่ Nexus (registry.panmodel.com)
docker.withRegistry('https://registry.panmodel.com', 'nexus-docker-auth') {
def appImage = docker.build("registry.panmodel.com/my-app:${env.BUILD_ID}")
appImage.push()
}
}
}
}
}
post {
always {
// เคลียร์ไฟล์ที่ Build เสร็จแล้วเพื่อประหยัดพื้นที่ VPS 48GB
cleanWs()
}
}
}
FROM alpine:3.21.3
# สร้าง User ใหม่ชื่อ 'factory_user' และสลับไปใช้งาน
RUN adduser -D factory_user
USER factory_user
RUN echo "Hello from My Factory with Secure User" > /tmp/hello.txt
CMD ["cat", "/tmp/hello.txt"]
เมื่อกด Create project ใน GitLab แล้ว เพื่อให้ "สายพาน" เริ่มวิ่งอัตโนมัติเมื่อมีการแก้ไขไฟล์ ให้ทำดังนี้
การตั้งค่าใน Jenkins เพื่อให้เรียกใช้ไฟล์ Jenkinsfile นี้ หรือก็คือ หลังจากที่เรามีไฟล์ Jenkinsfile ใน GitLab แล้ว เราต้องบอกให้ Jenkins รู้ว่าต้องมาอ่านไฟล์นี้เพื่อทำงานตามที่ระบุไว้ต่อไป
ลองกด Build Now ใน Jenkins ได้เลย Jenkins จะทำการ Build Image และ Push ไปยัง registry.panmodel.com ให้ล็อกอินเข้า Nexus ไปที่เมนู Browse และดูใน Repository ประเภท Docker (hosted) ควรจะเห็น Image ชื่อ my-app พร้อม Tag หมายเลข Build ปรากฏอยู่ในนั้น
เพื่อให้ระบบทั้งชุดทำงานสอดประสานกันอย่างไร้รอยต่อ เราต้องตั้งค่า การเชื่อมต่อกับ SigNoz