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
إنشاء تطبيق OAuth2 في Gitea
في Gitea، انتقل إلى الإعدادات ← التطبيقات ← إدارة تطبيقات OAuth2. أعطِ التطبيق اسماً (مثلاً woodpecker) وأدخل عنوان إعادة التوجيه: https://ci.your-domain.com/authorize. دوّن Client ID وClient Secret المُولَّدَين — ستحتاجهما في الخطوة التالية.
إذا كنت تستخدم Forgejo، الإجراء مطابق: الإعدادات ← التطبيقات ← OAuth2.
إنشاء ملف 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.
إنشاء ملف .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. هذه السلسلة تُصادق الوكيل لدى الخادم — لا تشاركها.
إعداد الوكيل العكسي 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.
تشغيل الحزمة
من /opt/woodpecker، شغّل:
docker compose up -dتابع سجلات الخادم حتى تظهر رسالة الجاهزية:
docker compose logs -f woodpecker-serverافتح https://ci.your-domain.com في متصفحك. تظهر صفحة تسجيل الدخول بزر تسجيل الدخول عبر Gitea. انقر عليه: يطلب Gitea الإذن بـOAuth2، ثم يعيد توجيهك إلى لوحة تحكم Woodpecker.
تفعيل مستودع وتشغيل أول بناء
في لوحة تحكم 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 الخطوات المتقدمة.