المرحلة 5: النشر والإطلاق
النشر في بيئة الإنتاج
لقد بنيت TaskFlow من الصفر -- النماذج والترحيلات ونقاط النهاية والمصادقة والاختبارات. حان الوقت الآن لتعبئته في حاوية جاهزة للإنتاج وإطلاقه.
بناء Docker متعدد المراحل
البناء متعدد المراحل يفصل بيئة البناء (حيث تثبت التبعيات وتجمّع) عن بيئة التشغيل (ما يعمل فعلياً في الإنتاج). هذا ينتج صوراً أصغر وأكثر أماناً.
# المرحلة 1: البناء -- تثبيت التبعيات
FROM python:3.12-slim AS builder
WORKDIR /app
RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential libpq-dev \
&& rm -rf /var/lib/apt/lists/*
COPY requirements.txt .
RUN pip install --no-cache-dir --prefix=/install -r requirements.txt
# المرحلة 2: الإنتاج -- بيئة تشغيل خفيفة
FROM python:3.12-slim AS production
RUN apt-get update && apt-get install -y --no-install-recommends \
libpq5 curl \
&& rm -rf /var/lib/apt/lists/*
# مستخدم غير جذري للأمان
RUN groupadd -r taskflow && useradd -r -g taskflow taskflow
WORKDIR /app
# نسخ الحزم المثبتة فقط من مرحلة البناء
COPY /install /usr/local
COPY . .
RUN chown -R taskflow:taskflow /app
USER taskflow
HEALTHCHECK \
CMD curl -f http://localhost:8000/health || exit 1
EXPOSE 8000
CMD ["gunicorn", "app.main:app", "-w", "4", "-k", "uvicorn.workers.UvicornWorker", "--bind", "0.0.0.0:8000"]
المبادئ الأساسية:
| المبدأ | لماذا هو مهم |
|---|---|
| بناء متعدد المراحل | مرحلة البناء تُحذف؛ الصورة النهائية تحتوي فقط على تبعيات التشغيل |
| تثبيت إصدار الصورة الأساسية | python:3.12-slim بدلاً من python:latest يمنع الأعطال المفاجئة |
| مستخدم غير جذري | يحد من الضرر إذا تم اختراق الحاوية |
| HEALTHCHECK | المُنسقات (Compose، ECS، K8s) تعرف متى يكون التطبيق جاهزاً فعلاً |
| ترتيب الطبقات | COPY requirements.txt قبل COPY . لتُخزن طبقات التبعيات مؤقتاً |
Docker Compose للإنتاج
احتفظ بملفات منفصلة للتطوير والإنتاج. التطوير يستخدم إعادة التحميل التلقائي وإعدادات التصحيح؛ الإنتاج يستخدم حدود الموارد وسياسات إعادة التشغيل.
# docker-compose.prod.yml
services:
api:
build:
context: .
dockerfile: Dockerfile
target: production
ports:
- "8000:8000"
env_file: .env.production
depends_on:
db:
condition: service_healthy
redis:
condition: service_healthy
deploy:
resources:
limits:
cpus: "1.0"
memory: 512M
restart: unless-stopped
networks:
- external
- internal
db:
image: postgres:18
volumes:
- pgdata:/var/lib/postgresql/data
environment:
POSTGRES_DB: taskflow
POSTGRES_USER: taskflow
POSTGRES_PASSWORD: ${DB_PASSWORD}
healthcheck:
test: ["CMD-SHELL", "pg_isready -U taskflow"]
interval: 10s
timeout: 5s
retries: 5
networks:
- internal
redis:
image: redis:7-alpine
command: redis-server --appendonly yes --maxmemory 128mb --maxmemory-policy allkeys-lru
volumes:
- redisdata:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
networks:
- internal
volumes:
pgdata:
redisdata:
networks:
external:
internal:
internal: true
لاحظ internal: true على شبكة قاعدة البيانات. PostgreSQL وRedis يمكن الوصول إليهما فقط من خدمة API، ولا يُعرضان أبداً للمضيف.
إدارة البيئة
لا تُضمّن الأسرار أبداً في الكود. استخدم ملفات .env للتطوير المحلي ومخازن الأسرار المناسبة للإنتاج.
# .env.development (يُرفع للمستودع كـ .env.example بقيم فارغة)
DATABASE_URL=postgresql+asyncpg://taskflow:localpass@localhost:5432/taskflow
REDIS_URL=redis://localhost:6379/0
SECRET_KEY=dev-only-not-for-production
ENVIRONMENT=development
# .env.production (لا يُرفع أبداً -- استخدم أسرار CI/CD)
DATABASE_URL=postgresql+asyncpg://taskflow:${DB_PASSWORD}@db:5432/taskflow
REDIS_URL=redis://redis:6379/0
SECRET_KEY=${SECRET_KEY}
ENVIRONMENT=production
مع Pydantic Settings، يتم التحقق من التكوين عند بدء التشغيل:
from pydantic_settings import BaseSettings
class Settings(BaseSettings):
database_url: str
redis_url: str
secret_key: str
environment: str = "development"
api_v1_prefix: str = "/api/v1"
@property
def is_production(self) -> bool:
return self.environment == "production"
model_config = {"env_file": ".env"}
settings = Settings()
CI/CD مع GitHub Actions
خط أنابيب قياسي: اختبار، بناء، نشر -- يُشغل عند كل دفع إلى main وعند طلبات السحب.
# .github/workflows/ci.yml
name: CI/CD Pipeline
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
services:
postgres:
image: postgres:18
env:
POSTGRES_DB: taskflow_test
POSTGRES_USER: taskflow
POSTGRES_PASSWORD: testpassword
ports: ["5432:5432"]
options: >-
--health-cmd="pg_isready -U taskflow"
--health-interval=10s
--health-timeout=5s
--health-retries=5
redis:
image: redis:7-alpine
ports: ["6379:6379"]
options: >-
--health-cmd="redis-cli ping"
--health-interval=10s
--health-timeout=5s
--health-retries=5
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- run: pip install -r requirements.txt
- run: ruff check .
- run: pytest --cov=app tests/
env:
DATABASE_URL: postgresql+asyncpg://taskflow:testpassword@localhost:5432/taskflow_test
REDIS_URL: redis://localhost:6379/0
SECRET_KEY: test-secret-key
build:
needs: test
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: docker build -t taskflow-api:${{ github.sha }} .
قائمة فحص الإنتاج
قبل الإطلاق، تحقق من كل عنصر:
| الفئة | العنصر | الكيفية |
|---|---|---|
| الأمان | مستخدم Docker غير جذري | USER taskflow في Dockerfile |
| الأمان | ترويسات الأمان | Middleware: X-Content-Type-Options، X-Frame-Options، Strict-Transport-Security |
| الأمان | CORS مقيد | أصول مسموحة صريحة، لا تستخدم * أبداً في الإنتاج |
| الأداء | عمال Gunicorn | gunicorn -w 4 -k uvicorn.workers.UvicornWorker |
| الموثوقية | فحوصات الصحة | نقطة /health تُرجع 200 عندما يكون DB وRedis متاحين |
| الموثوقية | سياسة إعادة التشغيل | restart: unless-stopped في Compose |
| الإصدارات | بادئة API | جميع المسارات تحت /api/v1/ |
| الأسرار | لا مفاتيح مُضمنة | جميع الأسرار من متغيرات البيئة أو مدير الأسرار |
خيارات النشر (اعتباراً من 2026)
| المنصة | الأفضل لـ | ملاحظات |
|---|---|---|
| Railway | النشر السريع، الفرق الصغيرة | Docker + إضافات PostgreSQL + Redis، تسعير بسيط |
| Render | النشر التلقائي من Git | مستوى مجاني للهوايات، PostgreSQL مُدار |
| Fly.io | النشر على الحافة، زمن وصول منخفض | نشر الحاويات عالمياً، Postgres مدمج |
| AWS ECS / Fargate | النطاق المؤسسي | نظام AWS البيئي الكامل، يحتاج تكوين أكثر |
جميع المنصات الأربع تدعم النشر القائم على Docker. بالنسبة لـ TaskFlow، Railway أو Render تنقلك من الكود إلى الإنتاج في أقل من 10 دقائق.
التالي: معمل عملي حيث ستُحوّل TaskFlow إلى حاوية وتُعد خط أنابيب CI/CD الكامل. :::