دليل Docker Compose: إدارة تطبيقات متعددة الحاويات
تعريف وإدارة التطبيقات متعددة الحاويات باستخدام Docker Compose: تبعيات الخدمات، متغيرات البيئة، فحوصات الصحة، التوسع والنشر في بيئة الإنتاج. دليل شامل.
إنشاء CI/CD pipelines مع GitHub Actions: بناء ونشر Docker، النشر على الخادم عبر SSH، أتمتة الاختبارات، إدارة الأسرار وتحسين سير العمل.
GitHub Actions منصة CI/CD قوية تختبر تغييرات الكود تلقائياً وتبنيها وتنشرها على الخادم. في هذا الدليل سنبني pipeline جاهزاً للإنتاج من الصفر.
GitHub Actions منصة أتمتة مدمجة في مستودعات GitHub:
تُخزَّن ملفات سير عمل GitHub Actions بتنسيق YAML في مجلد .github/workflows/.
# .github/workflows/deploy.yml
name: CI/CD Pipeline
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: إعداد Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: تثبيت التبعيات
run: npm ci
- name: تشغيل الاختبارات
run: npm test
deploy:
needs: test
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v4
- name: النشر
run: echo "خطوات النشر هنا"
on:
# Push إلى فرع
push:
branches: [main, develop]
paths:
- 'src/**'
- 'package.json'
# Pull request
pull_request:
branches: [main]
types: [opened, synchronize, reopened]
# تشغيل مجدول (cron)
schedule:
- cron: '0 2 * * *' # كل ليلة الساعة 02:00
# تشغيل يدوي
workflow_dispatch:
inputs:
environment:
description: 'بيئة النشر'
required: true
default: 'staging'
type: choice
options: [staging, production]
# عند اكتمال سير عمل آخر
workflow_run:
workflows: ["Build"]
types: [completed]
jobs:
build:
runs-on: ubuntu-latest
env:
NODE_ENV: test
timeout-minutes: 30
strategy:
matrix:
node-version: [18, 20, 22]
os: [ubuntu-latest, windows-latest]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
jobs:
docker:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: بيانات Docker الوصفية
id: meta
uses: docker/metadata-action@v5
with:
images: username/myapp
tags: |
type=ref,event=branch
type=semver,pattern={{version}}
type=sha,prefix=sha-
- name: إعداد Docker Buildx
uses: docker/setup-buildx-action@v3
- name: تسجيل الدخول إلى Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: البناء والنشر
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
- name: تسجيل الدخول إلى GHCR
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: البناء والنشر (GHCR)
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: ghcr.io/${{ github.repository }}:latest
deploy:
needs: docker
runs-on: ubuntu-latest
environment: production
steps:
- name: النشر عبر SSH
uses: appleboy/ssh-action@v1.0.3
with:
host: ${{ secrets.SERVER_HOST }}
username: ${{ secrets.SERVER_USER }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
port: ${{ secrets.SERVER_PORT }}
script: |
cd /root/myapp
git pull origin main
docker compose pull
docker compose up -d --remove-orphans
docker image prune -f
echo "اكتمل النشر: $(date)"
- name: نشر Docker Compose
uses: appleboy/ssh-action@v1.0.3
with:
host: ${{ secrets.SERVER_HOST }}
username: ${{ secrets.SERVER_USER }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
script: |
# سحب الصورة الجديدة
docker pull ghcr.io/${{ github.repository }}:latest
# نشر بدون توقف
docker compose -f /root/app/docker-compose.yml up -d \
--no-deps \
--build \
--remove-orphans
# تنظيف الصور القديمة
docker image prune -af --filter "until=24h"
# فحص الصحة
sleep 10
curl -f http://localhost:3000/health || exit 1
يخزّن GitHub Secrets المعلومات الحساسة بأمان:
steps:
- name: تكوين التطبيق
env:
DATABASE_URL: ${{ secrets.DATABASE_URL }}
JWT_SECRET: ${{ secrets.JWT_SECRET }}
API_KEY: ${{ secrets.API_KEY }}
run: |
echo "تم تحميل التكوين"
# لا تُطبع الأسرار في السجلات، تُخفى تلقائياً
الأسرار المطلوبة:
SERVER_HOST: عنوان IP للخادمSERVER_USER: اسم مستخدم SSHSSH_PRIVATE_KEY: المفتاح الخاص لـ SSHDOCKERHUB_USERNAME: اسم مستخدم Docker HubDOCKERHUB_TOKEN: رمز وصول Docker Hub - name: تخزين تبعيات Node.js مؤقتاً
uses: actions/cache@v4
with:
path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
- name: npm ci (مع التخزين المؤقت)
run: npm ci
# تخزين طبقات Docker مؤقتاً
- name: البناء والنشر
uses: docker/build-push-action@v5
with:
cache-from: type=gha
cache-to: type=gha,mode=max
jobs:
test:
strategy:
fail-fast: false
matrix:
node: [18, 20]
os: [ubuntu-latest, macos-latest]
include:
- node: 20
os: ubuntu-latest
coverage: true
exclude:
- node: 18
os: macos-latest
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
- run: npm ci
- run: npm test
- name: تقرير التغطية
if: matrix.coverage
run: npm run coverage
jobs:
deploy-production:
runs-on: ubuntu-latest
environment:
name: production
url: https://example.com
steps:
- name: نشر الإنتاج
run: echo "النشر إلى الإنتاج"
في GitHub تحت Settings > Environments > production:
name: Full CI/CD
on:
push:
branches: [main]
pull_request:
branches: [main]
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- run: npm ci
- run: npm run lint
- run: npm test -- --coverage
- name: رفع التغطية
uses: codecov/codecov-action@v4
build:
needs: test
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@v4
- uses: docker/setup-buildx-action@v3
- uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
- uses: docker/build-push-action@v5
with:
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
cache-from: type=gha
cache-to: type=gha,mode=max
deploy:
needs: build
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
environment:
name: production
url: https://example.com
steps:
- uses: appleboy/ssh-action@v1.0.3
with:
host: ${{ secrets.SERVER_HOST }}
username: ${{ secrets.SERVER_USER }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
script: |
docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:main
docker compose -f /root/app/docker-compose.yml up -d
docker image prune -f
بإعداد CI/CD pipeline مؤتمت بالكامل مع GitHub Actions، يمكنك تحسين جودة الكود وتقليل أخطاء النشر وتسريع عملية التطوير. مع إدارة الأسرار وتحسين التخزين المؤقت وقواعد حماية البيئة، ستحصل على pipeline بمستوى الإنتاج.
مجاني تماماً وغير محدود للمستودعات العامة. تحصل المستودعات الخاصة على 2,000 دقيقة مجانية شهرياً. إذا تجاوز هذا الحد في خطة GitHub Free، تتوقف سير العمل. تتضمن خطط GitHub Pro وTeam دقائق أكثر.
أنشئ زوج مفاتيح على جهازك المحلي بالأمر 'ssh-keygen -t ed25519 -C "github-actions"'. أضف المفتاح العام (~/.ssh/id_ed25519.pub) إلى ~/.ssh/authorized_keys على خادمك. احفظ المفتاح الخاص (~/.ssh/id_ed25519) في مستودع GitHub تحت Settings > Secrets باسم SSH_PRIVATE_KEY.
'needs: test' يعني أن هذه المهمة لن تعمل حتى تكتمل مهمة 'test' بنجاح. استخدم 'needs: [test, build]' لتبعيات متعددة. إذا فشلت مهمة، تُلغى المهام التابعة تلقائياً.
نعم، استخدم 'on.push.paths' لمراقبة ملفات أو مجلدات محددة. مثلاً 'paths: ["src/**", "package.json"]' يشغّل سير العمل فقط عند تغيير هذه الملفات. استخدم 'paths-ignore' لاستبعاد ملفات معينة.
يمنع تخزين بناء Docker المؤقت إعادة بناء الطبقات غير المتغيرة. 'cache-from: type=gha' يستخدم تخزين GitHub Actions المؤقت. يمكن أن يقلل وقت البناء بنسبة 50-80%. يحدث فرقاً كبيراً خاصة لخطوات تثبيت التبعيات (npm install, pip install).
تضيف آلية موافقة للبيئات الحرجة مثل الإنتاج. مع 'Required reviewers' لا يمكن النشر بدون موافقة أشخاص محددين. 'Wait timer' يحدد وقت انتظار قبل النشر. هذا يمنع النشر العرضي إلى الإنتاج.
تعريف وإدارة التطبيقات متعددة الحاويات باستخدام Docker Compose: تبعيات الخدمات، متغيرات البيئة، فحوصات الصحة، التوسع والنشر في بيئة الإنتاج. دليل شامل.
تثبيت Ansible، ملف الجرد، كتابة playbook، هيكل الأدوار، المتغيرات، vault المشفر، أوامر ad-hoc وأتمتة تكوين الخادم. دليل خطوة بخطوة.
تثبيت خادم ويب Caddy، تكوين Caddyfile، SSL تلقائي من Let's Encrypt، بروكسي عكسي، استضافة المواقع الثابتة، تكامل PHP-FPM وإعدادات الأداء.