انتقل إلى المحتوى الرئيسي

اختبار: Docker و CI/CD

اختبر معرفتك بـ Docker و Docker Compose و GitHub Actions.

30 سؤالاً - انقر على كل سؤال لكشف الإجابة.


الأسئلة 1-15: Docker​

السؤال 1: ما هو Docker؟

الإجابة: Docker هو منصة للحاويات تتيح تعبئة التطبيق مع جميع تبعياته في حاوية خفيفة وقابلة للنقل. الفوائد:

  • نفس البيئة في كل مكان
  • عزل التطبيقات
  • نشر سريع
  • قابلية التوسع

السؤال 2: ما الفرق بين الصورة والحاوية؟

الإجابة:

  • الصورة: نموذج للقراءة فقط (مثل الفئة)
  • الحاوية: مثيل قيد التشغيل لصورة (مثل الكائن)
# إنشاء حاوية من صورة
docker run -d --name my-app my-image:1.0

السؤال 3: كيف تكتب Dockerfile لـ Spring Boot؟

الإجابة:

FROM eclipse-temurin:21-jdk-alpine

WORKDIR /app

COPY target/*.jar app.jar

EXPOSE 8080

ENTRYPOINT ["java", "-jar", "app.jar"]

السؤال 4: كيف تحسن Dockerfile باستخدام بناء متعدد المراحل؟

الإجابة:

# المرحلة 1: البناء
FROM maven:3.9-eclipse-temurin-21 AS build
WORKDIR /app
COPY pom.xml .
RUN mvn dependency:go-offline
COPY src ./src
RUN mvn package -DskipTests

# المرحلة 2: التشغيل
FROM eclipse-temurin:21-jre-alpine
WORKDIR /app
COPY --from=build /app/target/*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]

الصورة النهائية أصغر (بدون Maven، JDK كامل).


السؤال 5: كيف تبني وتشغل صورة Docker؟

الإجابة:

# بناء الصورة
docker build -t my-app:1.0 .

# تشغيل
docker run -d -p 8080:8080 --name my-app my-app:1.0

# عرض السجلات
docker logs -f my-app

# إيقاف
docker stop my-app

# حذف
docker rm my-app

السؤال 6: كيف تمرر متغيرات البيئة إلى الحاوية؟

الإجابة:

# في سطر الأوامر
docker run -e SPRING_PROFILES_ACTIVE=prod \
-e DB_HOST=postgres \
my-app:1.0

# باستخدام ملف
docker run --env-file .env my-app:1.0
# .env
SPRING_PROFILES_ACTIVE=prod
DB_HOST=postgres
DB_PASSWORD=secret

السؤال 7: كيف تحافظ على البيانات باستخدام Docker؟

الإجابة: باستخدام وحدات التخزين:

# وحدة تخزين مسماة
docker run -v postgres-data:/var/lib/postgresql/data postgres

# ربط التركيب
docker run -v $(pwd)/data:/app/data my-app

البيانات تبقى بعد حذف الحاوية.


السؤال 8: كيف تربط الحاويات ببعضها البعض؟

الإجابة: باستخدام شبكة Docker:

# إنشاء شبكة
docker network create my-network

# ربط الحاويات
docker run -d --name postgres --network my-network postgres
docker run -d --name app --network my-network \
-e DB_HOST=postgres my-app

# الحاويات تجد بعضها البعض بالاسم

السؤال 9: ما هو Docker Compose؟

الإجابة: أداة لتعريف وتشغيل التطبيقات متعددة الحاويات:

# docker-compose.yml
services:
app:
build: .
ports:
- "8080:8080"
depends_on:
- postgres
environment:
- SPRING_DATASOURCE_URL=jdbc:postgresql://postgres:5432/mydb

postgres:
image: postgres:15
volumes:
- postgres-data:/var/lib/postgresql/data
environment:
- POSTGRES_DB=mydb
- POSTGRES_USER=user
- POSTGRES_PASSWORD=pass

volumes:
postgres-data:

السؤال 10: ما هي الأوامر الرئيسية لـ Docker Compose؟

الإجابة:

# بدء جميع الخدمات
docker compose up -d

# عرض السجلات
docker compose logs -f

# إيقاف
docker compose stop

# حذف (مع وحدات التخزين)
docker compose down -v

# إعادة البناء
docker compose up -d --build

السؤال 11: كيف تضبط فحص الصحة لـ Docker؟

الإجابة:

HEALTHCHECK --interval=30s --timeout=3s --start-period=60s --retries=3 \
CMD curl -f http://localhost:8080/actuator/health || exit 1

أو في docker-compose.yml:

services:
app:
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/actuator/health"]
interval: 30s
timeout: 3s
retries: 3
start_period: 60s

السؤال 12: كيف تحدد موارد الحاوية؟

الإجابة:

services:
app:
deploy:
resources:
limits:
cpus: '1'
memory: 512M
reservations:
cpus: '0.5'
memory: 256M

السؤال 13: كيف ترى الحاويات والصور؟

الإجابة:

# الحاويات الجارية
docker ps

# جميع الحاويات
docker ps -a

# الصور
docker images

# استخدام القرص
docker system df

# تنظيف
docker system prune -a

السؤال 14: كيف تقوم بتصحيح حاوية؟

الإجابة:

# السجلات
docker logs my-app

# شل داخل الحاوية
docker exec -it my-app /bin/sh

# تفتيش الحاوية
docker inspect my-app

# إحصائيات في الوقت الحقيقي
docker stats my-app

السؤال 15: كيف تدفع صورة إلى سجل؟

الإجابة:

# Docker Hub
docker login
docker tag my-app:1.0 username/my-app:1.0
docker push username/my-app:1.0

# GitHub Container Registry
docker login ghcr.io
docker tag my-app:1.0 ghcr.io/username/my-app:1.0
docker push ghcr.io/username/my-app:1.0

الأسئلة 16-30: CI/CD مع GitHub Actions​

السؤال 16: ما هو GitHub Actions؟

الإجابة: منصة أتمتة CI/CD مدمجة في GitHub:

  • تدفقات العمل التي يتم تشغيلها بواسطة الأحداث
  • Runners مستضافة أو ذاتية الاستضافة
  • سوق للإجراءات القابلة لإعادة الاستخدام
  • أسرار ومتغيرات آمنة

السؤال 17: كيف تنظم تدفق عمل GitHub Actions؟

الإجابة:

# .github/workflows/ci.yml
name: CI Pipeline

on:
push:
branches: [main]
pull_request:
branches: [main]

jobs:
build:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Set up JDK
uses: actions/setup-java@v4
with:
java-version: '21'
distribution: 'temurin'

- name: Build with Maven
run: mvn clean package

السؤال 18: كيف تنفذ الاختبارات في CI؟

الإجابة:

jobs:
test:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Set up JDK
uses: actions/setup-java@v4
with:
java-version: '21'
distribution: 'temurin'
cache: 'maven'

- name: Run tests
run: mvn test

- name: Upload test results
uses: actions/upload-artifact@v4
if: always()
with:
name: test-results
path: target/surefire-reports/

السؤال 19: كيف تستخدم ذاكرة التخزين المؤقت لـ Maven؟

الإجابة:

- uses: actions/setup-java@v4
with:
java-version: '21'
distribution: 'temurin'
cache: 'maven' # ذاكرة تخزين مؤقت تلقائية

# أو يدوياً
- uses: actions/cache@v4
with:
path: ~/.m2/repository
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
restore-keys: |
${{ runner.os }}-maven-

السؤال 20: كيف تبني وتدفع صورة Docker؟

الإجابة:

jobs:
docker:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Build and push
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: ghcr.io/${{ github.repository }}:${{ github.sha }}

السؤال 21: كيف تستخدم الأسرار في GitHub؟

الإجابة:

jobs:
deploy:
runs-on: ubuntu-latest

steps:
- name: Deploy to server
env:
SSH_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
DB_PASSWORD: ${{ secrets.DB_PASSWORD }}
run: |
echo "$SSH_KEY" > key.pem
chmod 600 key.pem
ssh -i key.pem user@server "deploy.sh"

الأسرار مخفية في السجلات.


السؤال 22: كيف تنفذ الوظائف بالتوازي؟

الإجابة:

jobs:
test:
runs-on: ubuntu-latest
steps:
- run: mvn test

lint:
runs-on: ubuntu-latest
steps:
- run: mvn checkstyle:check

security:
runs-on: ubuntu-latest
steps:
- run: mvn dependency-check:check

بشكل افتراضي، الوظائف تنفذ بالتوازي.


السؤال 23: كيف تنشئ تبعيات بين الوظائف؟

الإجابة:

jobs:
build:
runs-on: ubuntu-latest
steps:
- run: mvn package

test:
needs: build # ينتظر حتى ينتهي البناء
runs-on: ubuntu-latest
steps:
- run: mvn test

deploy:
needs: [build, test] # ينتظر كلاهما
runs-on: ubuntu-latest
steps:
- run: ./deploy.sh

السؤال 24: كيف تستخدم المصفوفة لاختبار عدة إصدارات؟

الإجابة:

jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
java: [17, 21]
os: [ubuntu-latest, windows-latest]

steps:
- uses: actions/setup-java@v4
with:
java-version: ${{ matrix.java }}
distribution: 'temurin'

- run: mvn test

ينفذ 4 وظائف (2 إصدارات x 2 أنظمة تشغيل).


السؤال 25: كيف تشغل تدفق عمل يدوياً؟

الإجابة:

on:
workflow_dispatch:
inputs:
environment:
description: 'Environment to deploy'
required: true
default: 'staging'
type: choice
options:
- staging
- production

jobs:
deploy:
runs-on: ubuntu-latest
steps:
- run: echo "Deploying to ${{ inputs.environment }}"

السؤال 26: كيف تستخدم البيئات في GitHub؟

الإجابة:

jobs:
deploy-staging:
environment: staging
runs-on: ubuntu-latest
steps:
- run: ./deploy.sh ${{ vars.SERVER_URL }}

deploy-production:
needs: deploy-staging
environment:
name: production
url: https://myapp.com
runs-on: ubuntu-latest
steps:
- run: ./deploy.sh ${{ vars.SERVER_URL }}

البيئات يمكن أن تحتوي على:

  • أسرار محددة
  • قواعد الموافقة
  • مؤقتات الانتظار

السؤال 27: كيف تتحقق من جودة الكود؟

الإجابة:

jobs:
quality:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: SonarCloud Scan
uses: SonarSource/sonarcloud-github-action@master
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}

- name: Check coverage
run: |
mvn jacoco:report
COVERAGE=$(grep -oP 'Total.*?([0-9]+)%' target/site/jacoco/index.html | grep -oP '[0-9]+')
if [ "$COVERAGE" -lt 70 ]; then exit 1; fi

السؤال 28: كيف تنشر على خادم؟

الإجابة:

jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Deploy via SSH
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.HOST }}
username: ${{ secrets.USERNAME }}
key: ${{ secrets.SSH_KEY }}
script: |
cd /app
docker compose pull
docker compose up -d

السؤال 29: كيف تخطر الفريق بالنتيجة؟

الإجابة:

jobs:
notify:
runs-on: ubuntu-latest
needs: [build, test, deploy]
if: always()

steps:
- name: Slack Notification
uses: slackapi/slack-github-action@v1
with:
channel-id: 'deployments'
slack-message: |
Deployment ${{ needs.deploy.result }}
Commit: ${{ github.sha }}
Author: ${{ github.actor }}
env:
SLACK_BOT_TOKEN: ${{ secrets.SLACK_TOKEN }}

السؤال 30: ما هي أفضل الممارسات لـ CI/CD؟

الإجابة:

  1. فشل سريع: التوقف بمجرد فشل اختبار
  2. ذاكرة تخزين مؤقت عدوانية: تبعيات Maven، صور Docker
  3. التوازي: اختبارات مستقلة بالتوازي
  4. أسرار آمنة: لا تظهر أبداً بشكل واضح
  5. بيئات منفصلة: اختبار قبل الإنتاج
  6. تراجع تلقائي: في حالة الفشل
  7. إخطارات: Slack، البريد الإلكتروني للفشل
  8. القطع الأثرية: حفظ تقارير الاختبار
  9. إصدار دلالي: علامات للإصدارات
  10. حماية الفروع: مراجعات إلزامية

النتيجة​

النتيجةالمستوى
27-30ممتاز - إتقان Docker و CI/CD
21-26جيد - بعض المراجعات
15-20متوسط - أعد قراءة الفصول
أقل من 15بحاجة إلى مراجعة

العودة إلى الوحدة 12