لماذا استضافة Apache Airflow على VPS خاص
خدمات التنسيق السحابية مثل Cloud Composer أو MWAA تجمع Airflow كخدمة مُدارة، لكنها تفوتر البيئة بالساعة بغض النظر عن حمل العمل الفعلي. الاستضافة الذاتية على VPS تعني أنك تدفع فقط مقابل الخادم، وتعمل DAGs الخاصة بك بالقرب من مصادر بياناتك الداخلية دون نقل شبكة خارجي. الحرية تمتد أبعد من ذلك: تختار إصدار Airflow، ومكتبات Python، واتصالات قاعدة البيانات، والمُنفِّذ. للبيانات الحساسة أو البيئات المنظمة، البقاء محلياً مع VPS مخصص ليس خياراً بل متطلباً.
ما الذي ينسقه Airflow عملياً
- خطوط أنابيب البيانات وETL — الاستخراج من APIs أو قواعد البيانات، التحويل والتحميل إلى مستودع البيانات.
- سير عمل التعلم الآلي — تدريب النماذج، التقييم، النشر الآلي مع تبعيات الخطوات.
- المهام المجدولة المعقدة — backfills، catchups، إعادة المحاولة قابلة للتهيئة لكل مهمة.
- التكاملات مع الأطراف الثالثة — أكثر من 80 مزوداً رسمياً: PostgreSQL، MySQL، S3، BigQuery، dbt، Spark.
- خطوط أنابيب التقارير — إنشاء تقارير دورية آلية وتسليمها عبر البريد الإلكتروني أو Slack.
- تنسيق الخدمات المصغرة — تشغيل وظائف عن بُعد عبر API والانتظار لنتائجها قبل المتابعة.
متطلبات VPS والحزمة التقنية
Airflow هو الأكثر استهلاكاً للموارد في هذه الفئة في وضع CeleryExecutor، حيث يشغّل عدة خدمات بالتوازي. للإنتاج: الحد الأدنى 4 vCPU و8 GB RAM. للتطوير أو الاختبار: 2 vCPU و4 GB RAM كافيان في LocalExecutor. يلزم 40 GB SSD للسجلات والبيانات الوصفية. المتطلبات البرمجية: Docker 24+ وDocker Compose v2، Ubuntu 22.04 LTS أو Debian 12، واسم نطاق يشير إلى VPS الخاص بك.
معمارية Docker Compose لـ Airflow
ملف docker-compose.yaml الرسمي لـ Airflow ينشر ستة خدمات تشكل معمارية كاملة. خادم الويب يخدم الواجهة الرسومية على المنفذ 8080. المجدول هو قلب النظام: يحلل DAGs، ويجدول المهام، ويضعها في قائمة الانتظار للعمال. العامل ينفذ المهام المسندة. المُشغِّل يتعامل مع المهام القابلة للتأجيل. PostgreSQL هي قاعدة بيانات البيانات الوصفية. Redis يخدم كوسيط رسائل بين المجدول وعمال Celery.
نشر Airflow 3.x باستخدام Docker Compose
جلب docker-compose الرسمي وإنشاء المجلدات
أنشئ مجلد العمل، نزّل الملف المرجعي وجهّز المجلدات:
mkdir -p /opt/airflow && cd /opt/airflow curl -LfO 'https://airflow.apache.org/docs/apache-airflow/stable/docker-compose.yaml' mkdir -p ./dags ./logs ./plugins ./configتهيئة ملف .env (UID، PostgreSQL، المفتاح السري)
أنشئ
/opt/airflow/.envبالمتغيرات الأساسية:echo "AIRFLOW_UID=$(id -u)" > .env echo "AIRFLOW__DATABASE__SQL_ALCHEMY_CONN=postgresql+psycopg2://airflow:airflow@postgres/airflow" >> .env echo "AIRFLOW__CORE__FERNET_KEY=$(python3 -c 'from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())')" >> .envFERNET_KEYيشفر الاتصالات والمتغيرات — أنشئها مرة واحدة واحتفظ بنسخة احتياطية.تهيئة قاعدة البيانات
طبّق الترحيلات وأنشئ أول حساب مسؤول:
docker compose up airflow-initانتظر كود الخروج
0— أي كود آخر يشير إلى مشكلة اتصال بـ PostgreSQL.تشغيل جميع الخدمات
أطلق المجموعة الكاملة في الخلفية:
docker compose up -d docker compose psجميع الحاويات يجب أن تصل إلى حالة
healthyفي غضون دقيقة إلى ثلاث دقائق.إنشاء حساب مسؤول مخصص
أنشئ حسابك الدائم:
docker compose exec airflow-webserver airflow users create \ --username admin --firstname الاسم --lastname الكنية \ --role Admin --email [email protected] \ --password كلمةمرورقويةكشف Airflow خلف reverse proxy مع SSL
لا تكشف المنفذ 8080 مباشرة. مع Caddy:
apt install -y caddy cat > /etc/caddy/Caddyfile << 'EOF' airflow.yourdomain.com { reverse_proxy localhost:8080 } EOF systemctl reload caddy && ufw deny 8080
تهيئة PostgreSQL كخلفية للبيانات الوصفية
لا تستخدم SQLite في الإنتاج مع Airflow على Docker. SQLite غير مصمم للوصول المتزامن من عدة عمليات: المجدول وخادم الويب والعمال يصلون إلى قاعدة البيانات في نفس الوقت، وSQLite على Docker volumes له قيود تأمين تسبب تلف البيانات وفقدانها. تحقق أن .env يفرض الاتصال بـ PostgreSQL:
AIRFLOW__DATABASE__SQL_ALCHEMY_CONN=postgresql+psycopg2://airflow:airflow@postgres/airflowانسخ قاعدة البيانات بانتظام: docker compose exec postgres pg_dump -U airflow airflow > backup_$(date +%Y%m%d).sql.
الانتقال إلى CeleryExecutor لعدة عمال
LocalExecutor ينفذ المهام كعمليات فرعية من المجدول — بسيط لكن محدود بعقدة واحدة. CeleryExecutor يفصل التنفيذ: المجدول يضع المهام في قائمة انتظار Redis، وعامل واحد أو أكثر يستهلكونها بشكل مستقل. للتوسع الأفقي:
docker compose up -d --scale airflow-worker=3هذا يشغّل ثلاثة عمال يستهلكون نفس قائمة انتظار Redis بالتوازي.
إدارة الاتصالات والمتغيرات السرية
Airflow يشفر الاتصالات والمتغيرات الحساسة في قاعدة البيانات باستخدام FERNET_KEY. عبر الواجهة: Admin → Connections → Add Connection. عبر متغيرات البيئة: متغير بيئة مسبوق بـ AIRFLOW_CONN_ يتجاوز أي اتصال مخزن في قاعدة البيانات:
AIRFLOW_CONN_MY_POSTGRES=postgresql://user:password@host:5432/dbnameSecret Backend: لبيئات Kubernetes أو السحابة، هيّئ مزود السر المناسب (AWS Secrets Manager، HashiCorp Vault).
إنشاء واختبار أول DAG Python
إنشاء ملف DAG في مجلد /dags
أنشئ
/opt/airflow/dags/my_first_dag.py:from airflow.sdk import DAG, task from datetime import datetime with DAG( dag_id='my_first_dag', schedule='@daily', start_date=datetime(2025, 1, 1), catchup=False, ) as dag: @task def extract(): return {'rows': 42} @task def transform(data): return data['rows'] * 2 @task def load(result): print(f'Result: {result}') load(transform(extract()))التحقق من أن المجدول يحلل DAG دون أخطاء
تحقق يدوياً:
docker compose exec airflow-scheduler airflow dags list | grep my_first_dagإذا لم يظهر DAG بعد 30 ثانية، ابحث عن أخطاء التحليل:
docker compose logs airflow-scheduler | grep -i 'error\|exception' | tail -20تشغيل يدوي وفحص السجلات
في واجهة Airflow، انتقل إلى DAGs، ابحث عن
my_first_dag، فعّله، ثم اضغط ▶ Trigger DAG. انقر على مهمة ثم Logs لرؤية المخرجات. من الطرفية:docker compose exec airflow-scheduler airflow dags trigger my_first_dag
تأمين تثبيت Airflow
تثبيت Airflow يكشف محتملاً اتصالات قاعدة البيانات والمتغيرات وسجلات التنفيذ. طبّق هذه الإجراءات فور النشر. تعطيل DAGs المثال:
AIRFLOW__CORE__LOAD_EXAMPLES=Falseجدار الحماية على المنفذ 8080: ufw deny 8080. المصادقة: هيّئ LDAP أو OAuth2 للمؤسسات. تدوير المفاتيح: إذا احتجت لتغيير FERNET_KEY، استخدم airflow db rotate-fernet-key لإعادة تشفير جميع الاتصالات المخزنة.
LocalExecutor مقابل CeleryExecutor مقابل KubernetesExecutor
مرّر الجدول أفقيًا
| المعيار | LocalExecutor | CeleryExecutor | KubernetesExecutor |
|---|---|---|---|
| الموارد المطلوبة | 2 vCPU / 4 GB RAM | 4 vCPU / 8 GB RAM + Redis | مطلوب Kubernetes cluster |
| التوازي | محدود بعدد CPU المجدول | أفقي — عدد عمال حسب الحاجة | pod واحد لكل مهمة |
| عزل المهام | عمليات فرعية مشتركة | عمال منفصلون، نفس الصورة | pod معزول لكل مهمة |
| التعقيد التشغيلي | بسيط — بدون Redis | معتدل — Redis للصيانة | مرتفع — Kubernetes مطلوب |
| حالة الاستخدام المثالية | التطوير، الاختبارات | إنتاج VPS | السحابة الأصلية |
تحديث Airflow دون توقف
للتحديث المتدرج دون مقاطعة DAGs الجارية:
docker compose stop airflow-webserver airflow-scheduler
docker compose pull
docker compose up -d airflow-webserver airflow-scheduler
docker compose exec airflow-scheduler airflow db upgrade
docker compose up -dاحتفظ دائماً بنسخة احتياطية حديثة من PostgreSQL قبل أي ترقية.
تصحيح الأخطاء وقراءة سجلات Airflow
سجلات المهام: كل مهمة تكتب في ./logs/dag_id/run_id/task_id/. سجلات المجدول: الأهم لتشخيص DAGs التي لا تُشغَّل:
docker compose logs airflow-scheduler --follow --tail=100أخطاء الاستيراد الصامتة:
docker compose exec airflow-webserver airflow dags list-import-errorsتنظيف السجلات: عيّن AIRFLOW__LOG_RETENTION_DAYS=30 لتجنب امتلاء القرص.