CircleCI Orbs คืออะไร
CircleCI Orbs เป็น Reusable Configuration Packages ที่รวม Jobs, Commands และ Executors ไว้ด้วยกัน ช่วยให้ทีมไม่ต้องเขียน CI/CD Config ซ้ำๆ ตัวอย่างเช่น AWS Orb ช่วยให้ Deploy ไป AWS ได้โดยไม่ต้องเขียน AWS CLI Setup เอง Docker Orb ช่วย Build และ Push Image โดยไม่ต้อง Config Docker Login เอง
แม้ Orbs จะช่วยประหยัดเวลา แต่ก็มีปัญหาที่พบบ่อยหลายอย่าง ตั้งแต่ Version Conflicts, Permission Errors ไปจนถึง Caching Issues บทความนี้รวบรวมปัญหาที่พบบ่อยและวิธีแก้ไขทั้งหมด
ปัญหาที่ 1 — Orb Version Conflicts
# === ปัญหา: Orb Version ไม่ Compatible กับ Config ===
# config.yml ที่มีปัญหา
version: 2.1
orbs:
aws-cli: circleci/aws-cli@4.1.3 # ต้องการ config version 2.1
node: circleci/node@5.2.0
# Error: "Orb 'circleci/aws-cli@4.1.3' requires config version 2.1"
# วิธีแก้ 1: ตรวจสอบ Config Version
# ต้องใช้ version: 2.1 เสมอเมื่อใช้ Orbs
version: 2.1 # ต้องเป็น 2.1 ไม่ใช่ 2.0 หรือ 2
# วิธีแก้ 2: ตรวจสอบ Orb Compatibility
circleci orb info circleci/aws-cli@4.1.3
# จะแสดง Dependencies และ Requirements
# วิธีแก้ 3: ใช้ Orb Version ที่ Pinned
# ดี: Pinned Version
orbs:
aws-cli: circleci/aws-cli@4.1.3
# ไม่ดี: Volatile Tag (อาจ Break Build)
orbs:
aws-cli: circleci/aws-cli@volatile
# วิธีแก้ 4: Validate Config ก่อน Push
circleci config validate .circleci/config.yml
# ถ้ามี Error จะแสดงทันที
# วิธีแก้ 5: Process Config เพื่อดู Expanded Version
circleci config process .circleci/config.yml > processed.yml
# ดู Expanded Config ที่ Orbs ถูก Inline แล้ว
# === ปัญหา: Multiple Orbs ใช้ Same Executor ===
# Error: "Executor 'default' is defined in multiple orbs"
# วิธีแก้: ใช้ Orb Prefix
jobs:
build:
executor: node/default # ใช้ Executor จาก Node Orb
deploy:
executor: aws-cli/default # ใช้ Executor จาก AWS Orb
ปัญหาที่ 2 — Permission และ Authentication Errors
# === ปัญหา: Private Orb Access Denied ===
# Error: "Could not find orb 'myorg/private-orb@1.0.0'"
# วิธีแก้ 1: ตรวจสอบ Organization Settings
# CircleCI Dashboard > Organization Settings > Security
# Enable "Allow Uncertified Orbs" ถ้าใช้ Third-party Orbs
# Enable "Allow Private Orbs" ถ้าใช้ Private Orbs
# วิธีแก้ 2: ตรวจสอบ API Token
circleci setup
# ใส่ Personal API Token ที่มี Orb Access
# === ปัญหา: AWS Credentials ไม่ทำงานใน Orb ===
# Error: "Unable to locate credentials"
# วิธีแก้: ตั้ง Environment Variables ที่ถูกต้อง
# CircleCI Dashboard > Project Settings > Environment Variables
# ตั้งค่า:
# AWS_ACCESS_KEY_ID
# AWS_SECRET_ACCESS_KEY
# AWS_DEFAULT_REGION
# ตัวอย่าง Config ที่ถูกต้อง
version: 2.1
orbs:
aws-cli: circleci/aws-cli@4.1.3
jobs:
deploy:
executor: aws-cli/default
steps:
- checkout
- aws-cli/setup:
role_arn: "arn:aws:iam::123456789:role/deploy-role"
# ใช้ OIDC แทน Static Credentials (ปลอดภัยกว่า)
- run:
name: Deploy to S3
command: aws s3 sync ./build s3://my-bucket/
# === ปัญหา: Docker Hub Rate Limit ===
# Error: "toomanyrequests: You have reached your pull rate limit"
# วิธีแก้: ใช้ Docker Hub Credentials
version: 2.1
orbs:
docker: circleci/docker@2.6.0
jobs:
build:
executor: docker/docker
steps:
- checkout
- docker/check:
docker-username: DOCKERHUB_USERNAME # Env var name
docker-password: DOCKERHUB_TOKEN # Env var name
- docker/build:
image: myorg/myapp
tag:
- docker/push:
image: myorg/myapp
tag:
ปัญหาที่ 3 — Caching Issues
# === ปัญหา: Cache ไม่ Hit หรือ Restore ไม่ได้ ===
# วิธีแก้ 1: ตรวจสอบ Cache Key Pattern
version: 2.1
orbs:
node: circleci/node@5.2.0
jobs:
build:
executor: node/default
steps:
- checkout
# Cache Key ที่ดี — ใช้ Checksum ของ Lock File
- restore_cache:
keys:
- v2-deps-{{ checksum "package-lock.json" }}
- v2-deps- # Fallback
- node/install-packages:
pkg-manager: npm
- save_cache:
key: v2-deps-{{ checksum "package-lock.json" }}
paths:
- node_modules
- ~/.npm
# ปัญหาที่พบบ่อย:
# 1. Cache Key เปลี่ยนทุก Build → ไม่มี Hit
# แก้: ใช้ Checksum ของ Lock File ไม่ใช่ Branch Name
# 2. Cache Size ใหญ่เกินไป → Restore ช้า
# แก้: Cache เฉพาะ node_modules ไม่ Cache ทั้ง Project
# 3. Cache Version ไม่ตรง → ไม่ Restore
# แก้: เปลี่ยน Prefix (v1 → v2) เมื่อต้องการ Invalidate
# วิธีแก้ 2: Debug Cache
# เพิ่ม Step ดู Cache Status
- run:
name: Debug Cache
command: |
echo "Cache key: v2-deps-$(md5sum package-lock.json | cut -d' ' -f1)"
echo "node_modules exists: $(test -d node_modules && echo 'YES' || echo 'NO')"
echo "node_modules size: $(du -sh node_modules 2>/dev/null || echo 'N/A')"
# วิธีแก้ 3: Docker Layer Caching (DLC)
jobs:
build-image:
machine:
image: ubuntu-2204:current
docker_layer_caching: true # เปิด DLC (Paid Feature)
steps:
- checkout
- run:
name: Build Docker Image
command: docker build -t myapp:latest .
# DLC จะ Cache Docker Layers ระหว่าง Builds
# === ปัญหา: Workspace ไม่ส่งข้อมูลระหว่าง Jobs ===
# วิธีแก้: ใช้ persist_to_workspace และ attach_workspace
workflows:
build-test-deploy:
jobs:
- build:
# persist build artifacts
post-steps:
- persist_to_workspace:
root: .
paths:
- build/
- dist/
- test:
requires: [build]
pre-steps:
- attach_workspace:
at: .
Debug Techniques
# === Debug CircleCI Pipelines ===
# 1. Validate Config Locally
circleci config validate .circleci/config.yml
# 2. Process Config (ดู Expanded Orbs)
circleci config process .circleci/config.yml
# 3. Run Job Locally (Docker)
circleci local execute --job build
# 4. SSH Debug (เข้าไป Debug ใน Container)
# CircleCI Dashboard > Rerun Job with SSH
# จะได้ SSH Command เช่น:
# ssh -p 64535 xx.xx.xx.xx
# มีเวลา 2 ชั่วโมงก่อน Container ถูกลบ
# 5. Store Artifacts สำหรับ Debug
jobs:
test:
steps:
- run:
name: Run Tests
command: |
pytest --junitxml=test-results/results.xml \
--html=test-results/report.html \
-v 2>&1 | tee test-results/output.log
- store_test_results:
path: test-results
- store_artifacts:
path: test-results
destination: test-reports
# 6. Environment Variables Debug
- run:
name: Debug Environment
command: |
echo "Branch: $CIRCLE_BRANCH"
echo "SHA: $CIRCLE_SHA1"
echo "Build: $CIRCLE_BUILD_NUM"
echo "PR: $CIRCLE_PULL_REQUEST"
# ห้าม Print Secrets!
echo "AWS Key Set: $(test -n \"$AWS_ACCESS_KEY_ID\" && echo YES || echo NO)"
# 7. Timing Debug
- run:
name: Check Timing
command: |
START=$(date +%s)
npm run build
END=$(date +%s)
echo "Build took $((END-START)) seconds"
# === Python Script วิเคราะห์ CircleCI Build History ===
import requests
import json
from datetime import datetime
CIRCLECI_TOKEN = "your-token"
ORG = "github/myorg"
PROJECT = "myrepo"
def get_recent_pipelines(limit=20):
"""ดึง Pipeline ล่าสุดวิเคราะห์ปัญหา"""
url = f"https://circleci.com/api/v2/project/{ORG}/{PROJECT}/pipeline"
headers = {"Circle-Token": CIRCLECI_TOKEN}
resp = requests.get(url, headers=headers, params={"limit": limit})
pipelines = resp.json().get("items", [])
stats = {"success": 0, "failed": 0, "total_duration": 0}
failures = []
for p in pipelines:
pid = p["id"]
# Get workflows for pipeline
wf_url = f"https://circleci.com/api/v2/pipeline/{pid}/workflow"
wf_resp = requests.get(wf_url, headers=headers)
for wf in wf_resp.json().get("items", []):
if wf["status"] == "success":
stats["success"] += 1
elif wf["status"] == "failed":
stats["failed"] += 1
failures.append({
"pipeline_id": pid,
"workflow": wf["name"],
"branch": p.get("vcs", {}).get("branch", ""),
"created": p["created_at"],
})
total = stats["success"] + stats["failed"]
success_rate = (stats["success"] / total * 100) if total > 0 else 0
print(f"=== CircleCI Build Analysis ===")
print(f"Total Builds: {total}")
print(f"Success Rate: {success_rate:.1f}%")
print(f"Failed: {stats['failed']}")
if failures:
print(f"\nRecent Failures:")
for f in failures[:5]:
print(f" {f['created'][:10]} | {f['branch']} | {f['workflow']}")
get_recent_pipelines()
Best Practices สำหรับ CircleCI Orbs
- Pin Orb Versions: ใช้ Exact Version เช่น @4.1.3 ไม่ใช่ @4 หรือ @volatile ป้องกัน Breaking Changes
- Validate ก่อน Push: รัน circleci config validate ทุกครั้งก่อน Push ลด Wasted Build Minutes
- ใช้ OIDC: สำหรับ Cloud Provider Authentication แทน Static Credentials ปลอดภัยกว่า
- Cache อย่างมีกลยุทธ์: ใช้ Checksum ของ Lock File เป็น Cache Key มี Fallback Key
- แยก Workflows: แยก Build, Test, Deploy เป็น Jobs ต่างกัน ใช้ Workspace ส่งข้อมูล
- ตั้ง Resource Class: เลือก Resource Class ที่เหมาะสม ไม่ใช้ Large สำหรับ Job เล็กๆ
- Monitor Build Duration: ติดตาม Build Duration เมื่อเพิ่มขึ้นอาจมี Cache Issue
CircleCI Orbs คืออะไร
CircleCI Orbs เป็น Reusable Packages ของ CI/CD Configuration รวม Jobs, Commands และ Executors ไว้ด้วยกัน ช่วยลดการเขียน Config ซ้ำ มี Orbs สำหรับ AWS, Docker, Slack, Terraform และอื่นๆอีกมาก ใช้แค่ Reference แล้ว Config ไม่กี่บรรทัด
ปัญหาที่พบบ่อยกับ CircleCI Orbs มีอะไรบ้าง
Version Incompatibility กับ Config Version, Permission Errors เมื่อใช้ Private Orbs, Cache ไม่ Hit, Environment Variables ไม่ส่งไปยัง Orb Commands, Docker Rate Limit, Workspace ไม่ส่งข้อมูลระหว่าง Jobs และ Resource Class ไม่เหมาะสม
วิธี Debug CircleCI Pipeline ทำอย่างไร
ใช้ circleci config validate ตรวจ Config, circleci local execute รันบน Local, SSH Debug เข้าไปใน Container, store_artifacts เก็บ Log, circleci config process ดู Expanded Config และ Debug Environment Variables ดูว่าตั้งค่าถูกต้องหรือไม่
ควรใช้ Orb Version แบบไหน
Production ใช้ Pinned Version เช่น @4.1.3 ไม่ใช้ @volatile หรือ Major Version เช่น @4 เพราะอาจ Break Build Development ใช้ @dev:alpha ได้ ตรวจสอบ Orb Changelog ก่อนอัปเดต Version และทดสอบบน Branch ก่อน Merge
สรุป
CircleCI Orbs ช่วยประหยัดเวลาในการเขียน CI/CD Config แต่ต้องระวังปัญหาที่พบบ่อย สิ่งสำคัญคือ Pin Orb Versions เสมอ, Validate Config ก่อน Push, ใช้ OIDC สำหรับ Cloud Authentication, Cache อย่างมีกลยุทธ์ด้วย Checksum Keys และใช้ Debug Tools เช่น SSH Access, store_artifacts และ circleci config process เพื่อวิเคราะห์ปัญหาได้เร็ว
