การเชื่อมต่อ Jenkins กับ GitHub เป็นแนวทางพื้นฐานที่สำคัญของงาน DevOps และ Continuous Integration/Continuous Delivery (CI/CD) โดยทำให้ Jenkins สามารถดึง Source Code จาก GitHub แล้วสั่ง Build, Test, สร้าง Docker Image หรือ Deploy ระบบโดยอัตโนมัติเมื่อมีการเปลี่ยนแปลงโค้ด

บทความนี้อธิบายตั้งแต่การเตรียม Jenkins การเพิ่ม Credentials การสร้าง Pipeline การตั้งค่า GitHub Webhook ไปจนถึงตัวอย่าง Jenkinsfile ที่สามารถนำไปทดลองได้จริง


#1. ภาพรวมการทำงาน

สถาปัตยกรรมพื้นฐานมีลักษณะดังนี้

Developer
    |
    | git push
    v
GitHub Repository
    |
    | Webhook
    v
Jenkins
    |
    +--> Checkout
    +--> Install Dependencies
    +--> Unit Test
    +--> Build
    +--> Docker Build
    +--> Deploy

เมื่อ Developer ทำ git push ขึ้น GitHub:

  1. GitHub ตรวจพบ Push Event
  2. GitHub Webhook ส่ง HTTP Request ไปยัง Jenkins
  3. Jenkins เริ่ม Pipeline
  4. Jenkins Checkout Source Code
  5. Pipeline ทำ Build และ Test
  6. หากผ่าน สามารถสร้าง Docker Image และ Deploy ต่อได้

#2. สิ่งที่ต้องเตรียม

ควรมีองค์ประกอบดังนี้

  • Jenkins Server
  • GitHub Account
  • GitHub Repository
  • Git ติดตั้งบน Jenkins Agent
  • Jenkins สามารถเข้าถึง Repository ได้
  • หากต้องใช้ Webhook จาก GitHub โดยตรง Jenkins ต้องมี URL ที่ GitHub เข้าถึงได้
  • Docker หากต้องการทำ Container Build

ตัวอย่าง Jenkins URL:

https://jenkins.example.com

หาก Jenkins ทำงานอยู่เฉพาะ localhost ภายในเครื่อง GitHub Cloud จะไม่สามารถเรียก Webhook เข้ามาโดยตรงได้


#3. ติดตั้ง Jenkins Plugins

เข้า Jenkins Dashboard แล้วเลือก

Manage Jenkins
→ Plugins

ติดตั้ง Plugin ที่เกี่ยวข้อง เช่น

Git
GitHub
Pipeline
Credentials Binding

หน้าที่หลักของแต่ละ Plugin:

Plugin หน้าที่


Git เชื่อมต่อและ Checkout Git Repository GitHub เชื่อม Jenkins กับ GitHub และรองรับ GitHub Webhook Pipeline สร้าง Pipeline ด้วย Jenkinsfile Credentials Binding ใช้งาน Secret/Credential ใน Pipeline อย่างปลอดภัย

หลังติดตั้ง Plugin อาจต้อง Restart Jenkins ตามที่ระบบแจ้ง


#4. เตรียม GitHub Repository

สมมติ Repository คือ

https://github.com/USERNAME/my-app.git

โครงสร้าง Project อาจเป็น

my-app/
├── src/
├── tests/
├── package.json
├── Dockerfile
└── Jenkinsfile

ไฟล์ Jenkinsfile จะเก็บนิยาม CI/CD Pipeline และควรเก็บร่วมกับ Source Code เพื่อให้ Pipeline เปลี่ยนแปลงตาม Version ของระบบได้


#5. การเข้าถึง Private Repository

หากเป็น Public Repository Jenkins สามารถ Checkout ผ่าน HTTPS ได้โดยไม่ต้องใช้ Credential ในหลายกรณี

สำหรับ Private Repository ต้องกำหนด Credential ให้ Jenkins เช่น GitHub Personal Access Token (PAT), SSH Key หรือ GitHub App ตามรูปแบบการใช้งานขององค์กร

#เพิ่ม Credential ใน Jenkins

ไปที่

Manage Jenkins
→ Credentials
→ System
→ Global credentials
→ Add Credentials

ตัวอย่างกรณีใช้ Token:

Kind: Secret text
Secret: <GitHub Personal Access Token>
ID: github-token
Description: GitHub Personal Access Token

หลักสำคัญคือ ไม่ควรเขียน Token ลงใน Jenkinsfile หรือ Commit Token ลง GitHub


#6. สร้าง Jenkins Pipeline

ที่ Jenkins Dashboard เลือก

New Item

ตั้งชื่อ เช่น

my-app-pipeline

เลือก

Pipeline

จากนั้นในส่วน Pipeline เลือก

Definition:
Pipeline script from SCM

กำหนดค่า เช่น

SCM:
Git

Repository URL:
https://github.com/USERNAME/my-app.git

Branch Specifier:
*/main

Script Path:
Jenkinsfile

ถ้าเป็น Private Repository ให้เลือก Credential ที่เตรียมไว้


#7. สร้าง Jenkinsfile

ตัวอย่างสำหรับ Node.js Application:

pipeline {
    agent any

    stages {

        stage('Checkout') {
            steps {
                checkout scm
            }
        }

        stage('Install Dependencies') {
            steps {
                sh 'npm ci'
            }
        }

        stage('Test') {
            steps {
                sh 'npm test'
            }
        }

        stage('Build') {
            steps {
                sh 'npm run build'
            }
        }

    }

    post {
        success {
            echo 'Pipeline completed successfully'
        }

        failure {
            echo 'Pipeline failed'
        }
    }
}

Pipeline จะทำงานตามลำดับ

Checkout
   |
   v
npm ci
   |
   v
npm test
   |
   v
npm run build

หาก Jenkins Agent เป็น Windows และไม่ได้ใช้ Unix-like shell อาจต้องเปลี่ยนคำสั่ง sh เป็น bat หรือ PowerShell ตาม Environment


#8. ตั้งค่า GitHub Webhook

เข้า GitHub Repository แล้วเลือก

Settings
→ Webhooks
→ Add webhook

กำหนด Payload URL:

https://jenkins.example.com/github-webhook/

กำหนด Content type:

application/json

เลือก Event เช่น

Just the push event

จากนั้นเปิด

Active

แล้วกด Add webhook

URL /github-webhook/ เป็น Endpoint ที่ Jenkins GitHub Plugin ใช้รับ Event จาก GitHub


#9. เปิด GitHub Trigger ใน Jenkins

กลับไปยัง Jenkins Pipeline Job แล้วเลือก

Configure
→ Build Triggers

เปิด

GitHub hook trigger for GITScm polling

จากนั้น Save

เมื่อ GitHub ส่ง Webhook เข้ามา Jenkins จะตรวจสอบ Job ที่เกี่ยวข้องและเริ่ม Build ตามการตั้งค่า


#10. ทดสอบ Pipeline

แก้ Source Code แล้ว Commit:

git add .
git commit -m "test Jenkins pipeline"
git push origin main

Flow ที่เกิดขึ้น:

Developer
    |
    | git push
    v
GitHub
    |
    | Push Event
    v
GitHub Webhook
    |
    | HTTP POST
    v
Jenkins
    |
    v
Jenkins Pipeline
    |
    +--> Checkout
    +--> Test
    +--> Build

สามารถตรวจสอบ Pipeline ได้จาก Jenkins Dashboard และตรวจสอบการส่ง Webhook ได้จากหน้า Webhooks ของ Repository


#11. เพิ่ม Docker Build

หาก Application มี Dockerfile สามารถเพิ่ม Stage:

stage('Docker Build') {
    steps {
        sh 'docker build -t my-app:${BUILD_NUMBER} .'
    }
}

Pipeline จะกลายเป็น

GitHub
   |
   v
Jenkins
   |
   +--> Checkout
   +--> Install
   +--> Test
   +--> Build
   +--> Docker Build

${BUILD_NUMBER} คือหมายเลข Build ของ Jenkins ซึ่งช่วยแยก Image แต่ละ Build ได้


#12. ใช้ Git Commit เป็น Docker Image Tag

ในการทำงานจริง การใช้ Git Commit SHA ช่วย Trace Image กลับไปยัง Source Code ได้ง่ายกว่า

stage('Docker Build') {
    steps {
        script {
            def commit = sh(
                script: 'git rev-parse --short HEAD',
                returnStdout: true
            ).trim()

            sh "docker build -t my-app:${commit} ."
        }
    }
}

ตัวอย่าง Image:

my-app:a81c2f4

ทำให้สามารถตรวจสอบได้ว่า Container ที่ Deploy มาจาก Commit ใด


#13. Jenkinsfile แบบ CI/CD

ตัวอย่าง Pipeline ที่รวม Test, Build และ Docker:

pipeline {
    agent any

    environment {
        IMAGE_NAME = 'username/my-app'
    }

    stages {

        stage('Checkout') {
            steps {
                checkout scm
            }
        }

        stage('Install') {
            steps {
                sh 'npm ci'
            }
        }

        stage('Test') {
            steps {
                sh 'npm test'
            }
        }

        stage('Build') {
            steps {
                sh 'npm run build'
            }
        }

        stage('Docker Build') {
            steps {
                sh '''
                    docker build \
                    -t ${IMAGE_NAME}:${BUILD_NUMBER} .
                '''
            }
        }

        stage('Deploy') {
            steps {
                echo "Deploy version ${BUILD_NUMBER}"
            }
        }

    }

    post {

        success {
            echo 'CI/CD SUCCESS'
        }

        failure {
            echo 'CI/CD FAILED'
        }

    }
}

#14. การ Push Docker Image

หากต้องการ Push Image ไปยัง Registry สามารถเพิ่ม Stage เช่น

stage('Docker Push') {
    steps {
        withCredentials([
            usernamePassword(
                credentialsId: 'dockerhub',
                usernameVariable: 'DOCKER_USER',
                passwordVariable: 'DOCKER_PASSWORD'
            )
        ]) {
            sh '''
                echo "$DOCKER_PASSWORD" | docker login \
                    -u "$DOCKER_USER" --password-stdin

                docker push ${IMAGE_NAME}:${BUILD_NUMBER}
            '''
        }
    }
}

Credential ควรถูกจัดเก็บใน Jenkins Credentials ไม่ควรฝัง Username/Password หรือ Token ลงใน Repository


#15. Pipeline สำหรับระบบจริง

สามารถขยาย Architecture เป็น

Developer
    |
    v
GitHub
    |
    | Webhook
    v
Jenkins
    |
    +--> Checkout
    |
    +--> Unit Test
    |
    +--> Code Quality / SonarQube
    |
    +--> Build
    |
    +--> Docker Build
    |
    +--> Security Scan
    |
    +--> Push Container Registry
    |
    v
Deployment
    |
    +--> VM
    +--> Docker
    +--> Kubernetes

หรือใช้ GitOps:

GitHub Application Repo
        |
        v
     Jenkins
        |
        +--> Test
        +--> Build
        +--> Docker Build
        +--> Push Registry
        |
        v
GitOps Repository
        |
        v
     Argo CD
        |
        v
    Kubernetes

ในแนวทางนี้ Jenkins รับผิดชอบงาน CI ส่วน Argo CD รับผิดชอบการ Sync Desired State จาก Git Repository ไปยัง Kubernetes


#16. แนวทางสำหรับ Pull Request

สำหรับ Project ที่มีหลาย Branch อาจพิจารณาใช้ Multibranch Pipeline เพื่อให้ Jenkins ค้นหา Branch และ Jenkinsfile โดยอัตโนมัติ และรองรับ Workflow ที่เกี่ยวข้องกับ Pull Request ได้เหมาะสมกว่า Pipeline Job แบบ Branch เดียว

ตัวอย่าง Flow:

feature/login
     |
     v
Pull Request
     |
     v
Jenkins
     |
     +--> Build
     +--> Unit Test
     +--> Integration Test
     +--> Quality Check

เมื่อผ่านการตรวจสอบจึง Merge เข้า main


#17. แนวทางด้าน Security

การเชื่อม Jenkins กับ GitHub ควรระวังเรื่อง Secret และสิทธิ์ของระบบ โดยมีแนวทางสำคัญดังนี้

  1. ไม่ Commit Token, Password หรือ Private Key ลง Repository
  2. เก็บ Secret ใน Jenkins Credentials
  3. กำหนด Permission ของ GitHub Credential เท่าที่จำเป็น
  4. ใช้ HTTPS สำหรับ Jenkins ที่เปิดสู่ Internet
  5. จำกัดสิทธิ์ Jenkins User และ Agent
  6. อัปเดต Jenkins และ Plugins อย่างสม่ำเสมอ
  7. ตรวจสอบ Plugin ก่อนติดตั้ง
  8. แยก Jenkins Controller และ Build Agent ในระบบขนาดใหญ่
  9. ไม่เปิด Docker Socket หรือสิทธิ์ระดับสูงให้ Job โดยไม่จำเป็น
  10. พิจารณา GitHub App สำหรับระบบองค์กรที่ต้องการจัดการสิทธิ์แบบละเอียด

#18. ปัญหาที่พบบ่อย

#GitHub Webhook ไม่ Trigger Jenkins

ตรวจสอบ:

GitHub
→ Repository
→ Settings
→ Webhooks
→ Recent Deliveries

ตรวจสอบว่า Jenkins URL เข้าถึงจาก Internet ได้ และ Endpoint ถูกต้อง:

https://jenkins.example.com/github-webhook/

#Jenkins Clone Private Repository ไม่ได้

ตรวจสอบ:

  • Credential
  • Repository URL
  • Permission ของ Token/App/SSH Key
  • Credential ที่เลือกใน Jenkins Job

#docker: command not found

หมายความว่า Jenkins Agent ไม่มี Docker CLI หรือ PATH ไม่ถูกต้อง

ตรวจสอบ:

docker --version

#Jenkins ใช้ Docker ไม่ได้

ตรวจสอบสิทธิ์ของ User ที่ใช้รัน Jenkins และรูปแบบ Docker Runtime ที่เลือกใช้ ควรกำหนดสิทธิ์เท่าที่จำเป็นและหลีกเลี่ยงการให้สิทธิ์ระดับสูงโดยไม่มีเหตุผล


#19. Workshop แนะนำ

#Workshop 1: GitHub → Jenkins

เป้าหมาย:

GitHub
   |
   v
Jenkins
   |
   +--> Checkout
   +--> Build

เรียนรู้:

  • Jenkins Pipeline
  • Git SCM
  • Jenkinsfile

#Workshop 2: GitHub Webhook

เป้าหมาย:

git push
   |
   v
GitHub
   |
   v
Webhook
   |
   v
Jenkins Pipeline

เรียนรู้:

  • GitHub Webhook
  • Automated Build
  • Push Event

#Workshop 3: CI Pipeline

GitHub
   |
   v
Jenkins
   |
   +--> Checkout
   +--> Unit Test
   +--> Build

#Workshop 4: Docker CI/CD

GitHub
   |
   v
Jenkins
   |
   +--> Test
   +--> Build
   +--> Docker Build
   +--> Docker Push
   |
   v
Container Registry

#Workshop 5: Kubernetes และ GitOps

GitHub
   |
   v
Jenkins CI
   |
   v
Container Registry
   |
   v
GitOps Repository
   |
   v
Argo CD
   |
   v
Kubernetes

#20. สรุป

การเชื่อม Jenkins กับ GitHub ช่วยเปลี่ยนกระบวนการพัฒนาจากการ Build และ Deploy ด้วยมือไปเป็นระบบอัตโนมัติ

แนวคิดหลักคือ

Code
  ↓
GitHub
  ↓
Webhook
  ↓
Jenkins
  ↓
Test
  ↓
Build
  ↓
Docker
  ↓
Deploy

สำหรับผู้เริ่มต้นควรเริ่มจาก GitHub → Jenkins → Webhook → Test → Build ก่อน แล้วจึงขยายไปสู่ Docker, Container Registry, Kubernetes, SonarQube และ GitOps ตามลำดับ


#เอกสารอ้างอิง