بتذكر مرة، قبل كم سنة، انضم إلنا شب جديد للفريق، اسمه “سعيد”، شب شاطر ومليان حماس. أعطيناه جهاز لابتوب جديد وطلبنا منه يجهز بيئة العمل لمشروع الذكاء الاصطناعي اللي كنا شغالين عليه. المشروع كان معقد شوي، بيعتمد على Python و TensorFlow ومكتبات تانية وبده قاعدة بيانات PostgreSQL معينة وشوية أدوات بتشتغل من الـ command line.
أنا بكل ثقة أعطيته ملف الـ README وقلتله: “يا سعيد، كل شي مكتوب هون، اتبع الخطوات وإن شاء الله بيمشي الحال. إذا لزمك إشي، أنا موجود.”
مرّ أول يوم… وسعيد ما زال “يُصارع” التثبيتات. نسخة الـ Python مش متوافقة، إحدى المكتبات بدها
`build-essential` وهو على ويندوز، والـ PostgreSQL اللي نزّلها طلعت نسخة أحدث من اللي بيطلبها المشروع. اليوم الثاني نفس الإشي، مشاكل في متغيرات البيئة (Environment Variables) وصرنا نسمع منه جمل زي “هاي المكتبة ما بتركب عندي” و “بيطلعلي خطأ غريب ما شفته بحياتي”.
في نهاية اليوم الثاني، إجاني سعيد على مكتبي، وجهه أصفر والتعب مبين عليه، وقال جملته الشهيرة اللي كل مدير فريق بيعرفها:
“يا عمي أبو عمر، والله عملت كل إشي قلته، بس الكود لسا ما بشتغل… مع إنه شغال على جهازك تمام!”
في هذيك اللحظة، ما لُمت سعيد. لُمت نفسي والنظام اللي كنا ماشيين عليه. كان لازم يكون في حل أفضل من “اقرأ التعليمات وتمنى الأفضل”. من هنا بدأت رحلتي مع “حاويات التطوير” أو الـ Dev Containers، الحل اللي غيّر طريقة عملنا كلياً.
ما هي مشكلة “شغّال على جهازي” اللعينة؟
هذه المشكلة أكبر من مجرد مزحة بين المبرمجين، إنها عارض لمرض خطير في عملية تطوير البرمجيات: غياب التوحيد القياسي للبيئة (Lack of Environment Standardization). كل جهاز هو عالم مختلف، وكل عالم له قوانينه الخاصة. الأسباب كثيرة ومتشعبة:
- اختلاف أنظمة التشغيل: أوامر تعمل على Linux/macOS لا تعمل على Windows والعكس صحيح (خصوصاً مسارات الملفات وصلاحياتها).
- اختلاف إصدارات الأدوات: مشروعك يتطلب Python 3.9، لكن زميلك لديه 3.11 مثبت على جهازه بشكل أساسي.
- الاعتماديات الخفية (Hidden Dependencies): مكتبات نظام التشغيل التي قمت بتثبيتها قبل أشهر ونسيت أمرها تماماً، لكن مشروعك يعتمد عليها ليعمل.
- تعارض المكتبات العامة (Global Packages): أدوات قمت بتثبيتها بشكل عام على جهازك (globally) تتعارض مع نسخة محلية (local) يتطلبها المشروع.
- إعدادات وقواعد بيانات: كل مبرمج يقوم بإعداد قاعدة البيانات والخدمات الأخرى (مثل Redis أو RabbitMQ) بطريقته الخاصة، مما يؤدي إلى عدم تطابق.
النتيجة؟ ساعات وأيام ضائعة في تصحيح أخطاء لا علاقة لها بالكود نفسه، بل بالبيئة التي يعمل فيها. وهذا هو الجحيم الذي كنا نعيشه.
الحل السحري: ادخل إلى عالم حاويات التطوير (Dev Containers)
تخيل معي لو أنك تستطيع أن تضع “وصفة” دقيقة لبيئة العمل الخاصة بمشروعك، وهذه الوصفة تتضمن: نظام التشغيل، إصدار لغة البرمجة، المكتبات المطلوبة، إعدادات المحرر، وحتى الخدمات الإضافية كقواعد البيانات. ثم، يستطيع أي مبرمج، بضغطة زر واحدة، أن “يطبخ” هذه البيئة المتطابقة 100% على جهازه، بغض النظر عن نظام تشغيله الأصلي.
هذا بالضبط ما تقدمه حاويات التطوير. هي باختصار، بيئات تطوير معزولة، خفيفة، وقابلة للتكرار تعمل داخل حاويات Docker، ويتم إدارتها بشكل كامل من خلال محرر الأكواد VS Code.
كيف تعمل هذه “الحاويات”؟
الفكرة عبقرية في بساطتها. بدل أن تثبت كل شيء على جهازك مباشرة (Host OS)، أنت تطلب من VS Code أن يبني لك “جهاز كمبيوتر افتراضي صغير” (حاوية Docker) بناءً على ملفات إعدادات بسيطة تضعها في مشروعك. ثم يقوم VS Code بتشغيل خدماته داخل هذه الحاوية، مما يجعلك تكتب الكود على جهازك، لكن كل عمليات التشغيل والتصحيح (Debugging) والـ Terminal تحدث داخل تلك البيئة المعزولة والنظيفة.
الأمر كله يعتمد على مجلد بسيط اسمه .devcontainer تضعه في جذر مشروعك، ويحتوي غالباً على ملفين رئيسيين:
devcontainer.json: ملف الإعدادات الرئيسي. يخبر VS Code بكيفية بناء الحاوية، ما هي الإضافات (Extensions) التي يجب تثبيتها بداخلها، وما هي الأوامر التي يجب تشغيلها بعد الإنشاء.Dockerfile: هذا هو “كتاب الطبخ” الفعلي. هو ملف نصي يحتوي على تعليمات خطوة بخطوة لبناء صورة الحاوية: ما هو نظام التشغيل الأساسي (غالباً توزيعة لينكس خفيفة)، ما هي البرامج والمكتبات التي يجب تثبيتها، إلخ.
لنطبق عملياً: إعداد أول حاوية تطوير لمشروع Python
كلام جميل يا أبو عمر، بس ورجينا كيف. أبشر! لنقم بإعداد مشروع Python بسيط باستخدام Flask كمثال.
المتطلبات الأساسية:
- محرر VS Code.
- برنامج Docker Desktop (تأكد من أنه يعمل في الخلفية).
- إضافة Dev Containers في VS Code.
الخطوات:
-
أنشئ مشروعك:
أنشئ مجلداً جديداً. بداخله، أنشئ ملفين:
main.py:from flask import Flask app = Flask(__name__) @app.route('/') def hello_world(): return 'مرحباً من داخل حاوية التطوير! Hello from the Dev Container!' if __name__ == '__main__': app.run(host='0.0.0.0', port=5000)requirements.txt:flask -
أضف إعدادات حاوية التطوير:
افتح المشروع في VS Code. اضغط على
Ctrl+Shift+P(أوCmd+Shift+Pعلى ماك) لفتح لوحة الأوامر (Command Palette). اكتب “Dev Containers” واختر الأمر:Dev Containers: Add Dev Container Configuration Files…
سيظهر لك معالج إعداد (wizard):
- ابحث واختر “Python 3”.
- اختر إصدار Python الذي تريده (مثلاً 3.10).
- سيطلب منك إضافة ميزات إضافية (like Git)، يمكنك تجاهلها الآن.
- اضغط “OK”.
سيقوم VS Code بإنشاء مجلد
.devcontainerوبداخله ملفيdevcontainer.jsonوDockerfile. -
افتح المشروع في الحاوية:
بمجرد إنشاء الملفات، سيظهر إشعار في أسفل يمين الشاشة يسألك: “Folder contains a Dev Container configuration file. Reopen to run in container?”. اضغط على الزر الأخضر “Reopen in Container”.
في المرة الأولى، قد يستغرق الأمر بضع دقائق لأنه يقوم بتحميل صورة Docker الأساسية وبناء بيئتك. في المرات اللاحقة، ستكون العملية أسرع بكثير.
-
أنت الآن بالداخل!
عندما يعاد تحميل VS Code، انظر إلى الزاوية السفلية اليسرى، ستجد عبارة “Dev Container: Python 3”. هذا يؤكد أنك تعمل الآن داخل الحاوية.
افتح الـ Terminal المدمج في VS Code (
Ctrl+`). أنت الآن لا تتحدث مع جهازك، بل مع نظام Linux داخل الحاوية!جرّب هذه الأوامر:
# تحقق من إصدار بايثون داخل الحاوية python --version # قم بتثبيت المكتبات من ملف المتطلبات pip install -r requirements.txt # قم بتشغيل التطبيق python main.pyسترى أن الخادم يعمل. سيقوم VS Code تلقائياً بعمل “Port Forwarding”، وسيظهر لك إشعار لفتح الموقع في المتصفح. افتحه وستجد رسالتك الترحيبية!
المعجزة هنا أن زميلك “سعيد” الآن كل ما عليه فعله هو: `git clone` ثم “Reopen in Container”. خلال دقائق، سيحصل على نفس البيئة المتطابقة 100%، دون أي صداع. 🎉
نصيحة من أبو عمر: أسرار لتخصيص بيئتك
القوة الحقيقية تكمن في التخصيص. افتح ملف devcontainer.json، ستجد كنزاً من الخيارات. إليك بعض الأسرار العملية:
-
التثبيت التلقائي للمكتبات: لا تجعل زميلك يكتب `pip install` يدوياً. استخدم خاصية
postCreateCommandلتشغيل أي أمر بعد بناء الحاوية:"postCreateCommand": "pip install --user -r requirements.txt" -
توحيد إضافات VS Code: لضمان أن كل الفريق يستخدم نفس الأدوات المساعدة، أضفها إلى قائمة
extensions. هذا يضمن تثبيت إضافات الـ Linter والـ Formatter تلقائياً للجميع:"customizations": { "vscode": { "extensions": [ "ms-python.python", "ms-python.vscode-pylance", "charliermarsh.ruff" ] } } - إضافة خدمات أخرى (Databases): هل يحتاج مشروعك إلى قاعدة بيانات PostgreSQL؟ بدلاً من تثبيتها يدوياً، يمكنك استخدام Docker Compose لتعريفها وتشغيلها كحاوية أخرى بجانب حاوية التطوير الخاصة بك. كل ما عليك هو الإشارة إلى ملف `docker-compose.yml` في `devcontainer.json`.
الفوائد الحقيقية التي لمسناها كفريق
بعد تبنينا لحاويات التطوير، تغيرت حياتنا للأفضل بشكل جذري:
- إعداد سريع للمطورين الجدد: عملية الانضمام للفريق أصبحت تستغرق دقائق بدلاً من أيام. “اعمل clone وافتح بالحاوية”. انتهى.
- بيئة متطابقة للجميع: لا مزيد من “شغّال على جهازي”. الكود يعمل بنفس الطريقة على جهاز المطور، جهاز زميله، وعلى خوادم الـ CI/CD.
- جهازك يبقى نظيفاً: لا حاجة لتثبيت 5 إصدارات مختلفة من Node.js أو Python على جهازك. كل مشروع معزول بأدواته الخاصة.
- سهولة تجربة التقنيات: هل تريد تجربة قاعدة بيانات جديدة أو إصدار لغة مختلف؟ يمكنك فعل ذلك في حاوية منفصلة دون التأثير على أي شيء آخر.
- التطوير والتكامل المستمر (CI/CD) أصبحا وجهين لعملة واحدة: نفس الـ
Dockerfileالذي تستخدمه للتطوير المحلي يمكن استخدامه لبناء بيئة الاختبار والإنتاج، مما يقلل الفجوات والمفاجآت.
الخلاصة: استثمر في بيئتك، فهي ورشتك 🛠️
يا جماعة الخير، كودك هو منتجك، وبيئة التطوير هي ورشتك التي تصنع فيها هذا المنتج. لا يمكنك أن تكون حرفياً فعالاً وأدواتك مبعثرة وغير منظمة. حاويات التطوير (Dev Containers) ليست مجرد أداة تقنية جديدة، بل هي نقلة نوعية في فلسفة العمل.
إنها تنقل تعريف بيئة العمل من مجموعة تعليمات شفهية أو ملف README مهمل، إلى جزء أساسي من الكود المصدري نفسه (Infrastructure as Code)، يمكن التحكم بإصداراته ومراجعته وتطويره مثل أي جزء آخر من المشروع.
نصيحتي لك: إذا كنت لا تزال تعاني من جحيم الإعداد اليدوي، أو تسمع جملة “شغّال على جهازي” بشكل متكرر في فريقك، فتوقف عن كل شيء الآن. استثمر بضع ساعات في تعلم وتطبيق Dev Containers على مشروعك التالي. أضمن لك أنك ستشكرني لاحقاً.
جربها يا خوي، وما رح تندم. بالتوفيق!