من أكثر المشاكل التقنية التي تبدو غريبة في البداية أن يعمل التطبيق بشكل طبيعي على جهاز المطور، ثم يبدأ بإظهار الأخطاء فور رفعه إلى الخادم. العبارة الشهيرة هنا: > "لكنه يعمل عندي." وغالبًا المشكلة ليست في الكود نفسه، بل في **البيئة التي يعمل فيها الكود**. ## أين تبدأ المشكلة؟ لنفترض أنك تطور تطبيق Python يستخدم ملفًا محليًا: ```python with open("config.json") as file: config = json.load(file) ``` على جهازك يعمل الكود بدون أي مشكلة. لكن بعد رفع التطبيق إلى Linux Server يظهر: ```text FileNotFoundError: [Errno 2] No such file or directory: 'config.json' ``` أول رد فعل قد يكون: "الملف موجود فعلًا." وهنا تبدأ المشكلة الحقيقية. الملف موجود، لكن البرنامج لا يبحث عنه بالضرورة في المكان الذي تتوقعه. --- ## المسار النسبي ليس مسارًا ثابتًا عندما تكتب: ```python open("config.json") ``` أنت لا تقول للبرنامج: > افتح `config.json` الموجود بجانب هذا الملف البرمجي. بل تقول: > افتح `config.json` بالنسبة إلى **مجلد التشغيل الحالي**. وهذا فرق مهم. مثلًا، إذا كان المشروع: ```text project/ ├── app.py ├── config.json └── services/ └── users.py ``` وشغلت التطبيق من: ```bash cd project python app.py ``` فسيبحث Python عن: ```text project/config.json ``` لكن إذا شغلت التطبيق من مكان مختلف: ```bash cd /var/www python /var/www/project/app.py ``` فقد يبحث عن: ```text /var/www/config.json ``` وليس: ```text /var/www/project/config.json ``` الكود نفسه لم يتغير. **الذي تغير هو Current Working Directory.** --- ## الحل الأفضل: ابنِ المسار اعتمادًا على موقع الملف بدل الاعتماد على مكان تشغيل البرنامج، اجعل المسار مرتبطًا بموقع الكود نفسه. في Python يمكن استخدام `pathlib`: ```python from pathlib import Path import json BASE_DIR = Path(__file__).resolve().parent CONFIG_FILE = BASE_DIR / "config.json" with CONFIG_FILE.open("r", encoding="utf-8") as file: config = json.load(file) ``` الآن أصبح البرنامج يعرف مكان `config.json` بناءً على مكان الملف البرمجي، وليس بناءً على المكان الذي شُغّل منه التطبيق. وهذا يجعل السلوك أكثر استقرارًا عند التشغيل محليًا أو عبر: * Gunicorn * systemd * Docker * Cron * CI/CD * بيئة استضافة مختلفة --- ## لكن لماذا تظهر المشكلة عند النشر فقط؟ لأن بيئة التطوير المحلية غالبًا تكون أبسط. أنت تعرف: ```text أين المشروع أين الملفات من أي مجلد تشغله أي Python تستخدم أي متغيرات بيئية موجودة ``` لكن الخادم قد يشغّل التطبيق بطريقة مختلفة تمامًا. مثلًا باستخدام `systemd`: ```ini [Service] WorkingDirectory=/var/www/myapp ExecStart=/var/www/myapp/venv/bin/gunicorn app:app ``` هنا أصبح `WorkingDirectory` جزءًا من سلوك التطبيق. إذا تغير هذا المسار، أو لم يتم تحديده أصلًا، فقد تبدأ المسارات النسبية في التصرف بطريقة مختلفة. --- ## ليست المشكلة في الملفات فقط نفس الفكرة تنطبق على متغيرات البيئة. قد يعمل التطبيق عندك لأن جهازك يحتوي على: ```text DATABASE_URL SECRET_KEY API_KEY ``` لكن الخادم لا يحتوي عليها. فتجد: ```python os.getenv("DATABASE_URL") ``` يعيد: ```python None ``` ثم يظهر الخطأ لاحقًا في مكان مختلف تمامًا. وهنا الخطأ الظاهر قد لا يكون هو السبب الحقيقي. لذلك عند ظهور مشكلة بعد النشر، لا تسأل فقط: > "أين الخطأ في الكود؟" بل اسأل: > "ما الذي يختلف بين البيئتين؟" --- ## قاعدة بسيطة تختصر كثيرًا من وقت التصحيح عندما يعمل التطبيق محليًا ويفشل في الإنتاج، قارن هذه الأشياء أولًا: ```text Python version Dependencies Environment variables Current working directory File paths File permissions Database configuration Operating system Network access Service configuration ``` في كثير من الحالات ستجد أن الكود لم يكن هو المشكلة أصلًا. --- ## الخلاصة البرمجيات لا تعمل داخل الكود فقط. هي تعمل داخل **بيئة تنفيذ كاملة**. ولهذا فإن عبارة: > "يعمل عندي" لا تعني أن البرنامج صحيح، كما أن: > "لا يعمل على السيرفر" لا تعني أن الكود خاطئ. الفرق بين المطور الذي يضيع ساعات في البحث والمطور الذي يجد السبب بسرعة هو قدرته على النظر إلى النظام كاملًا: **الكود + البيئة + طريقة التشغيل + الموارد + الإعدادات.** وأحيانًا يكون سبب الخطأ مجرد سطر صغير مثل: ```python open("config.json") ``` لكن المشكلة الحقيقية كانت في افتراض أن البرنامج سيُشغّل دائمًا من المكان الذي تتوقعه.