لماذا تستضيف CI/CD الخاص بك مع Jenkins
خدمة CI المستضافة عملية إلى أن تتكاثر عمليات البناء: كل دقيقة بعد الحصة تُفوتر، والمشاريع الكبيرة تنتظر دورها، ومفاتيح نشر خوادمك مخزّنة لدى المزوّد. يقلب Jenkins هذا النموذج: يعمل على VPS الخاص بك، وينفّذ من عمليات البناء بقدر ما تسمح به أجهزتك، ويحفظ بيانات اعتمادك مشفّرة لديك.
وهو أيضًا الأداة التي تعرفها معظم الفرق: يُقرأ ملف Jenkinsfile دون تدريب، والتوثيق وفير، ولكل أداة تقريبًا في السوق إضافة لـ Jenkins.
ما يقدّمه Jenkins
- المسارات كشيفرة — ملف Jenkinsfile محفوظ مع المشروع يصف كل مرحلة، ويُراجع في مراجعة الشيفرة كبقية الملفات.
- webhooks من Git — تطلق GitHub وGitLab وGitea وForgejo عملية البناء عند كل push أو pull request.
- Multibranch — يحصل كل فرع وكل pull request على مسار خاص يُنشأ تلقائيًا.
- وكلاء البناء — تُنفَّذ عمليات البناء على أجهزة مخصّصة متصلة عبر SSH.
- أكثر من 2000 إضافة — Docker وKubernetes وSonarQube وSlack وتقارير اختبارات JUnit.
- بيانات اعتماد مشفّرة — مفاتيح SSH والرموز تُحقن في المسار وتُخفى في السجلات.
Jenkins مقارنةً بأدوات CI أخرى مستضافة ذاتيًا
مرّر الجدول أفقيًا
| Jenkins | Woodpecker CI | OneDev | |
|---|---|---|---|
| الرخصة | MIT | Apache-2.0 | MIT |
| تعريف المسار | Jenkinsfile (Groovy) | YAML | YAML أو محرر مرئي |
| منصة Git مدمجة | لا، يرتبط بمنصتك | لا، يرتبط بمنصتك | نعم |
| منظومة الإضافات | أكثر من 2000 إضافة | إضافات على شكل صور Docker | وظائف مدمجة |
| الأنسب لـ | مسارات معقدة وفرق قائمة | مسارات بسيطة داخل الحاويات | فريق صغير يريد حلًا متكاملًا |
المتطلبات
يكفي VPS بنظام Ubuntu 24.04 وذاكرة 2 غيغابايت ومعالجين افتراضيين لوحدة التحكم؛ احسب 4 غيغابايت إذا كانت عمليات البناء تعمل على الجهاز نفسه. تحتاج إلى Docker وإضافة Compose، واسم نطاق (أو نطاق فرعي) يشير إلى الخادم، وnginx مع شهادة TLS لنشره عبر HTTPS. يجب أن يستجيب Jenkins على عنوان HTTPS ثابت، فهو العنوان الذي تستدعيه مستودعاتك لإرسال webhooks.
تثبيت Jenkins باستخدام Docker Compose
إنشاء ملف Compose
يشغّل ملف
docker-compose.ymlهذا Jenkins LTS على Java 21. لا يُنشر المنفذ إلا على الواجهة المحلية، فلا يصل إليه سوى nginx. كل البيانات (المهام والإضافات وبيانات الاعتماد والسجل) موجودة في وحدة التخزينjenkins-home. لا يُنشر المنفذ 50000 الخاص بالوكلاء الواردين، إذ يتصل الوكلاء عبر SSH.services: jenkins: image: jenkins/jenkins:2.580.1-lts-jdk21 restart: unless-stopped ports: - "127.0.0.1:8104:8080" environment: JAVA_OPTS: -Djava.awt.headless=true volumes: - jenkins-home:/var/jenkins_home healthcheck: test: ["CMD-SHELL", "curl -fsS -o /dev/null http://localhost:8080/login || exit 1"] interval: 15s retries: 10 start_period: 60s volumes: jenkins-home: {}تشغيل الحاوية
ضع الملف في
/opt/jenkinsثم شغّل الحزمة. يستغرق التشغيل الأول نحو ثلاثين ثانية، ويجب أن يعرض الأمرdocker compose psالحالةhealthy.mkdir -p /opt/jenkins && cd /opt/jenkins docker compose up -d docker compose psنشر Jenkins عبر HTTPS خلف nginx
في كتلة
serverالخاصة بنطاقك، مرّر الترويساتX-Forwarded-*: بدونها يولّد Jenkins روابط HTTP ويشير إلى وكيل عكسي غير مضبوط.location / { proxy_pass http://127.0.0.1:8104; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Port 443; }فتح Jenkins
افتح
https://your-domain. يطلب Jenkins كلمة المرور الأولية المكتوبة في وحدة تخزين بياناته:docker compose exec jenkins cat /var/jenkins_home/secrets/initialAdminPasswordثم ثبّت الإضافات المقترحة وأنشئ حساب المدير وأكّد عنوان HTTPS للخادم.
لا تشغّل عمليات البناء على وحدة التحكم
تحتفظ وحدة التحكم في Jenkins بكل بيانات اعتمادك، وأي عملية بناء تعمل عليها يمكنها قراءتها. في «Manage Jenkins» اجعل عدد المنفّذين في العقدة المدمجة 0 واربط وكيلًا واحدًا على الأقل عبر SSH. وللسبب نفسه، لا تربط مقبس Docker الخاص بالخادم داخل حاوية Jenkins: فذلك يمنح أي عملية بناء صلاحيات root على الخادم.
كتابة أول مسار
أنشئ «Multibranch Pipeline» يشير إلى مستودعك، ثم أضف ملف Jenkinsfile في الجذر. يبني هذا المثال كل فرع ويختبره، ولا ينشر إلا الفرع main، على وكيل يحمل الوسم linux:
pipeline {
agent { label 'linux' }
stages {
stage('Build') { steps { sh 'make build' } }
stage('Test') { steps { sh 'make test' } }
stage('Deploy') {
when { branch 'main' }
steps { sh './deploy.sh' }
}
}
}أخيرًا، أضف webhook في مستودعك نحو https://your-domain/github-webhook/ بالنسبة إلى GitHub، أو نحو العنوان الذي تعطيه إضافة منصتك. عندها يطلق كل push عملية بناء.
بيانات الاعتماد ووكلاء البناء
تُحفظ مفاتيح SSH ورموز API وكلمات مرور النشر في «Manage Jenkins» ثم «Credentials». يخزّنها Jenkins مشفّرة في وحدة التخزين الخاصة به، ولا يحقنها في عملية البناء إلا عندما تطلبها مرحلة ما، عبر withCredentials أو التوجيه environment في ملف Jenkinsfile، وتُخفى قيمتها في السجلات. امنح كل بيان اعتماد أضيق نطاق ممكن: مفتاح نشر لكل خادم هدف، ورمز للقراءة فقط لاستنساخ المستودعات.
بالنسبة إلى الوكلاء، أبسط حل هو VPS ثانٍ مثبّت عليه Java وDocker. في «Manage Jenkins» ثم «Nodes»، أضف عقدة دائمة بطريقة التشغيل «via SSH» وعنوان الخادم ومفتاح SSH محفوظ كبيان اعتماد. امنحها وسمًا، مثل linux، واستهدفها في مساراتك. عندها تكتفي وحدة التحكم بالتنسيق، ولا تصل أي عملية بناء مخترقة إلى أسرارك الأخرى.
النسخ الاحتياطي لـ Jenkins وتحديثه
كل حالة Jenkins موجودة في وحدة التخزين jenkins-home: المهام والإعدادات والإضافات وبيانات الاعتماد المشفّرة وسجل عمليات البناء. يكفي أرشيف لهذه الوحدة لاستعادة كل شيء. أوقف Jenkins أثناء النسخ للحصول على أرشيف متّسق:
cd /opt/jenkins
docker compose stop jenkins
docker run --rm -v jenkins_jenkins-home:/data -v \"$PWD\":/backup alpine tar czf /backup/jenkins-home.tar.gz -C /data .
docker compose start jenkinsللتحديث، اتبع خط LTS الذي يصدر تقريبًا كل اثني عشر أسبوعًا مع تصحيحات بينية: استبدل وسم الصورة في docker-compose.yml ثم شغّل docker compose pull وdocker compose up -d. بعد ذلك حدّث الإضافات من «Manage Jenkins» ثم «Plugins»، واقرأ نشرات الأمان التي يصدرها المشروع: معظم الثغرات المصحّحة تخص الإضافات لا النواة.
استكشاف الأخطاء
«It appears that your reverse proxy set up is broken»: لا يمرّر nginx الترويسة X-Forwarded-Proto أو أن عنوان Jenkins ليس HTTPS. صحّح كتلة location ثم العنوان في «Manage Jenkins» ثم «System».
الحاوية تعيد التشغيل باستمرار: اقرأ السجلات. السبب الأكثر شيوعًا هو نقص الذاكرة؛ امنح الخادم 2 غيغابايت على الأقل.
docker compose logs --tail=100 jenkinsلا تصل إشعارات webhook: تحقق من سجل التسليم في إعدادات المستودع، ثم من أن العنوان المستدعى هو عنوان HTTPS العام لـ Jenkins.
التثبيت بنقرة واحدة من متجر ServOrbit
على VPS من ServOrbit، يُثبَّت Jenkins من المتجر: اختر العنوان وانقر «تثبيت»، فينشر السكربت Jenkins LTS داخل Docker مع وحدة تخزين البيانات والوكيل العكسي nginx عبر HTTPS. تظهر كلمة مرور الإدارة الأولية في مساحة العميل. ليس لديك نطاق؟ يكفي النطاق الفرعي المجاني للخادم مع HTTPS.