ติดตั้ง Drone CI CD Pipeline บน VPS

ติดตั้ง Drone CI CD Pipeline บน VPS

มิถุนายน 2026 · อ่าน 8 นาที

Drone CI เป็น platform สำหรับ continuous integration และ continuous deployment (CI/CD) ที่ใช้งานง่ายและมีความยืดหยุ่นสูง รองรับการเชื่อมต่อกับ GitHub, GitLab, Gitea และ Bitbucket ได้ทำให้เป็นตัวเลือกยอดนิยมสำหรับการ automate build, test และ deploy ของโปรเจกต์ ในบทความนี้เราจะสอนวิธีการติดตั้ง Drone CI บน VPS แบบ self-hosted พร้อมการตั้งค่า Docker runner เพื่อ execute pipeline ของคุณ

ความต้องการของระบบ

ก่อนเริ่มติดตั้ง Drone CI คุณจำเป็นต้องมีสิ่งต่อไปนี้:

ติดตั้ง Docker และ Docker Compose

Drone CI ทำงานบน Docker ดังนั้นจำเป็นต้องติดตั้ง Docker ก่อน หากคุณยังไม่มี Docker ให้รัน commands ต่อไปนี้:

สำหรับ Ubuntu/Debian:

sudo apt-get update
sudo apt-get install -y docker.io docker-compose
sudo usermod -aG docker $USER
newgrp docker

สำหรับ CentOS/RHEL 7:

sudo yum install -y docker
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
sudo systemctl start docker
sudo usermod -aG docker $USER

สำหรับ CentOS/RHEL 8+:

sudo dnf install -y docker podman-docker
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
sudo systemctl start docker
sudo usermod -aG docker $USER

ตรวจสอบว่า Docker ทำงานได้:

docker --version
docker-compose --version
docker run hello-world

ดาวน์โหลดและติดตั้ง Drone Server

เราจะสร้าง directory สำหรับ Drone server และเตรียม docker-compose configuration file:

mkdir -p ~/drone-ci
cd ~/drone-ci

สร้าง docker-compose.yml ด้วย command ต่อไปนี้:

cat > docker-compose.yml << 'EOF'
version: '3.8'

services:
  drone-server:
    image: drone/drone:latest
    container_name: drone-server
    ports:
      - "80:80"
      - "443:443"
    environment:
      DRONE_SERVER_HOST: ci.yourdomain.com
      DRONE_SERVER_PROTO: https
      DRONE_RPC_SECRET: $(openssl rand -hex 16)
      DRONE_GITHUB_CLIENT_ID: your_github_client_id
      DRONE_GITHUB_CLIENT_SECRET: your_github_client_secret
      DRONE_AGENTS_ENABLED: true
      DRONE_USER_CREATE: username:admin,machine:false,admin:true
    volumes:
      - ./data:/data
      - /var/run/docker.sock:/var/run/docker.sock
    restart: always

  drone-runner:
    image: drone/drone-runner-docker:latest
    container_name: drone-runner
    depends_on:
      - drone-server
    environment:
      DRONE_RPC_HOST: drone-server
      DRONE_RPC_PROTO: http
      DRONE_RPC_SECRET: $(openssl rand -hex 16)
      DRONE_RUNNER_CAPACITY: 2
      DRONE_RUNNER_NAME: runner-1
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    restart: always
    networks:
      - drone-network

networks:
  drone-network:
    driver: bridge
EOF
หมายเหตุ: เมื่อสร้าง docker-compose.yml นี้ตรวจสอบให้แน่ใจว่าเปลี่ยน ci.yourdomain.com เป็นโดเมนจริงของคุณ และเพิ่มค่า GitHub OAuth credentials ลงไป

ตั้งค่า Drone Server กับ GitHub

หากคุณต้องการเชื่อมต่อ Drone กับ GitHub จะต้องสร้าง OAuth application ก่อน:

  1. ไปที่ GitHub Settings › Developer settings › OAuth Apps
  2. คลิก "New OAuth App"
  3. ใส่ข้อมูลดังนี้:
    • Application name: Drone CI
    • Homepage URL: https://ci.yourdomain.com
    • Authorization callback URL: https://ci.yourdomain.com/login/oauth/github
  4. คลิก "Register application" เพื่อรับ Client ID และ Client Secret

นำค่า Client ID และ Client Secret ไปใส่ในไฟล์ docker-compose.yml:

DRONE_GITHUB_CLIENT_ID: [your-github-client-id]
DRONE_GITHUB_CLIENT_SECRET: [your-github-client-secret]

สำหรับการเชื่อมต่อกับ Gitea ให้แทนที่ environment variables เหล่านี้:

DRONE_GITEA_SERVER: https://gitea.yourdomain.com
DRONE_GITEA_CLIENT_ID: your_gitea_client_id
DRONE_GITEA_CLIENT_SECRET: your_gitea_client_secret

เริ่มต้นบริการ Drone Server

เมื่อตั้งค่า docker-compose.yml เสร็จแล้ว ให้เริ่มบริการด้วย command:

cd ~/drone-ci
docker-compose up -d

ตรวจสอบว่า container ทำงานอยู่:

docker-compose ps
docker logs drone-server
docker logs drone-runner

ติดตั้ง Drone Runner

Drone Runner เป็น agent ที่รับหน้าที่ execute pipeline jobs หากใช้ docker-compose setup ข้างต้นแล้ว runner จะติดตั้งไปพร้อมกันเลย แต่หากต้องการติดตั้ง runner แยกต่างหากบนเครื่องอื่น สามารถทำได้ดังนี้:

mkdir -p ~/drone-runner
cd ~/drone-runner

cat > docker-compose.yml << 'EOF'
version: '3.8'

services:
  drone-runner:
    image: drone/drone-runner-docker:latest
    container_name: drone-runner
    environment:
      DRONE_RPC_HOST: drone-server-ip:80
      DRONE_RPC_PROTO: http
      DRONE_RPC_SECRET: your-rpc-secret-here
      DRONE_RUNNER_CAPACITY: 2
      DRONE_RUNNER_NAME: runner-remote-1
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    restart: always
EOF

docker-compose up -d
สำคัญ: ค่า DRONE_RPC_SECRET ต้องตรงกับที่กำหนดใน drone-server ถึงจะสื่อสารกันได้

สร้าง .drone.yml Pipeline Configuration

ในหน้าที่ repository ของคุณ สร้างไฟล์ .drone.yml เพื่อกำหนด pipeline steps:

kind: pipeline
type: docker
name: default

steps:
  - name: test
    image: node:16
    commands:
      - npm install
      - npm run test

  - name: build
    image: node:16
    commands:
      - npm run build

  - name: deploy
    image: alpine:latest
    commands:
      - echo "Deploying to production..."
      - apk add --no-cache curl
      - curl -X POST https://deploy.yourdomain.com/webhook

trigger:
  branch:
    - main
  event:
    - push
    - pull_request

ตัวอย่าง pipeline ที่มีหลายขั้นตอนและเงื่อนไข:

kind: pipeline
type: docker
name: full-pipeline

steps:
  - name: checkout
    image: alpine/git
    commands:
      - git clone $DRONE_GIT_HTTP_URL .
      - git checkout $DRONE_COMMIT

  - name: lint
    image: node:16
    commands:
      - npm install
      - npm run lint

  - name: unit-tests
    image: node:16
    commands:
      - npm test

  - name: build-image
    image: plugins/docker
    settings:
      username:
        from_secret: docker_username
      password:
        from_secret: docker_password
      repo: your-docker-repo/app
      tags: latest,${DRONE_COMMIT_SHA:0:7}

  - name: deploy-staging
    image: alpine:latest
    environment:
      DEPLOY_TOKEN:
        from_secret: deploy_token
    commands:
      - apk add --no-cache curl
      - curl -X POST https://staging-deploy.yourdomain.com/webhook -d "token=$DEPLOY_TOKEN"
    when:
      branch: main
      event: push

  - name: notify
    image: plugins/slack
    settings:
      webhook:
        from_secret: slack_webhook
      message: "Pipeline completed for $${DRONE_BRANCH}"
    when:
      status:
        - success
        - failure

trigger:
  branch:
    - main
    - develop
  event:
    - push
    - pull_request
    - tag

ตรวจสอบว่า Drone ทำงานถูกต้อง

เมื่อติดตั้งเสร็จแล้ว ให้ตรวจสอบว่า Drone ทำงานถูกต้องด้วยคำสั่งต่อไปนี้:

ตรวจสอบ Drone Server API:

curl -s http://localhost/api/version | jq .

ผลลัพธ์ที่เป็นปกติจะเป็นเช่นนี้:

{
  "version": "2.11.0"
}

ตรวจสอบ Docker logs:

docker logs drone-server | tail -20
docker logs drone-runner | tail -20

เข้าถึง Web Interface:

เปิด browser และเข้าที่ https://ci.yourdomain.com จากนั้นใช้บัญชี GitHub หรือ Gitea ของคุณเข้าสู่ระบบ

ทดสอบ Pipeline:

cd /path/to/your-repo
git add .drone.yml
git commit -m "Add Drone CI configuration"
git push origin main

ไปที่ Drone web UI และตรวจสอบว่า pipeline trigger ทำงานโดยอัตโนมัติเมื่อ push code

Tip: หากต้องการดู logs ของ pipeline ที่กำลังทำงาน ให้คลิกที่ build number ใน Drone UI

แก้ปัญหาที่พบบ่อย

ข้อผิดพลาด: DRONE_RPC_SECRET mismatch

เมื่อ drone-runner ไม่สามารถเชื่อมต่อกับ drone-server ได้ log จะแสดงข้อความเช่น:

ERROR client: 401 Unauthorized: invalid rpc secret

วิธีแก้: ตรวจสอบว่า DRONE_RPC_SECRET ใน docker-compose.yml ของ server และ runner ตรงกันหรือไม่ ทั้งสองต้องใช้ค่าเดียวกันเท่านั้น

ข้อผิดพลาด: GitHub OAuth not working

ถ้าเมื่อ login ด้วย GitHub ปรากฏข้อผิดพลาด ให้ตรวจสอบ:

docker logs drone-server | grep -i "oauth\|auth\|github"

วิธีแก้: ตรวจสอบว่า Client ID และ Client Secret ถูกต้องและตรงกับที่กำหนดไว้ใน GitHub Developer Settings นอกจากนี้ต้องแน่ใจว่า Authorization callback URL ตรงกับ https://ci.yourdomain.com/login/oauth/github

ข้อผิดพลาด: Pipeline not triggering

ถ้าสร้าง .drone.yml แล้ว push code แต่ pipeline ไม่ trigger ให้ตรวจสอบ:

docker logs drone-server | grep webhook
docker logs drone-server | grep trigger

วิธีแก้: ไปยัง GitHub repository Settings › Webhooks และตรวจสอบว่ามี webhook ของ Drone อยู่ หากไม่มี ให้ดำเนินการ re-sync ใน Drone UI โดยไปที่ repository settings และคลิก "Sync"

ข้อผิดพลาด: Docker image pull timeout

เมื่อ pipeline ติด error เช่น:

Error response from daemon: pull access denied for node:16, repository does not exist

วิธีแก้: ตรวจสอบการเชื่อมต่อ internet ของ VPS ว่าสามารถ pull docker images ได้หรือไม่ ลองทดสอบด้วยคำสั่ง:

docker pull node:16

คำถามที่พบบ่อย

สามารถใช้ Drone CI กับหลายๆ repository พร้อมกันได้หรือไม่?

ได้ครับ Drone CI สามารถใช้ได้กับหลายๆ repository พร้อมกัน แต่ความสามารถในการ execute job พร้อมกันจะขึ้นอยู่กับค่า DRONE_RUNNER_CAPACITY หากคุณตั้ง capacity เป็น 2 แสดงว่าสามารถ execute 2 jobs พร้อมกันได้เท่านั้น หากต้องการ execute มากกว่านั้น ให้เพิ่มค่านี้หรือเพิ่ม runners เพิ่มเติม

วิธีตั้งค่า HTTPS/SSL สำหรับ Drone CI ด้วย Let's Encrypt?

สามารถใช้ reverse proxy อย่าง Nginx หรือ Caddy เพื่อ terminate SSL ได้ ตัวอย่างการใช้ Caddy:

cat > ~/drone-ci/Caddyfile << 'EOF'
ci.yourdomain.com {
    reverse_proxy localhost:80
}
EOF

จากนั้นเพิ่ม Caddy service ในไฟล์ docker-compose.yml และเพิ่ม Caddy container ในการเริ่มบริการ

วิธีเชื่อมต่อ Drone CI กับ self-hosted Git server เช่น Gitea?

ใช้ environment variables ต่อไปนี้แทน GitHub:

DRONE_GITEA_SERVER: https://gitea.yourdomain.com
DRONE_GITEA_CLIENT_ID: [your-gitea-oauth-client-id]
DRONE_GITEA_CLIENT_SECRET: [your-gitea-oauth-client-secret]

วิธีสร้าง OAuth application ใน Gitea นั้นให้ไปที่ Gitea Admin › Applications › Create OAuth 2.0 Application และกรอกข้อมูลคล้ายกับการสร้างใน GitHub