diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml new file mode 100644 index 0000000..cfb94ed --- /dev/null +++ b/.github/workflows/deploy.yml @@ -0,0 +1 @@ +# Deploy Applications \ No newline at end of file diff --git a/q1-deploy-monitor/.ghaymah.json b/q1-deploy-monitor/.ghaymah.json new file mode 100644 index 0000000..8db0829 --- /dev/null +++ b/q1-deploy-monitor/.ghaymah.json @@ -0,0 +1,17 @@ +{ + "id": "bdf396c2-fdf8-45ef-9066-1486d9b4d512", + "name": "q1-deploy-monitor", + "projectId": "150648a2-a09a-4387-a3af-35f966a28292", + "ports": [ + { + "expose": true, + "number": 8080 + } + ], + "publicAccess": { + "enabled": true, + "domain": "auto" + }, + "resourceTier": "t1", + "dockerFileName": "Dockerfile" +} \ No newline at end of file diff --git a/q1-deploy-monitor/README.md b/q1-deploy-monitor/README.md index 3dcf7fa..cf74548 100644 --- a/q1-deploy-monitor/README.md +++ b/q1-deploy-monitor/README.md @@ -8,8 +8,10 @@ ├── Dockerfile ├── requirements.txt ├── .dockerignore +├── .ghaymah.json ├── app/ │ └── main.py # تطبيق Flask + /health + /metrics +├── demo/ ├── health-check.sh # سكربت مراقبة بلغة bash (فحص كل 30 ثانية) ├── health-check.py └── dashboard.html # لوحة مراقبة (HTML/CSS/JS) تعمل من المتصفح مباشرة @@ -25,35 +27,7 @@ curl http://localhost:8080/health curl http://localhost:8080/metrics ``` -## 2) النشر على ghaymah.systems - -منصة الحاويات في Ghaymah تدعم النشر إما عبر ربط مستودع Git (بناء تلقائي من الـ Dockerfile) أو عبر دفع صورة جاهزة إلى سجل الحاويات الخاص بها. الخطوات العامة: - -1. سجّل الدخول إلى console الخاص بـ **ghaymah.systems**. -2. من قسم **Containers**، اختر **New Service / Deploy Container**. -3. اختر مصدر النشر: - - **Git Repository**: اربط المستودع الذي يحتوي هذا المشروع (يجب أن يحتوي على `Dockerfile` في الجذر) — المنصة تبني الصورة تلقائيًا من الـ Dockerfile. - - **أو Container Registry**: ابنِ وادفع الصورة يدويًا: - ```bash - docker build -t //sample-api:1.0 . - docker push //sample-api:1.0 - ``` - ثم أدخل مسار الصورة هذا عند إنشاء الخدمة. -4. اضبط إعدادات الخدمة: - - **Port**: `8080` (نفس المنفذ في `EXPOSE` وفي `PORT` env). - - **Health Check Path**: `/health` (المنصة تستخدمه لمعرفة جاهزية الحاوية). - - **Environment Variables**: أضف `PORT=8080` إن احتاج الأمر. - - **Resources**: ابدأ بأصغر خطة (0.5 vCPU / 256-512MB) كافية لهذا التطبيق التجريبي. -5. اضغط **Deploy**. بعد اكتمال النشر ستحصل على رابط عام مثل: - `https://sample-api-xxxx.ghaymah.systems` -6. تحقق من النشر: - ```bash - curl https://sample-api-xxxx.ghaymah.systems/health - ``` - -> ملاحظة: أسماء الأزرار والحقول الدقيقة قد تختلف قليلًا حسب نسخة الواجهة الحالية على `ghaymah.systems` — الخطوات أعلاه تعكس تدفق العمل القياسي لمنصات الحاويات (Container-as-a-Service)، راجع `docs.ghaymah.cloud` لأي تفاصيل محدّثة. - -## 3) تشغيل سكربت المراقبة +## 2) تشغيل سكربت المراقبة بعد النشر، شغّل سكربت المراقبة موجّهًا إلى الرابط العام للتطبيق: @@ -62,8 +36,8 @@ curl http://localhost:8080/metrics python health-check.py --url https://sample-api-xxxx.ghaymah.systems --interval 30 # أو bash -chmod +x monitor.sh -./monitor.sh https://sample-api-xxxx.ghaymah.systems 30 +chmod +x health-check.sh +./health-check.sh https://sample-api-xxxx.ghaymah.systems 30 ``` السكربت يقوم بـ: @@ -74,7 +48,7 @@ chmod +x monitor.sh يمكن تشغيله كخدمة نظام دائمة (systemd) أو كحاوية منفصلة (sidecar) بجانب التطبيق نفسه. -## 4) لوحة المراقبة (Dashboard) +## 3) لوحة المراقبة (Dashboard) افتح `dashboard.html` مباشرة في المتصفح (لا يحتاج خادمًا، ملف ثابت واحد): @@ -90,7 +64,7 @@ chmod +x monitor.sh اللوحة تستدعي `/metrics` كل 5 ثوانٍ عبر `fetch()` مباشرة من المتصفح؛ التطبيق (`main.py`) يضيف ترويسة `Access-Control-Allow-Origin: *` لذلك لا حاجة لخادم وسيط. -## ملاحظات إنتاجية (Production Notes) +## 4) ملاحظات إنتاجية (Production Notes) - التطبيق يعمل بمستخدم غير جذري (`non-root user`) داخل الحاوية. - يُستخدم `gunicorn` كخادم WSGI إنتاجي بدلاً من خادم التطوير المدمج في Flask. - `HEALTHCHECK` مضمّن في الـ Dockerfile نفسه، بالإضافة إلى فحص خارجي (`health-check.py`) — طبقتا مراقبة مستقلتان. diff --git a/q1-deploy-monitor/demo/dashboard.png b/q1-deploy-monitor/demo/dashboard.png new file mode 100644 index 0000000..c30f96c Binary files /dev/null and b/q1-deploy-monitor/demo/dashboard.png differ diff --git a/q1-deploy-monitor/demo/ghaymah.png b/q1-deploy-monitor/demo/ghaymah.png new file mode 100644 index 0000000..b2c1cb7 Binary files /dev/null and b/q1-deploy-monitor/demo/ghaymah.png differ diff --git a/q1-deploy-monitor/demo/sample-api.png b/q1-deploy-monitor/demo/sample-api.png new file mode 100644 index 0000000..c44309a Binary files /dev/null and b/q1-deploy-monitor/demo/sample-api.png differ diff --git a/q1-deploy-monitor/health-check.py b/q1-deploy-monitor/health-check.py index 8335fc6..3785b4b 100644 --- a/q1-deploy-monitor/health-check.py +++ b/q1-deploy-monitor/health-check.py @@ -7,8 +7,8 @@ logs status + response time, and writes the latest result to a JSON file (status.json) that can be consumed by other tools or dashboards. Usage: - python health-check.py --url https://your-app.ghaymah.systems - python health-check.py --url https://your-app.ghaymah.systems --interval 30 + python health-check.py --url https://q1-deploy-monitor-cad54f6feeb3.hosted.ghaymah.systems/ + python health-check.py --url https://q1-deploy-monitor-cad54f6feeb3.hosted.ghaymah.systems/ --interval 30 """ import argparse diff --git a/q1-deploy-monitor/health-check.sh b/q1-deploy-monitor/health-check.sh index 7f97df9..52b901d 100644 --- a/q1-deploy-monitor/health-check.sh +++ b/q1-deploy-monitor/health-check.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash # # Simple bash health monitor - polls /health every 30s. -# Usage: ./monitor.sh https://your-app.ghaymah.systems [interval_seconds] +# Usage: ./health-check.sh https://q1-deploy-monitor-cad54f6feeb3.hosted.ghaymah.systems/ [interval_seconds] set -euo pipefail diff --git a/q3-cicd/README.md b/q3-cicd/README.md index 9ee8868..ce352a9 100644 --- a/q3-cicd/README.md +++ b/q3-cicd/README.md @@ -1,9 +1,10 @@ -# بناء CI/CD Pipeline على غيمة (GitHub Actions + Ghaymah Container Registry) +# بناء CI/CD Pipeline على غيمة (GitHub Actions + Docker Registry + Ghaymah CLI) ## محتويات ``` -.github/workflows/workflow.yml # الـ workflow الكامل -README.md # هذا التوثيق +q3-cicd/workflow.yml # نسخة workflow كاملة مرفقة مع إجابة السؤال +.github/workflows/deploy.yml # مسودة/نسخة قابلة للنقل إلى GitHub Actions عند الحاجة +q3-cicd/README.md # هذا التوثيق ``` --- @@ -18,7 +19,7 @@ build-and-push ──▶ deploy-staging ──▶ deploy-production + رفع للسجل) بدون موافقة) مطلوبة قبل التنفيذ) ``` -- **build-and-push**: يبني صورة Docker، يشغّلها محليًا داخل الـ runner ويتحقق من `/health` (بوابة جودة أساسية) قبل رفعها فعليًا إلى **Ghaymah Container Registry**. +- **build-and-push**: يبني صورة Docker، يشغّلها محليًا داخل الـ runner ويتحقق من `/health` (بوابة جودة أساسية) قبل رفعها فعليًا إلى سجل صور OCI. النسخة الحالية من `workflow.yml` تستخدم Docker Hub (`docker.io`) كقيمة افتراضية، ويمكن استبداله بسجل غيمة إن كان متاحًا في الحساب. - **deploy-staging**: ينشر الصورة تلقائيًا على بيئة `staging` فور نجاح البناء — بدون تدخل بشري، لأن الهدف من staging هو تحقق سريع ومستمر. - **deploy-production**: نفس صورة staging (بدون إعادة بناء) تُنشر على `production`، لكن **الوظيفة لا تبدأ التنفيذ إلا بعد موافقة يدوية** (تفاصيل القسم التالي). @@ -33,7 +34,7 @@ build-and-push ──▶ deploy-staging ──▶ deploy-production 2. أنشئ بيئة باسم `production` (يجب أن يطابق الاسم بالضبط ما هو مكتوب في `environment: name: production` داخل الـ workflow). 3. فعّل **Required reviewers** وأضف الأشخاص أو الفريق المخوّل بالموافقة على نشر الإنتاج (مثال: قائد الفريق التقني أو مسؤول SRE). 4. (اختياري لكن موصى به) فعّل **Wait timer** (مثلاً 0-5 دقائق) كطبقة أمان إضافية، و**Deployment branches** لتقييد النشر على فرع `main` فقط. -5. أضف أسرار الإنتاج (Secrets) الخاصة بهذه البيئة تحديدًا (`GHAYMAH_API_TOKEN` لبيئة production منفصل عن نفس المتغير في staging) — هذا يمنع تسريب صلاحيات الإنتاج حتى لو تم تشغيل job آخر بالخطأ. +5. أضف أسرار الإنتاج (Secrets) الخاصة بهذه البيئة تحديدًا (`GHAYMAH_Email` و`GHAYMAH_PASSWORD` في النسخة الحالية، أو `GHAYMAH_API_TOKEN` إذا كان الحساب يدعم token مخصصًا للنشر) — هذا يمنع تسريب صلاحيات الإنتاج حتى لو تم تشغيل job آخر بالخطأ. ### كيف يعمل عمليًا عندما يصل تنفيذ الـ workflow إلى job **deploy-production**، يتوقف تلقائيًا في حالة **"Waiting"** ولا تُنفَّذ أي خطوة داخله (بما فيها تسجيل الدخول لـ Ghaymah CLI) حتى يوافق أحد المراجعين المخوّلين من تبويب **Actions** في GitHub. هذا يضمن أن الكود الذي وصل فعليًا إلى staging وتحقق من صحته هو نفسه الذي يُنشر للإنتاج — دون إعادة بناء، ودون فجوة زمنية تسمح بتغييرات غير مراجعة. @@ -63,23 +64,30 @@ build-and-push ──▶ deploy-staging ──▶ deploy-production ### أ) التثبيت (داخل الـ workflow أو محليًا) ```bash curl -fsSL https://cli.ghaymah.systems/install.sh | sh -ghaymah --version +gy --version ``` > ملاحظة: عنوان التثبيت وأسماء الأوامر أعلاه مبنية على النمط القياسي لأدوات CLI الخاصة بمنصات الحاويات (deploy/login/logs). يُرجى التأكد من الأمر الدقيق ورابط التثبيت من `docs.ghaymah.cloud` أو console الحساب، حيث إن تفاصيل الواجهة قد تختلف عن الأمثلة هنا. ### ب) المصادقة (Authentication) -لا تُستخدم بيانات اعتماد شخصية داخل الـ pipeline أبدًا. بدلًا من ذلك: -1. يُنشأ **API Token** مخصص لبيئة CI/CD من لوحة تحكم غيمة (Settings → API Tokens أو ما يعادلها)، بصلاحيات محدودة (نشر/سحب صور فقط، وليس صلاحيات إدارية كاملة). -2. يُخزَّن هذا التوكن كسر (Secret) في GitHub: - - `GHAYMAH_REGISTRY_TOKEN` — لتسجيل الدخول لسجل الحاويات (`docker/login-action`). - - `GHAYMAH_API_TOKEN` — لتنفيذ أوامر `ghaymah deploy` عبر الـ CLI. -3. تسجيل الدخول داخل الـ workflow: +لا تُكتب بيانات الاعتماد داخل ملف الـ workflow. النسخة الحالية تستخدم أسرار GitHub التالية: + +- `GHAYMAH_REGISTRY_USER` و`GHAYMAH_REGISTRY_TOKEN` لتسجيل الدخول إلى سجل الصور عبر `docker/login-action`. +- `GHAYMAH_Email` و`GHAYMAH_PASSWORD` لتسجيل الدخول إلى Ghaymah CLI بالأمر `gy auth login`. + +إن كان الحساب يدعم API Token مخصصًا للنشر، فالخيار الأفضل إنتاجيًا هو تخزينه كـ `GHAYMAH_API_TOKEN` بصلاحيات محدودة واستبدال خطوة تسجيل الدخول بـ: + ```bash - ghaymah auth login --token "$GHAYMAH_API_TOKEN" + gy auth login --token "$GHAYMAH_API_TOKEN" ``` ### ج) الربط مع سجل الحاويات (Container Registry) -تسجيل الدخول لسجل الحاويات يتم عبر الأمر القياسي لـ Docker (متوافق مع أي سجل OCI، بما فيه سجل غيمة): +تسجيل الدخول لسجل الحاويات يتم عبر الأمر القياسي لـ Docker. في `workflow.yml` القيمة الافتراضية هي Docker Hub: +```bash +echo "$GHAYMAH_REGISTRY_TOKEN" | docker login docker.io \ + --username "$GHAYMAH_REGISTRY_USER" --password-stdin +``` + +وإذا تم استخدام سجل غيمة بدل Docker Hub، تصبح الصيغة: ```bash echo "$GHAYMAH_REGISTRY_TOKEN" | docker login registry.ghaymah.systems \ --username "$GHAYMAH_REGISTRY_USER" --password-stdin @@ -88,17 +96,18 @@ echo "$GHAYMAH_REGISTRY_TOKEN" | docker login registry.ghaymah.systems \ ### د) أوامر النشر الأساسية ```bash -# نشر صورة على خدمة معيّنة (staging أو production حسب --env) -ghaymah deploy --service --image //: --env --wait +# إنشاء/تحديد مشروع ثم تهيئة التطبيق وتشغيله +gy resource project create -s .name= +gy resource app init . -p +gy resource app launch # متابعة سجلات الخدمة بعد النشر -ghaymah logs --service --follow +gy resource app logs --follow # التحقق من حالة الخدمة والنسخ الحالية -ghaymah status --service +gy resource app get -# التراجع عن نشر فاشل (Rollback) إلى آخر نسخة مستقرة -ghaymah rollback --service +# ملاحظة: قد تختلف أوامر السجلات/الحالة/rollback الدقيقة حسب إصدار Ghaymah CLI. ``` ### هـ) أفضل الممارسات المطبّقة في هذا الـ Pipeline diff --git a/q3-cicd/workflow.yml b/q3-cicd/workflow.yml index d4a86c3..89ab28d 100644 --- a/q3-cicd/workflow.yml +++ b/q3-cicd/workflow.yml @@ -1,30 +1,32 @@ name: CI/CD - Build, Push, Deploy (Ghaymah) -# يعمل تلقائيًا عند الدفع لفرع main، أو يدويًا لأي فرع/بيئة عبر workflow_dispatch +# Runs automatically on pushes to the main branch, or manually for any branch/environment via workflow_dispatch on: push: branches: ["main"] workflow_dispatch: inputs: image_tag: - description: "وسم اختياري إضافي للصورة (افتراضيًا: git SHA)" + description: "Optional extra image tag (default: git SHA)" required: false default: "" -# صلاحيات أقل ما يمكن (least privilege) +# Least privilege permissions permissions: contents: read packages: write env: - # عنوان سجل الحاويات الخاص بغيمة - عدّله حسب مشروعك - GHAYMAH_REGISTRY: registry.ghaymah.systems + # Docker Hub registry address + DOCKER_HUB_REGISTRY: docker.io GHAYMAH_NAMESPACE: my-team IMAGE_NAME: sample-api + PROJECT_STAGING_NAME: sample-api-staging + PROJECT_PRODUCTION_NAME: sample-api-production jobs: # --------------------------------------------------------------------- - # 1) بناء الصورة واختبارها ورفعها إلى Ghaymah Container Registry + # 1) Build the image, test it, and push it to Docker Hub # --------------------------------------------------------------------- build-and-push: name: Build & Push Image @@ -33,7 +35,7 @@ jobs: image_ref: ${{ steps.vars.outputs.image_ref }} steps: - name: Checkout code - uses: actions/checkout@v4 + uses: actions/checkout@v5.0.0 - name: Set image tag variables id: vars @@ -41,18 +43,18 @@ jobs: SHORT_SHA=$(echo "${GITHUB_SHA}" | cut -c1-7) TAG="${{ github.event.inputs.image_tag }}" if [ -z "$TAG" ]; then TAG="$SHORT_SHA"; fi - IMAGE_REF="${GHAYMAH_REGISTRY}/${GHAYMAH_NAMESPACE}/${IMAGE_NAME}:${TAG}" + IMAGE_REF="${DOCKER_HUB_REGISTRY}/${GHAYMAH_NAMESPACE}/${IMAGE_NAME}:${TAG}" echo "image_ref=${IMAGE_REF}" >> "$GITHUB_OUTPUT" echo "Building: ${IMAGE_REF}" - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - # تسجيل الدخول إلى سجل حاويات غيمة عبر بيانات اعتماد مخزّنة كـ GitHub Secrets + # Log in to Docker Hub using credentials stored as GitHub Secrets - name: Log in to Ghaymah Container Registry uses: docker/login-action@v3 with: - registry: ${{ env.GHAYMAH_REGISTRY }} + registry: ${{ env.DOCKER_HUB_REGISTRY }} username: ${{ secrets.GHAYMAH_REGISTRY_USER }} password: ${{ secrets.GHAYMAH_REGISTRY_TOKEN }} @@ -64,11 +66,11 @@ jobs: load: true tags: | ${{ steps.vars.outputs.image_ref }} - ${{ env.GHAYMAH_REGISTRY }}/${{ env.GHAYMAH_NAMESPACE }}/${{ env.IMAGE_NAME }}:latest + ${{ env.DOCKER_HUB_REGISTRY }}/${{ env.GHAYMAH_NAMESPACE }}/${{ env.IMAGE_NAME }}:latest cache-from: type=gha cache-to: type=gha,mode=max - # اختبار سريع للتأكد أن /health يستجيب قبل الرفع للسجل (بوابة جودة أساسية) + # Quick smoke test to confirm /health responds before pushing - name: Smoke test the built image run: | docker run -d --name smoke -p 8080:8080 ${{ steps.vars.outputs.image_ref }} @@ -86,10 +88,10 @@ jobs: push: true tags: | ${{ steps.vars.outputs.image_ref }} - ${{ env.GHAYMAH_REGISTRY }}/${{ env.GHAYMAH_NAMESPACE }}/${{ env.IMAGE_NAME }}:latest + ${{ env.DOCKER_HUB_REGISTRY }}/${{ env.GHAYMAH_NAMESPACE }}/${{ env.IMAGE_NAME }}:latest # --------------------------------------------------------------------- - # 2) نشر تلقائي على STAGING فور نجاح البناء - بدون موافقة يدوية + # 2) Automatic deployment to STAGING right after a successful build - no manual approval # --------------------------------------------------------------------- deploy-staging: name: Deploy to Staging @@ -97,62 +99,64 @@ jobs: runs-on: ubuntu-latest environment: name: staging - url: https://sample-api-staging.ghaymah.systems steps: - name: Install Ghaymah CLI run: | curl -fsSL https://cli.ghaymah.systems/install.sh | sh - ghaymah --version + gy version - name: Authenticate Ghaymah CLI - run: ghaymah auth login --token "${{ secrets.GHAYMAH_API_TOKEN }}" + run: gy auth login -e "${{ secrets.GHAYMAH_Email }}" -p "${{ secrets.GHAYMAH_PASSWORD }}" - - name: Deploy image to staging service - run: | - ghaymah deploy \ - --service sample-api-staging \ - --image "${{ needs.build-and-push.outputs.image_ref }}" \ - --env staging \ - --wait + - name: create project + run: gy resource project create -s .name=${{ env.PROJECT_STAGING_NAME }} || true - - name: Verify staging health + - name: get project id + id: get_project_id run: | - curl -sf https://sample-api-staging.ghaymah.systems/health + echo "PROJECT_ID=$(gy resource project get | grep -oP '"id"\s*:\s*"\K[^"]+')" >> $GITHUB_ENV + + - name: initialize application in Ghaymah + run: gy resource app init . -p ${{ env.PROJECT_ID }} + + - name: Deploy Application to Staging + run: | + gy resource app launch + # --------------------------------------------------------------------- - # 3) نشر على PRODUCTION - يتطلب موافقة يدوية (Manual Approval) - # الموافقة تُنفَّذ عبر GitHub Environment "production" المحمي بمراجعين - # مطلوبين (Required Reviewers) من إعدادات المستودع، وليس بكود مخصص. + # 3) Deploy to PRODUCTION - requires manual approval + # Approval is handled by the protected GitHub Environment "production" + # with Required Reviewers in repository settings, not by custom code. # --------------------------------------------------------------------- deploy-production: name: Deploy to Production (Manual Approval Required) needs: [build-and-push, deploy-staging] runs-on: ubuntu-latest environment: - name: production # <-- هذا السطر يفعّل بوابة الموافقة اليدوية المضبوطة في إعدادات المستودع - url: https://sample-api.ghaymah.systems + name: production # This line enables the manual approval gate configured in repository settings steps: - name: Install Ghaymah CLI run: | curl -fsSL https://cli.ghaymah.systems/install.sh | sh - ghaymah --version + gy version - name: Authenticate Ghaymah CLI - run: ghaymah auth login --token "${{ secrets.GHAYMAH_API_TOKEN }}" + run: gy auth login -e "${{ secrets.GHAYMAH_Email }}" -p "${{ secrets.GHAYMAH_PASSWORD }}" - - name: Deploy image to production service - run: | - ghaymah deploy \ - --service sample-api-production \ - --image "${{ needs.build-and-push.outputs.image_ref }}" \ - --env production \ - --strategy rolling \ - --wait - - name: Verify production health - run: | - curl -sf https://sample-api.ghaymah.systems/health + - name: create project + run: gy resource project create -s .name=${{ env.PROJECT_PRODUCTION_NAME }} || true - - name: Post-deploy smoke check on /metrics + - name: get project id + id: get_project_id run: | - curl -sf https://sample-api.ghaymah.systems/metrics + echo "PROJECT_ID=$(gy resource project get | grep -oP '"id"\s*:\s*"\K[^"]+')" >> $GITHUB_ENV + + - name: initialize application in Ghaymah + run: gy resource app init . -p ${{ env.PROJECT_ID }} + + - name: Deploy Application to Production + run: | + gy resource app launch + diff --git a/q5-mithal-monitor/.ghaymah.json b/q5-mithal-monitor/.ghaymah.json new file mode 100644 index 0000000..a4b77b0 --- /dev/null +++ b/q5-mithal-monitor/.ghaymah.json @@ -0,0 +1,17 @@ +{ + "id": "08631d77-6ab4-4956-87c9-2c56db25c940", + "name": "q5-mithal-monitor", + "projectId": "150648a2-a09a-4387-a3af-35f966a28292", + "ports": [ + { + "expose": true, + "number": 8080 + } + ], + "publicAccess": { + "enabled": true, + "domain": "auto" + }, + "resourceTier": "t1", + "dockerFileName": "Dockerfile" +} \ No newline at end of file diff --git a/q5-mithal-monitor/Dockerfile b/q5-mithal-monitor/Dockerfile new file mode 100644 index 0000000..ba34e6e --- /dev/null +++ b/q5-mithal-monitor/Dockerfile @@ -0,0 +1,9 @@ +FROM python:3.11-slim + +WORKDIR /app + +COPY monitor.py dashboard.html /app/ + +EXPOSE 8080 + +CMD ["python", "monitor.py"] \ No newline at end of file diff --git a/q5-mithal-monitor/README.md b/q5-mithal-monitor/README.md new file mode 100644 index 0000000..b65ab21 --- /dev/null +++ b/q5-mithal-monitor/README.md @@ -0,0 +1,77 @@ +# مراقبة mithal.space ولوحة متابعة مباشرة + +حل مستقل لمراقبة موقع `mithal.space` بدون أي مكتبات خارجية. يشغّل السكربت فحوصات دورية، يخزّن النتائج محليًا بصيغة JSON Lines، ويقدّم لوحة متابعة عبر HTTP. + +## محتويات المشروع + +``` +. +├── Dockerfile +├── .ghaymah.json +├── monitor.py # فحوصات Latency/Uptime/DNS/SSL/Search + خادم HTTP +├── dashboard.html # لوحة متابعة مباشرة +└── demo/ # لقطات توضيحية للتشغيل واللوحة +``` + +## الفحوصات المنفذة + +- **Latency/Uptime:** فحص الصفحة الرئيسية وقياس زمن الاستجابة. +- **DNS:** قياس زمن تحليل اسم النطاق. +- **SSL:** التحقق من صلاحية الشهادة وعدد الأيام المتبقية. +- **Search:** إرسال طلب بحث فعلي إلى مسار البحث وقياس الاستجابة. + +## التشغيل المحلي + +```bash +cd q5-mithal-monitor +python monitor.py --interval 60 --port 8080 +``` + +ثم افتح: + +```text +http://localhost:8080 +``` + +المسارات المتاحة: + +- `/` أو `/dashboard.html`: لوحة المتابعة. +- `/api/metrics`: آخر المقاييس مجمّعة بصيغة JSON. +- `/health`: فحص صحة للخدمة نفسها. + +لتنفيذ فحص واحد فقط بدون تشغيل الخادم: + +```bash +python monitor.py --once +``` + +## التخصيص + +يمكن تعديل الهدف وسلوك البحث عبر متغيرات البيئة: + +| المتغير | الافتراضي | الغرض | +|---|---|---| +| `TARGET_URL` | `https://mithal.space` | الموقع المراد مراقبته | +| `SEARCH_PATH` | `/search` | مسار البحث | +| `SEARCH_QUERY_PARAM` | `q` | اسم باراميتر البحث | +| `SEARCH_QUERY_VALUE` | `test` | قيمة البحث التجريبية | +| `REQUEST_TIMEOUT` | `10` | مهلة الطلب بالثواني | +| `DATA_FILE` | `data.jsonl` | ملف تخزين النتائج | +| `MAX_RECORDS` | `3000` | أقصى عدد سجلات محفوظة | +| `PORT` | `8080` | منفذ لوحة المتابعة | + +## النشر على غيمة + +الصورة جاهزة للبناء مباشرة من `Dockerfile`: + +```bash +docker build -t mithal-monitor:latest . +docker run --rm -p 8080:8080 mithal-monitor:latest +``` + +عند إنشاء الخدمة على Ghaymah Containers: + +- اضبط المنفذ على `8080`. +- اضبط Health Check Path على `/health`. +- مرّر متغير `TARGET_URL` إذا أردت مراقبة نطاق مختلف. +- افتح الرابط العام للخدمة لعرض `dashboard.html`. diff --git a/q5-mithal-monitor/demo/CLI.png b/q5-mithal-monitor/demo/CLI.png new file mode 100644 index 0000000..52d803d Binary files /dev/null and b/q5-mithal-monitor/demo/CLI.png differ diff --git a/q5-mithal-monitor/demo/dashboard.png b/q5-mithal-monitor/demo/dashboard.png new file mode 100644 index 0000000..acc142e Binary files /dev/null and b/q5-mithal-monitor/demo/dashboard.png differ