الأتمتة8 دقيقة قراءة

استبدال ‎GitHub Actions‎ بـ‎Woodpecker CI‎ على ‎VPS

في ديسمبر 2025، أعلن ‎GitHub‎ فرض رسوم بالدقيقة على استخدام ‎self-hosted runners‎ في المستودعات الخاصة (نقاش المجتمع ‎#182089‎، 72 تصويتاً). في مواجهة ردود فعل مجتمعية واسعة، جرى تعليق هذه التسعيرة خلال 48 ساعة — وحتى 1 سبتمبر 2026، تبقى ‎self-hosted runners‎ مجانية ولم تُطبَّق الرسوم قط. غير أن التهديد حقيقي: لا شيء يمنع ‎GitHub‎ من إعادة تفعيلها. الانتقال إلى ‎Woodpecker CI‎ هو الحماية من الإعلان التالي — مع استعادة السيادة الكاملة على ‎CI/CD‎. ‎Woodpecker CI‎ هو بديل مفتوح المصدر يعمل في أقل من ‎50 Mo‎ من الذاكرة العشوائية، ويتصل بـ‎Gitea‎ أو ‎Forgejo‎ عبر ‎OAuth2‎، ولا يُكلّفك سوى ‎VPS‎.

‎GitHub‎ والتسعير: ما الذي حدث بين 2025 و2026

حتى عام 2025، كانت المستودعات الخاصة تستفيد من حصة شهرية من الدقائق المدرجة. في 16 ديسمبر 2025، أعلن ‎GitHub‎ تسعيراً بالدقيقة لاستخدام المشغّلات — بما فيها ‎self-hosted runners‎ التي تعمل على خوادمك الخاصة. نقاش ‎GitHub‎ رقم ‎#182089‎ (ديسمبر 2025، 72 تصويتاً) يلخّص القلق: كانت الفرق ستدفع لـ‎GitHub‎ لتنسيق مهمة تعمل على بنيتها التحتية الخاصة، بـ0.002 $ في الدقيقة.

في مواجهة ردود فعل مجتمعية واسعة، علّق ‎GitHub‎ هذه التسعيرة خلال 48 ساعة. حتى 1 سبتمبر 2026، تبقى ‎self-hosted runners‎ على المستودعات الخاصة مجانية — لم تُطبَّق هذه الإجراءات قط. لكن الإعلان كشف عن تبعية هيكلية: ‎GitHub‎ قادر على تغيير شروطه في أي وقت. نقل سلسلة ‎CI/CD‎ بالكامل إلى مستودع ذاتي الاستضافة هو الطريقة للتحرر من هذا الغموض. ‎Woodpecker CI‎ مُصمَّم تحديداً لهذا الغرض: محرك ‎pipeline‎ خفيف، مفتوح المصدر (‎Apache 2.0‎)، يُثبَّت إلى جانب ‎Gitea‎ أو ‎Forgejo‎ ولا يعرف عدّاد دقائق.

‎GitHub Actions runners‎ مقابل ‎Woodpecker CI‎ ذاتي الاستضافة

المعيار‎GitHub Actions‎ (مشغّلات سحابية)‎Woodpecker CI‎ على ‎VPS‎
التكلفة‎0.008 $‎ / دقيقة (‎Linux‎) + ‎0.002 $‎ / دقيقة تنسيق على المستودعات الخاصةمشمولة في التكلفة الثابتة لـ‎VPS‎ (ابتداءً من ‎`{{vps.start.price}}`‎)
ذاكرة محرك ‎CI‎مشغّلات ‎GitHub‎: موارد مشتركة غير خاضعة للتحكمخادم ‎Woodpecker‎ + وكيل: أقل من ‎50 Mo‎ مجتمعَين
السيادةالكود والأسرار تمر عبر بنية ‎GitHub/Microsoft‎كل شيء يبقى على ‎VPS‎ الخاص بك — لا عبور خارجي
صيغة سير العمل‎`.github/workflows/*.yml`‎ — معيار واسع الانتشار‎`.woodpecker.yml`‎ — صيغة خاصة، أقصر، غير متوافقة مع ‎GitHub Actions‎
متطلب المستودعلا شيء (‎GitHub‎ يستضيف المستودع)‎Gitea‎ أو ‎Forgejo‎ ذاتي الاستضافة
الرخصةملكية خاصة‎Apache 2.0‎

المتطلبات الأساسية قبل التثبيت

للنشر المريح لـ‎Woodpecker CI‎، تحقّق من النقاط التالية.

‎VPS‎: نواة واحدة و1 ‎Go‎ من الذاكرة تكفي لخادم ‎Woodpecker‎ ووكيل واحد ومستودع ‎Gitea‎ أو ‎Forgejo‎ خفيف. خطّط لـ2 ‎Go‎ إذا كنت تُشغّل عدة عمليات بناء متوازية أو تُجمّع صور ‎Docker‎.

البرمجيات: يجب تثبيت ‎Docker‎ و‎Docker Compose‎. إذا كنت تبدأ من ‎VPS‎ نظيف، يغطي دليل البداية مع ‎Docker‎ على ‎VPS‎ هذه الخطوة.

مستودع ‎git‎: يعتمد ‎Woodpecker CI‎ على ‎OAuth2‎ للمصادقة. تحتاج إلى نسخة ‎Gitea‎ أو ‎Forgejo‎ تعمل بالفعل ومتاحة عبر ‎HTTPS‎. يتوفر دليل استضافة ‎Gitea‎ ودليل استضافة ‎Forgejo‎.

النطاق: أعدّ نطاقاً فرعياً مخصصاً لـ‎Woodpecker‎ — مثل ci.your-domain.com — يشير إلى ‎IP‎ خادمك مع فتح المنفذ ‎443‎. هذا النطاق يُستخدم كـ‎WOODPECKER_HOST‎ وعنوان إعادة توجيه ‎OAuth2‎.

تثبيت ‎Woodpecker CI‎ باستخدام ‎Docker Compose‎

01

إنشاء تطبيق ‎OAuth2‎ في ‎Gitea‎

في ‎Gitea‎، انتقل إلى الإعدادات ← التطبيقات ← إدارة تطبيقات ‎OAuth2‎. أعطِ التطبيق اسماً (مثلاً woodpecker) وأدخل عنوان إعادة التوجيه: https://ci.your-domain.com/authorize. دوّن ‎Client ID‎ و‎Client Secret‎ المُولَّدَين — ستحتاجهما في الخطوة التالية.

إذا كنت تستخدم ‎Forgejo‎، الإجراء مطابق: الإعدادات ← التطبيقات ← ‎OAuth2‎.

02

إنشاء ملف ‎docker-compose.yml‎

أنشئ المجلد /opt/woodpecker وضع فيه ملف docker-compose.yml بالخدمتين — الخادم والوكيل:

services:
  woodpecker-server:
    image: woodpeckerci/woodpecker-server:v3
    restart: always
    ports:
      - "8000:8000"
    volumes:
      - woodpecker-server-data:/var/lib/woodpecker/
    environment:
      - WOODPECKER_OPEN=false
      - WOODPECKER_HOST=https://ci.your-domain.com
      - WOODPECKER_GITEA=true
      - WOODPECKER_GITEA_URL=https://git.your-domain.com
      - WOODPECKER_GITEA_CLIENT=${WOODPECKER_GITEA_CLIENT}
      - WOODPECKER_GITEA_SECRET=${WOODPECKER_GITEA_SECRET}
      - WOODPECKER_AGENT_SECRET=${WOODPECKER_AGENT_SECRET}

  woodpecker-agent:
    image: woodpeckerci/woodpecker-agent:v3
    restart: always
    command: agent
    depends_on:
      - woodpecker-server
    volumes:
      - woodpecker-agent-config:/etc/woodpecker
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
      - WOODPECKER_SERVER=woodpecker-server:9000
      - WOODPECKER_AGENT_SECRET=${WOODPECKER_AGENT_SECRET}

volumes:
  woodpecker-server-data:
  woodpecker-agent-config:

الخادم يستمع داخلياً على المنفذ ‎8000‎ (واجهة الويب) و‎9000‎ (‎gRPC‎، تواصل الوكيل). لا تكشف هذه المنافذ مباشرة: وكيل عكسي يتولى ‎TLS‎.

03

إنشاء ملف ‎.env‎

في /opt/woodpecker، أنشئ ملف .env يحتوي على المتغيرات الثلاثة الحساسة:

WOODPECKER_GITEA_CLIENT=<oauth2-client-id>
WOODPECKER_GITEA_SECRET=<oauth2-client-secret>
WOODPECKER_AGENT_SECRET=<سلسلة-عشوائية-طويلة>

أنشئ WOODPECKER_AGENT_SECRET بـ openssl rand -hex 32. هذه السلسلة تُصادق الوكيل لدى الخادم — لا تشاركها.

04

إعداد الوكيل العكسي ‎nginx‎

ضع ‎Woodpecker‎ خلف ‎nginx‎ مع شهادة ‎Let's Encrypt‎. مثال على كتلة server لـ ci.your-domain.com:

server {
    listen 443 ssl;
    server_name ci.your-domain.com;
    ssl_certificate /etc/letsencrypt/live/ci.your-domain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/ci.your-domain.com/privkey.pem;
    location / {
        proxy_pass http://127.0.0.1:8000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-Proto https;
    }
}

aحصل على الشهادة بـ certbot certonly --nginx -d ci.your-domain.com ثم أعد تحميل ‎nginx‎ بـ systemctl reload nginx.

05

تشغيل الحزمة

من /opt/woodpecker، شغّل:

docker compose up -d

تابع سجلات الخادم حتى تظهر رسالة الجاهزية:

docker compose logs -f woodpecker-server

افتح https://ci.your-domain.com في متصفحك. تظهر صفحة تسجيل الدخول بزر تسجيل الدخول عبر ‎Gitea‎. انقر عليه: يطلب ‎Gitea‎ الإذن بـ‎OAuth2‎، ثم يعيد توجيهك إلى لوحة تحكم ‎Woodpecker‎.

06

تفعيل مستودع وتشغيل أول بناء

في لوحة تحكم ‎Woodpecker‎، انقر على + إضافة مستودع. تظهر قائمة مستودعات ‎Gitea‎ الخاصة بك. اختر مشروعاً وفعّله. يُسجّل ‎Woodpecker‎ تلقائياً ‎webhook‎ في ‎Gitea‎ لتشغيل عمليات البناء عند كل push.

ادفع أول ‎commit‎ إلى هذا المستودع: إذا كان ملف .woodpecker.yml موجوداً في الجذر، يُشغَّل الـ‎pipeline‎ فوراً في الواجهة.

ترحيل سير عمل ‎GitHub Actions‎ إلى ‎.woodpecker.yml‎

لـ‎Woodpecker CI‎ صيغة ‎YAML‎ خاصة به — غير متوافقة مع ‎GitHub Actions‎. الخبر الجيد: إنها أقصر. إليك ترحيل سير عمل ‎Node.js‎ كلاسيكي.

قبل — .github/workflows/ci.yml:

name: CI
on: [push, pull_request]
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '20'
      - run: npm ci
      - run: npm test

بعد — .woodpecker.yml:

steps:
  - name: test
    image: node:20
    commands:
      - npm ci
      - npm test

الاختلافات الرئيسية: يستخدم ‎Woodpecker‎ صورة ‎Docker‎ مباشرة كبيئة تنفيذ (لا حاجة لـsetup-node)، وكل خطوة هي حاوية منفصلة. إجراء checkout ضمني — يستنسخ ‎Woodpecker‎ المستودع تلقائياً في مساحة العمل المشتركة بين الخطوات.

أسرار الـ‎pipeline‎ ومتغير ‎WOODPECKER_SECRET‎

لا تضع رموز الوصول أو مفاتيح ‎SSH‎ أو كلمات المرور في ملف .woodpecker.yml المُدار بالإصدار. تُدير ‎Woodpecker‎ الأسرار على مستوى المستودع أو المؤسسة: في لوحة التحكم، افتح المستودع ← الإعدادات ← الأسرار ← إضافة سر. كل سر يُحقَن كمتغير بيئة وقت البناء.

لاستخدام سر في الـ‎pipeline‎:

steps:
  - name: deploy
    image: alpine
    environment:
      SSH_DEPLOY_KEY:
        from_secret: ssh_deploy_key
    commands:
      - echo "$SSH_DEPLOY_KEY" > /tmp/id_rsa
      - chmod 600 /tmp/id_rsa
      - ssh -i /tmp/id_rsa [email protected] ./deploy.sh

صيغة from_secret تستخرج القيمة من خزنة ‎Woodpecker‎ دون كتابتها في السجلات أو ملف ‎YAML‎.

استكشاف الأخطاء الشائعة

الوكيل لا يظهر في لوحة التحكم. تحقّق من أن WOODPECKER_AGENT_SECRET متطابق في كلتا الخدمتين في docker-compose.yml. إذا عدّلت .env بعد الإطلاق الأول، أعد التشغيل بـ docker compose down && docker compose up -d.

تسجيل الدخول عبر ‎OAuth2‎ يفشل. يجب أن يطابق عنوان إعادة التوجيه المسجّل في ‎Gitea‎ تماماً https://ci.your-domain.com/authorize. شرطة مائلة إضافية أو خطأ إملائي أو ‎HTTP‎ بدلاً من ‎HTTPS‎ يكفي لإيقاف تدفق ‎OAuth2‎. تحقّق أيضاً من أن WOODPECKER_GITEA_URL يشير إلى عنوان ‎URL‎ العام لـ‎Gitea‎.

الـ‎webhook‎ لا يُشغَّل. افتح المستودع في ‎Gitea‎ ← الإعدادات ← ‎Webhooks‎ وتحقّق من وجود ‎webhook‎ ‎Woodpecker‎ وخلوّ عمليات التسليم الأخيرة من أخطاء ‎4xx‎.

البناء يفشل بسبب نفاد الذاكرة. يستهلك خادم ‎Woodpecker‎ والوكيل أقل من ‎50 Mo‎ في وضع الخمول — لكن كل خطوة بناء تُطلق حاوية ‎Docker‎ إضافية. على ‎VPS‎ بـ1 ‎Go‎، قيّد عمليات البناء المتزامنة بإضافة WOODPECKER_MAX_PROCS=2 إلى بيئة خدمة woodpecker-agent.

للمزيد من التعمق

بمجرد أن يعمل الـ‎pipeline‎ الأساسي، تستحق عدة تحسينات الاستكشاف.

مشغّلات متعددة. أضف خدمة woodpecker-agent ثانية إلى docker-compose.yml (نفس الصورة، نفس WOODPECKER_AGENT_SECRET) لتوازي عمليات البناء.

ذاكرة تخزين مؤقت ‎Docker‎ بين عمليات البناء. ثبّت حجم ‎Docker‎ في الوكيل وفعّل التخزين المؤقت لطبقات ‎Docker‎ لتجنب إعادة تنزيل الصور عند كل بناء.

الإشعارات. يدعم ‎Woodpecker‎ إشعارات قنوات المراسلة عند كل بناء — ‎Matrix‎ و‎Slack‎ و‎Telegram‎ و‎Mattermost‎.

‎pipeline‎ شرطي. تتيح صيغة ‎Woodpecker‎ تقييد خطوة على فرع أو حدث محدد:

steps:
  - name: deploy
    image: alpine
    when:
      branch: main
      event: push
    commands:
      - ./deploy.sh

للتعمق في إعداد الـ‎pipelines‎، يُفصّل دليل ‎Woodpecker CI‎ و‎Forgejo‎: ‎pipeline CI/CD‎ على ‎VPS‎ الخطوات المتقدمة.

‎VPS ServOrbit‎ لخطوط ‎CI/CD‎ الخاصة بك

خطة `{{vps.start.name}}` بسعر `{{vps.start.price}}` — نواة واحدة، 1 ‎Go‎ ذاكرة، ‎IP‎ ثابتة — تكفي لتشغيل ‎Woodpecker CI‎ ووكيل ومستودع ‎Gitea‎ معاً، بلا عدّاد دقائق.

مقالات ذات صلة

بحاجة إلى مساعدة؟

تصفّح مركز المساعدة والأسئلة الشائعة، أو تواصل مع فريقنا — معاودة اتصال أو WhatsApp أو بريد إلكتروني. الدعم بـالعربية والفرنسية والإنجليزية.

راسلنا على WhatsAppيُفتح في علامة تبويب جديدة