Django هو إطار عمل ويب مفتوح المصدر وعالي المستوى لـ Python يساعدك على بناء تطبيق Python الخاص بك بسرعة. إنه يشجع على التطوير السريع والتصميم النظيف والعملي باتباع النمط المعماري نموذج-قالب-عرض (model–template–views). يأتي إطار العمل مجهزًا بمكونات التطبيق الحديثة الضرورية مثل مصادقة المستخدم، و إطار عمل التخزين المؤقت, مخطط العلاقات الكائنية, موزع عناوين URL, نظام القوالب، وواجهة إدارة قابلة للتخصيص.
Gunicorn ‘Green Unicorn’ هو خادم Python WSGI HTTP لأنظمة UNIX. يتوافق خادم Gunicorn مع أطر عمل الويب المختلفة، ويقدم أداءً رائعًا، وهو خفيف على موارد الخادم. Docker هي منصة حاويات مفتوحة المصدر موجودة منذ فترة، مما يجعل تطوير التطبيقات سريعًا وفعالًا وقابلًا للتنبؤ.
في هذا البرنامج التعليمي، سوف تكتسب مهارات في تطوير ونشر تطبيقات ويب Django المعبأة في حاويات والقابلة للتطوير. سنقوم باستخدام تطبيق Django Polls تم إنشاؤه باتباع الأدلة التمهيدية للبدء مع Django. في وقت كتابة هذا البرنامج التعليمي، اعتمدنا على Django 3.2 المدعوم بواسطة Python 3.6 أو أحدث. سنقوم بنشر التطبيق كحاوية باستخدام Docker وتشغيله باستخدام خادم Gunicorn. بالطبع، قبل نشر تطبيق Django في حاوية، سيتعين عليك إجراء بعض التعديلات على كود المشروع للتعامل مع أشياء مثل تسجيل البيانات إلى تدفقات المخرجات القياسية والعمل مع متغيرات البيئة. يمكن نقل الملفات الثابتة مثل ملفات CSS و JavaScript والصور إلى خدمات تخزين الكائنات للسماح بإدارة سهلة للملفات من مكان واحد في بيئة متعددة الحاويات.
سنوضح لك كيفية تنفيذ هذه التعديلات بناءً على منهجية twelve-factor لبناء تطبيقات ويب قابلة للتطوير. بمجرد الانتهاء من التعديلات، ستقوم ببناء صورة Docker للتطبيق ونشر التطبيق المعبأ في حاويات باستخدام Docker. نوصي باتباع الخطوات الموضحة في البرنامج التعليمي للحصول على فهم كامل للبرنامج التعليمي.
المتطلبات الأساسية
بما أن هذا برنامج تعليمي عملي، فإننا نشجعك على إعداد التكوين أدناه لمساعدتك في المتابعة:
-
خادم Ubuntu 20.04. يمكنك اتباع الخطوات من 1 إلى 4 من هذا البرنامج التعليمي خطوة بخطوة لمساعدتك في إعداد خادم Ubuntu الخاص بك على CloudSigma.
-
تأكد من إضافة مستخدم يتمتع بامتيازات sudo على كلا العقدتين اللتين سنستخدمهما لتشغيل الأوامر كما هو موضح في البرنامج التعليمي أعلاه.
-
قم بتثبيت Docker على الخادم. يمكنك اتباع الخطوات 1 و 2 و 3 من برنامجنا التعليمي حول تثبيت وتشغيل Docker. تذكر إضافة مستخدم sudo الذي تم إنشاؤه أعلاه إلى مجموعة Docker.
-
مساحة تخزين كائنات متوافقة. يدعم Django العديد من خدمات التخزين كما هو موضح في وثائق django-storages. يمكنك اختيار الخدمة التي تفضلها واتباع الوثائق لإعدادها. في هذا البرنامج التعليمي، سنستخدم MinIO وهي خدمة تخزين سحابي متوافقة مع S3.
-
مثيل قاعدة بيانات SQL. يدعم Django العديد من قواعد بيانات SQL التي يمكنك اختيارها بحرية. في هذا البرنامج التعليمي، سنستخدم PostgreSQL. لن يتم نشر قاعدة بيانات PostgreSQL داخل حاوية. سنقوم بإعداد خادم Ubuntu منفصل لاستضافة مثيل PostgreSQL لضمان تحقيق إعداد متعدد الحاويات بالإضافة إلى استمرار البيانات. يمكنك إنشاء مثيل Ubuntu 20.04 آخر واتباع هذا البرنامج التعليمي لـ إعداد مثيل قاعدة بيانات PostgreSQL على Ubuntu. تذكر إضافة دور في قاعدة بيانات PostgreSQL لمستخدم sudo الخاص بك كما هو موضح في الخطوات 2 و 3. سيسمح لك هذا الدور بالاتصال بقاعدة البيانات من الخوادم الأخرى التي تستضيف حاوياتك.
وفقًا لهذه المتطلبات الأساسية، يجب أن يكون لديك مثيلان لخادم Ubuntu. سيعمل أحد المثيلين على تشغيل حاوية Docker الخاصة بك، وسيعمل المثيل الآخر على تشغيل مثيل PostgreSQL. لنبدأ!
الخطوة 1: تكوين مثيل قاعدة بيانات PostgreSQL
في هذا القسم، سنقوم بتعديل تكوينات Postgres على خادم Ubuntu الذي يقوم بتشغيل مثيل Postgres. سيسمح هذا بالاتصالات من عنوان IP خارجي. بمجرد الاتصال، يمكننا إنشاء قاعدة بيانات ودور مستخدم، خاصين بتطبيق Django Polls الذي نقوم بنشره.
أولاً، إذا كنت قد قمت بإعداد بيئتك وفقًا لـ المتطلبات الأساسية، فيجب أن يكون لديك دور في قاعدة بيانات PostgreSQL الخاصة بك لمستخدم sudo الخاص بك. بعد ذلك، نحتاج إلى تعيين كلمة مرور لهذا الدور. أثناء وجودك على الخادم الذي يقوم بتشغيل PostgreSQL، قم بتسجيل الدخول إلى طرفية Postgres باستخدام الأمر التالي:
|
1 |
sudo -u postgres psql |
بمجرد الدخول إلى طرفية Postgres، أصدر الأمر \password لتعديل كلمة مرور المستخدم. صيغة الأمر \password هي \password <username>. بالنسبة لحالتنا، الأمر:
|
1 |
\password cloudsigma |
أدخل كلمة المرور وقم بتأكيدها. احفظ كلمة المرور هذه في مكان آمن لأنك ستستخدمها للمصادقة من خادم Ubuntu الآخر لاحقًا. بعد ذلك، اكتب exit واضغط على Enter للخروج من طرفية Postgres.
إذا قمت بتمكين جدار الحماية (ufw) على مثيل خادم PostgreSQL، فستحتاج إلى السماح بمرور حركة المرور إلى منفذ Postgres الافتراضي 5432. يمكنك تقييد حركة المرور لتصدر فقط من عنوان IP محدد لخادم Ubuntu الآخر الذي سيقوم بتشغيل حاوية Docker. قم بتنفيذ الأمر التالي لإضافة قاعدة ufw، مع استبدال عنوان IP الخاص بك حيث تم تمييزه:
|
1 |
sudo ufw allow from ubuntu_server_ip_address to any port 5432 |
سيضمن هذا أن خادمك فقط هو من يمكنه الاتصال بمثيل PostgreSQL. بينما يسمح ذلك بمرور حركة المرور عبر جدار الحماية، فإنك تحتاج أيضًا إلى تعديل ملفات تكوين PostgreSQL للسماح بالاتصال من عنوان IP البعيد. بشكل افتراضي، يسمح التكوين فقط بالاتصال من localhost. توجد ملفات تكوين PostgreSQL في دليل /etc/postgresql/12/main . 12، في هذه الحالة، هو إصدار PostgreSQL الذي قمنا بتثبيته لهذا البرنامج التعليمي. ربما قمت بتثبيت إصدار مختلف. وبالتالي، يمكنك تغييره إلى الدليل /etc/postgresql/ وعرض المحتويات للعثور على رقم إصدار PostgreSQL الذي قمت بتثبيته.
استخدم nano لتعديل ملف التكوين:
|
1 |
sudo nano /etc/postgresql/12/main/postgresql.conf |
ابحث عن هذا السطر أدناه، وقم بإلغاء التعليق عليه، واضبطه للسماح بالاتصالات من جميع عناوين IP:
|
1 |
listen_addresses = '*' |
احفظ الملف وأغلقه. بعد ذلك، يتعين عليك تعديل ملف pg_hba.conf أيضًا، فهو موجود في نفس دليل postgresql.conf. يسمح لك ملف pg_hba.conf بتحديد أجهزة الكمبيوتر التي يمكنك الاتصال منها بمثيل PostgreSQL بالإضافة إلى طريقة المصادقة. افتح الملف باستخدام nano:
|
1 |
sudo nano /etc/postgresql/12/main/pg_hba.conf |
يرجى قراءة التعليقات في هذا الملف لفهم الكلمات الرئيسية. القسم الذي نبحث عنه هو هذا:

سيكون تركيزنا على السطر الثاني، وتريد أن يبدو مثل السطر أدناه بعد إلغاء التعليق:
|
1 |
host all all your_ubuntu_server_ip/24 md5 |
يرجى استبدال الجزء المميز بعنوان IP الخاص بخادم Ubuntu للسماح له بالاتصال بمثيل PostgreSQL. احفظ الملف بمجرد أن تصبح جاهزًا. أعد تشغيل قاعدة بيانات PostgreSQL لتطبيق التغييرات:
|
1 |
sudo service postgresql restart |
يجب أن يكون خادم Ubuntu الآخر الخاص بنا والذي يحمل عنوان IP المحدد قادرًا على الاتصال بمثيل Postgres.
الخطوة 2: الاتصال بمثيل خادم PostgreSQL وإنشاء قاعدة بيانات ومستخدم
في هذه الخطوة، سنحاول التأكد من أن مثيل Ubuntu الذي يخدم حاوية Docker الخاصة بنا يمكنه الاتصال بالخادم الآخر الذي يقوم بتشغيل مثيل PostgreSQL. قم بتسجيل الدخول إلى مثيل Ubuntu الذي يحتوي على Docker وقم بتثبيت حزمة postgresql-client داخل جهاز Ubuntu المضيف (وليس داخل الحاوية بعد).
كالمعتاد، قم أولاً بتحديث حزمة apt ثم قم بتثبيت الحزمة باستخدام الأوامر التالية:
|
1 |
sudo apt update |
|
1 |
sudo apt install postgresql-client |
ستساعدك الحزمة المثبتة أعلاه في إنشاء قاعدة بيانات ومستخدم لتطبيقك. بعد ذلك، نحتاج إلى الاتصال بمثيل PostgreSQL عن طريق إرسال معلمات الاتصال إلى عميل Postgresql.
تتبع معلمات الاتصال هذا النحو:
|
1 |
psql -U username -h host -p port -d database --set=sslmode=require |
في هذا الأمر، الـ username هو المستخدم/الدور الذي أضفته إلى قاعدة بيانات PostgreSQL الخاصة بك. host هو عنوان IP لمثيل Ubuntu الذي يقوم بتشغيل قاعدة بيانات PostgreSQL الخاصة بك. port هو المنفذ الافتراضي الذي يستمع عليه Postgres للاتصالات الواردة، أي 5432. في مكان الـ database، سنستخدم قاعدة البيانات الافتراضية المسماة postgres التي تأتي مع تثبيت PostgreSQL. استبدل قيمك في الأجزاء المحددة بشكل مناسب واضغط على Enter. عند مطالبتك بذلك، أدخل كلمة المرور التي قمت بتعيينها. يؤدي هذا إلى تسجيل دخولك إلى موجه Postgres حيث يمكنك إدارة قاعدة البيانات.
لقد اتصلت بنجاح بمثيل PostgreSQL. يمكنك الآن إنشاء قاعدة بيانات لتطبيق استطلاعات Django. لنطلق عليها اسم django_polls:
|
1 |
CREATE DATABASE django_polls; |
تأكد من أن عبارتك تنتهي بفاصلة منقوطة لتجنب الوقوع في أخطاء. بعد ذلك، انتقل إلى قاعدة بيانات django_polls باستخدام الأمر:
|
1 |
\c django_polls; |
بعد ذلك، قم بإنشاء مستخدم قاعدة بيانات خاص بهذا المشروع. لنطلق على المستخدم اسم django_user:
|
1 |
CREATE USER django_user WITH PASSWORD 'password'; |
اختر كلمة مرور آمنة لمستخدمك. بمجرد الانتهاء، نحتاج إلى تعديل معلمات الاتصال للمستخدم الذي أنشأناه للتو. يساعد هذا في تسريع عمليات قاعدة البيانات من خلال ضمان عدم الاستعلام عن القيم الصحيحة وتعيينها في كل مرة يتم فيها إنشاء اتصال.
قم بتعيين الترميز الافتراضي الذي يتوقعه Django كـ UTF-8:
|
1 |
ALTER ROLE django_user SET client_encoding TO 'utf8'; |
بعد ذلك، قم بتعيين مخطط عزل المعاملات الافتراضي إلى “ read committed”، مما يمنع القراءات من المعاملات غير الملتزم بها:
|
1 |
ALTER ROLE django_user SET default_transaction_isolation TO 'read committed'; |
قم بتعيين منطقتك الزمنية. لإبقاء البرنامج التعليمي عالميًا، سنستخدم UTC:
|
1 |
ALTER ROLE django_user SET timezone TO 'UTC'; |
أخيرًا، امنح امتيازات إدارية لقاعدة البيانات للمستخدم الجديد:
|
1 |
GRANT ALL PRIVILEGES ON DATABASE django_polls TO django_user; |
اخرج من موجه PostgreSQL عندما تكون مستعدًا:
|
1 |
\q |
هذا كل شيء بالنسبة لهذه الخطوة. بمجرد تكوين تطبيق Django بشكل صحيح، يجب أن يكون قادرًا على إدارة قاعدة البيانات الخاصة بك.
الخطوة 3: سحب التطبيق من مستودع Git وتحديد التبعيات
في هذه الخطوة، سنقوم باستنساخ مستودع تطبيق Django-polls . يحتوي هذا المستودع على الكود الخاص بـ Django’s برنامج تعليمي لكتابة تطبيق Django الأول الخاص بك.
قم بتسجيل الدخول إلى خادم Ubuntu الذي يقوم بتشغيل Docker، وأنشئ دليلًا باسم django_project وانتقل إليه:
|
1 2 |
mkdir django_project cd django_project |
ثم، قم باستنساخ المستودع في الدليل باستخدام الأمر التالي:
|
1 |
git clone https://github.com/jaymoh/django-polls.git |
انتقل إلى الدليل واعرض المحتويات:
|
1 |
cd django-polls |
اعرض محتويات الدليل:
|
1 |
ls |

لاحظ العناصر التالية:
-
manage.py: هذا ملف هو المدخل إلى أداة سطر الأوامر التي يوفرها Django لإدارة تطبيقك.
-
mysite: دليل يحتوي على نطاق مشروع Django وإعدادات الكود.
-
polls: دليل يحتوي على polls الخاص بالتطبيق.
-
templates: يحتوي على ملفات قوالب مخصصة لصفحات المسؤول.
لمعرفة المزيد حول كيفية إنشاء المشروع بالفعل، يرجى إلقاء نظرة على Writing your first Django app من الوثائق الرسمية. داخل الـ django-polls دليل، نريد تحديد تبعيات Python الخاصة بنا في ملف نصي. سنطلق عليه اسم requirements.txt. افتح الملف باستخدام المحرر المفضل لديك:
|
1 |
nano requirements.txt |
قم بلصق السطور التالية داخل الملف للإعلان عن التبعيات:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
Django==3.2.9 gunicorn==20.1.0 docutils==0.18.1 sqlparse==0.4.2 jmespath==0.10.0 psycopg2==2.9.2 python-dateutil==2.8.2 pytz==2021.3 six==1.16.0 urllib3==1.26.7 django-storages==1.12.2 minio==7.1.6 django-minio-backend==3.3.2 django-dotenv==1.4.2 boto3==1.21.38 |
في هذا الملف، قمنا بتحديد تبعيات Python بإصداراتها الدقيقة التي يجب تثبيتها عند إنشاء التطبيق. يتضمن بعضها Django, django-storages للتفاعل مع حاويات تخزين الكائنات، ومحول psycopg2 لـ PostgreSQL، وخادم gunicorn WSGI، وتبعيات إضافية أخرى. احفظ الملف وأغلقه عند الانتهاء.
الخطوة 4: تكوين متغيرات البيئة لتطبيق Django
توصي منهجية twelve-factor app باستخراج التكوينات المكتوبة بشكل صلب من قاعدة كود تطبيقك. ومن خلال القيام بذلك، ستحصل على حرية تغيير سلوك التطبيق في وقت التشغيل عن طريق تعديل متغيرات البيئة دون لمس قاعدة الكود. يعمل Docker مع هذا الإعداد، لذلك سنقوم بتعديل ملف الإعدادات للعمل مع متغيرات البيئة. Kubernetes يعمل أيضًا مع إعداد التكوين هذا. سنقوم بمشاركة برنامج تعليمي آخر حول النشر باستخدام Kubernetes على CloudSigma blog.
ملف settings.py هو ملف الإعدادات الرئيسي لمشروع Django. وهو عبارة عن وحدة Python تستخدم هياكل البيانات الأصلية لتكوين التطبيق. بالنسبة لتطبيقنا، يوجد الملف في الموقع django-polls/mysite/settings.py. معظم قيمه مكتوبة بشكل صلب. سيتطلب منك هذا تعديل ملف التكوين في قاعدة الكود إذا قمت بتغيير سلوك التطبيق. نريد تغيير ذلك. لحسن الحظ، توفر Python وظيفة getenv في وحدة os . يمكننا استخدامها لتكوين Django لقراءة معلمات التكوين من متغيرات البيئة المحلية بدلاً من ذلك.
دعنا نواصل بتعديل ملف django-polls/mysite/settings.py لاستبدال القيم المكتوبة بشكل صلب للمتغيرات. قد نرغب في التحديث في وقت التشغيل باستدعاء os.getenv. تقرأ هذه الوظيفة القيمة المحددة في اسم متغير البيئة المقدم. اختياريًا، يمكنك تقديم معلمة ثانية وهي قيمة افتراضية سيتم استخدامها إذا لم يتم تعيين متغير البيئة.
إليك مثال:
|
1 |
SECRET_KEY = os.getenv('DJANGO_SECRET_KEY') |
في السطر أعلاه، نطلب من Django استرداد المفتاح السري من متغير البيئة. لا نقدم قيمة احتياطية لأننا سنوفر المفتاح خارجيًا. إذا لم يكن موجودًا، يجب أن يفشل التطبيق في العمل. أثناء توفير المفتاح السري خارجيًا، نريد أيضًا التأكد من أن جميع نسخ تطبيقنا المعبأة في حاويات تستخدم نفس المفتاح عبر الخوادم المختلفة. هذا يتجنب المشاكل المحتملة التي تنشأ عندما تستخدم نسخ التطبيق المختلفة مفاتيح مختلفة.
إليك مثال آخر مع خيار افتراضي:
|
1 |
DEBUG = os.getenv('DEBUG', False) |
في هذا السطر، نحدد متغير بيئة DEBUG يجب قراءته. ومع ذلك، إذا لم يتم تعيينه، فقد قدمنا معلمة ثانية سيتم تمريرها إلى متغير إعدادات DEBUG. يتم تعيين DEBUG على False لضمان عدم تمرير المعلومات الحساسة إلى الواجهة الأمامية في حالة وجود مشكلة في التطبيق. ومع ذلك، إذا كنا في وضع التطوير، فنحن نريد تعيينه على True للسماح لنا برؤية معلومات الخطأ لتسهيل إصلاح الأخطاء علينا.
الآن بعد أن عرفت أهمية متغيرات البيئة، افتح ملف django_project/django-polls/settings.py في المحرر الخاص بك. أولاً، قم باستيراد وحدة os عن طريق إضافة هذا السطر في الجزء العلوي من ملف settings.py:
|
1 |
import os |
ثم، ابحث عن هذه المتغيرات وقم بتحديثها على النحو التالي:
|
1 2 3 |
SECRET_KEY = os.getenv('DJANGO_SECRET_KEY') DEBUG = os.getenv('DEBUG', False) ALLOWED_HOSTS = os.getenv('DJANGO_ALLOWED_HOSTS', '127.0.0.1').split(',') |
في ALLOWED_HOSTS ، نحدد أنه يجب الحصول على القيمة من DJANGO_ALLOWED_HOSTS ، وتقسيمها إلى قائمة Python باستخدام الفاصلة ( ,) كفاصل. إذا كان المتغير مفقودًا، فإن ALLOWED_HOSTS يتم تعيينه إلى 127.0.0.1.
بعد ذلك، قم بالتمرير عبر الملف وابحث عن قسم DATABASES ، وقم بتهيئته ليقرأ أيضًا من متغيرات البيئة:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.{}'.format( os.getenv('DB_ENGINE', 'sqlite3') ), 'NAME': os.getenv('DB_DATABASE', 'django_polls'), 'USER': os.getenv('DB_USERNAME', 'your_db_username'), 'PASSWORD': os.getenv('DB_PASSWORD', 'your_secure_default_password'), 'HOST': os.getenv('DB_HOST', '127.0.0.1'), 'PORT': os.getenv('DB_PORT', 5432), 'OPTIONS': json.loads( os.getenv('DB_OPTIONS', '{}') ), } } |
لاحظ أننا أضفنا وحدة json.loads. يجب عليك أيضًا إضافة استيراد للوحدة في الجزء العلوي من ملف settings.py :
|
1 |
import json |
تقوم دالة json.loads بإلغاء تسلسل كائن JSON الممرر إلى DATABASES['default']['OPTIONS'] من متغير البيئة DB_OPTIONS. يتيح لنا تحديد هذا الخيار تمرير بنية بيانات عشوائية لتعريف تكوين قاعدة البيانات. يتضمن محرك قاعدة البيانات مجموعة من الخيارات الصالحة القابلة للتطبيق عليه. يمنحنا خيار JSON المرونة لتشفير كائن JSON بالمعلمات المناسبة لمحرك قاعدة البيانات الذي نستخدمه في ذلك الوقت.
يحدد DATABASES['default']['NAME'] اسم قاعدة البيانات في نظام إدارة قواعد البيانات العلاقية الذي قمنا بإعداده. في حالة استخدام قاعدة بيانات SQLite، يجب عليك تحديد المسار إلى ملف قاعدة البيانات.
لاحظ أن Python توفر عدة طرق لـ قراءة متغيرات البيئة الخارجية. لقد استخدمنا طريقة واحدة فقط منها. أنت حر في البحث واستخدام طرق أخرى. في هذه الخطوة، تعلمت كيفية العمل مع متغيرات البيئة الخارجية. يمنحك هذا المرونة لتغيير المتغيرات وتعديل سلوك التطبيق الذي يعمل في الحاويات. في الخطوة التالية، ستتعلم كيفية العمل مع خدمات تخزين الكائنات.
الخطوة 5: العمل مع خدمات تخزين الكائنات الخارجية
تتمثل الميزة الرئيسية لتحويل تطبيقك إلى حاوية في جعله محمولاً لسهولة نشر نسخ متعددة من التطبيق عند زيادة حركة المرور. وبالتالي، إفساح المجال للتوسع. ومع ذلك، فإن هذا يثير مسألة الحفاظ على إصدارات الملفات والأصول الثابتة عبر الحاويات المختلفة. بفضل التحسينات في تكنولوجيا السحاب، يمكنك تفريغ هذه العناصر الثابتة المشتركة إلى وحدة تخزين خارجية. بعد ذلك، يمكنك جعل الملفات قابلة للوصول عبر الشبكة لجميع الحاويات قيد التشغيل. بدلاً من محاولة مزامنة الملفات عبر الحاويات المختلفة قيد التشغيل، لديك مكان مركزي واحد لإدارتها.
المفهوم الذي نحاول شرحه أعلاه هو استخدام خدمات تخزين الكائنات السحابية، أو خدمات التخزين البسيطة (S3). يحتوي Django على حزمة تسمى django-storages الذي يتيح لك العمل مع واجهات التخزين الخلفية البعيدة. Django-storages العمل مع معظم خدمات تخزين الكائنات المتوافقة مع S3 مثل FTP و SFTP و AWS S3 من Amazon و Google Cloud Storage و Dropbox و Azure Storage وغيرها. في هذا البرنامج التعليمي، سنستخدم MinIO. لا تتردد في استخدام أي خدمات تخزين كائنات متوافقة مع S3. MinIOتقدم MinIO تخزين كائنات عالي الأداء ومتوافق مع S3. باستخدام MinIO، يمكنك بناء بنية تحتية للبيانات متوافقة مع S3 على أي سحابة.
سنوضح لك كيفية إعداد خدمة تخزين MinIO على منصة CloudSigma. يرجى اتباع الخطوات التالية:
-
ابدأ بـ إنشاء حساب على CloudSigma. إذا واجهت أي مشاكل أثناء إنشاء تخزين MinIO، يرجى التواصل مع دعم الدردشة المباشرة المجاني على مدار الساعة طوال أيام الأسبوع من CloudSigma’s، وسيقومون بمساعدتك.
-
أضف معلومات الفوترة الخاصة بك.
-
بعد ذلك، اطلب حاوية التخزين (bucket) العامة الخاصة بك من هنا: https://blog.cloudsigma.com/xxxx. ستحتاج إلى الاتصال بدعم الدردشة المباشرة للحصول على بيانات اعتماد الوصول إلى حسابك.
-
بمجرد إنشاء بيئة تخزين الكائنات MinIO الخاصة بك، سيتم تزويدك ببيانات اعتماد الوصول وإرشادات أخرى للوصول إليها. يجب أن تتضمن بيانات الاعتماد الخاصة بك MINI_ACCESS_KEY, MINIO_SECRET_KEY، و MINIO_URL. ستستخدم هذه المفاتيح في الإرشادات أدناه.
دعنا نجري بعض التغييرات الإضافية على ملف mysite/settings.py الذي قمنا بتعديله في الخطوة السابقة. في الملف، أضف تطبيق storages إلى قائمة Django لـ INSTALLED_APPS:

يتم تثبيت تطبيق storages عبر django-storages كما هو محدد في ملف requirements.txt. انتقل إلى أسفل الملف واستبدل متغير STATIC_URL بمقتطف الكود التالي:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
# Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/3.2/howto/static-files/ DEFAULT_FILE_STORAGE = os.getenv('STATIC_DEFAULT_FILE_STORAGE', 'storages.backends.s3boto3.S3Boto3Storage') AWS_S3_ENDPOINT_URL = os.getenv('MINIO_URL') AWS_ACCESS_KEY_ID = os.getenv('MINIO_ACCESS_KEY') AWS_SECRET_ACCESS_KEY = os.getenv('MINIO_SECRET_KEY') AWS_STORAGE_BUCKET_NAME = os.getenv('STATIC_MINIO_BUCKET_NAME') AWS_S3_OBJECT_PARAMETERS = { 'CacheControl': 'max-age=86400', } AWS_LOCATION = 'static' AWS_DEFAULT_ACL = 'public-read' STATICFILES_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage' STATIC_URL = '{}/{}/'.format(AWS_S3_ENDPOINT_URL, AWS_LOCATION) STATIC_ROOT = "static/" |
لاحظ أن بعض متغيرات التكوين مكتوبة بشكل مباشر (hard-coded):
-
STATICFILES_STORAGE: يحدد واجهة التخزين الخلفية التي سيستخدمها Django للتعامل مع الملفات الثابتة. في دليلنا، نستخدم تخزين MinIO، ولكن يمكنك استخدام أي واجهة خلفية متوافقة مع S3 كما هو موضح في وثائق Django Storages.
-
AWS_S3_OBJECT_PARAMETERS: يحدد ترويسات التحكم في ذاكرة التخزين المؤقت (cache-control).
-
AWS_LOCATION: نستخدم هذا لتعيين دليل داخل حاوية التخزين حيث سيتم تخزين جميع الملفات الثابتة. أنت حر في اختيار اسم مختلف.
-
AWS_DEFAULT_ACL: يحدد قائمة التحكم في الوصول (ACL) للملفات الثابتة. تعيين القيمة إلى ‘ public-Read’ سيجعل الملفات سهلة الوصول لجميع المستخدمين العامين.
-
STATIC_URL: يستخدم Django عنوان URL الأساسي المحدد في هذا المتغير لإنشاء عناوين URL للملفات الثابتة. يتم اشتقاق عنوان URL الأساسي في هذه الحالة من دمج عنوان URL لنقطة النهاية والدليل الفرعي للملفات الثابتة.
-
STATIC_ROOT: يحدد مكان تجميع الملفات الثابتة محليًا قبل نسخها إلى تخزين الكائنات البعيد.
لدينا أيضًا بعض متغيرات البيئة المحددة خارجيًا للحفاظ على المرونة وقابلية النقل:
-
AWS_STORAGE_BUCKET_NAME: يحدد اسم حاوية التخزين التي سيقوم Django برفع الأصول إليها.
-
AWS_S3_ENDPOINT_URL: يحدد عنوان URL لنقطة النهاية المستخدم للوصول إلى خدمة تخزين الكائنات. سيكون هذا هو عنوان URL المرتبط بالخادم الذي يستضيف خدمة MinIO الخاصة بك.
احفظ الملف وأغلقه عند الانتهاء من التعديل.
بمجرد تطبيق هذه الإعدادات وتثبيت تبعيات Python المعلنة، يمكنك تشغيل أمر Django manage.py collectstatic في أي وقت لتجميع ملفات مشروعك الثابتة ورفعها إلى الواجهة الـخلفية لتخزين الكائنات البعيدة:
|
1 |
python manage.py collectstatic |
ومع ذلك، لم نقم بإعداد ملف env بالتكوينات بعد، لذا فمن المحتمل أن يفشل.
عند تشغيل الأمر، يستغرق الأمر بعض الوقت لنسخ أصولك إلى مساحة تخزين MinIO السحابية اعتمادًا على حجمها وسرعة الإنترنت لديك.
هذا كل شيء بالنسبة لهذه الخطوة. دعنا نرى كيف يمكننا التعامل مع دفع سجلات Django إلى Docker Engine حتى تتمكن من عرضها باستخدام أمر docker logs في الخطوة التالية.
الخطوة 6: إعداد تسجيل السجلات في تطبيق Django
أثناء وجودك في وضع تصحيح الأخطاء (Debug)، عندما يكون خيار DEBUG معينًا على True، يقوم Django بتسجيل المعلومات في المخرجات القياسية والخطأ القياسي. تظهر معلومات السجل عادةً من الطرفية التي قمت بتشغيل خادم HTTP للتطوير منها.
أثناء وجودك في بيئة الإنتاج، من المحتمل أنك تستخدم خادم HTTP مختلفًا، ويكون خيار DEBUG معينًا على False. سيستخدم Django طريقة تسجيل مختلفة في هذه الحالة. يرسل Django سجلات ذات أولوية ERROR أو CRITICAL إلى حساب بريد إلكتروني إداري تحدده أنت. هذا يعمل بشكل رائع في العديد من الحالات.
في إعدادات الحاويات وKubernetes، يوصى بشدة بتسجيل السجلات في المخرجات القياسية والخطأ القياسي. يتم جمع رسائل السجل في دليل واحد على نظام ملفات العقدة (Node) ويمكن الوصول إليها بسهولة باستخدام أوامر kubectl و docker . من خلال وجود نقطة تسجيل مركزية على نظام ملفات العقدة، يمكن لفريق العمليات تشغيل العمليات بسهولة على كل عقدة لمراقبة السجلات وتوجيهها. وبالتالي، يجب علينا تكوين تطبيقنا لكتابة السجلات في هذا الإعداد القياسي.
سيسعدك معرفة أن Django يستفيد من وحدة logging القابلة للتخصيص بدرجة كبيرة من مكتبة Python القياسية. يتيح لك هذا تحديد قاموس يمر عبر logging.config.dictConfig لتحديد المخرجات والتنسيق المطلوبين. إليك مقال رائع حول تسجيل سجلات Django، بالطريقة الصحيحة يمكن أن يساعدك في إتقان تقنيات تسجيل سجلات Django.
افتح ملف django-polls/mysite/settings.py في المحرر الخاص بك. أضف استيرادًا لمكتبة Python logging.config في الجزء العلوي من الملف:
|
1 |
import logging.config |
حتى الآن، مع جميع عمليات الاستيراد التي أضفناها، يجب أن يبدو قسم الاستيراد الخاص بك في settings.py كالتالي:

تأخذ مكتبة logging.config قاموسًا لتكوين التسجيل الجديد من خلال دالة dictConfig لتجاوز سلوك تسجيل السجلات الافتراضي لـ Django.
قم بالتمرير إلى أسفل الملف وأضف مقتطف رمز تكوين تسجيل السجلات التالي:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
# تكوين تسجيل السجلات # تعطيل التكوين السابق LOGGING_CONFIG = None # الحصول على مستوى السجل من البيئة LOGLEVEL = os.getenv('DJANGO_LOGLEVEL', 'info').upper() logging.config.dictConfig({ 'version': 1, 'disable_existing_loggers': False, 'formatters': { 'console': { 'format': '%(asctime)s %(levelname)s [%(name)s:%(lineno)s] %(module)s %(process)d %(thread)d %(message)s', }, }, 'handlers': { 'console': { 'class': 'logging.StreamHandler', 'formatter': 'console', }, }, 'loggers': { '': { 'level': LOGLEVEL, 'handlers': ['console',], }, }, }) |
LOGGING_CONFIG مُعيّن على None لتعطيل/مسح تكوينات تسجيل الأحداث الافتراضية التي يحددها Django. LOGLEVEL يتم تعيينه بواسطة DJANGO_LOGLEVEL متغير البيئة. ومع ذلك، إذا لم يكن موجودًا، فنحن نريد تعيينه على ‘ info’.
إنّ logging.config التي استوردناها في الأعلى توفر دالة dictConfig تُستخدم لتعيين قاموس تكوين جديد. يحدد هذا القاموس تنسيق النص باستخدام المفتاح formatters . ويتم تعيين المخرجات باستخدام المفتاح handlers ، وأخيرًا، يحدد المفتاح loggers الرسالة التي يجب أن تذهب إلى أي معالج.
بمجرد تحديد هذه الإعدادات، Docker سيعرض سجلات الأحداث من خلال الأمر docker logs . وبالمثل، في درس تعليمي آخر سنقوم به لـ Kubernetes، يمكنك عرض سجلات الأحداث باستخدام الأمر kubectl logs . دعنا الآن نبدأ عملية إنشاء الحاويات في الخطوة التالية.
الخطوة 7: تحديد ملف Dockerfile الخاص بالتطبيق
في هذه الخطوة، نحدد التكوين لتشغيل صورة الحاوية التي ستشغل تطبيق Django الذي يخدمه خادم Gunicorn WSGI. سنحدد بيئة التشغيل لبناء صورة حاوية، وتثبيت التطبيق وتبعياته، وإجراء بعض التكوينات النهائية.
-
الصورة الأب لتطبيق Django
إن اتخاذ القرار بشأن الصورة الأساسية التي ستبني عليها حاويتك هو أول قرار ستتخذه عند التعامل مع عمليات النشر المعتمدة على الحاويات. بالطبع، لديك خيار بناء صور الحاويات الخاصة بك من الصفر (SCRATCH)، أي نظام ملفات فارغ، أو تأسيسها على صورة حاوية موجودة بالفعل. نظرًا لأننا لا نريد إعادة اختراع العجلة، فسنقوم ببناء صورتنا من صورة أساسية. هناك العديد من صور الحاويات مفتوحة المصدر المتاحة من مستودع صور حاويات Docker الرسمي. ما لم تكن تبني صورتك من الصفر، يوصى بشدة باستخدام صورة من مستودع Docker الرسمي (Docker Hub). وذلك لأن Docker يتحقق من الصور لاتباع أفضل الممارسات، ويضمن توفر التحديثات المنتظمة والتصحيحات الأمنية.
بما أن Django هو إطار عمل Python، فسنستفيد من صورة ذات بيئة Python قياسية تحتوي على الأدوات والمكتبات التي نحتاجها مثبتة بالفعل. من الصفحة الرسمية لـ صور Python على Docker Hub، يمكنك العثور على صورة تعتمد على Python لإصدارات مختلفة من Python.
من خلال دروسنا التعليمية المتنوعة المعتمدة على Docker، ستلاحظ أننا نستخدم صورًا تعتمد على Alpine Linux. يوفر Alpine Linux بيئة نظام تشغيل قوية ولكنها خفيفة لتشغيل التطبيقات المعبأة في حاويات. على الرغم من أن نظام الملفات الخاص به صغير، إلا أنه قابل للتوسيع ويأتي مع نظام إدارة حزم كامل مع إمكانية إضافة وظائف.
عند اختيار صورة أساسية على Docker Hub، قد تلاحظ وجود علامات (tags) متعددة متاحة لكل صورة. من أجل Python، لدينا 3-alpine، والتي تشير إلى أحدث إصدار من صورة Python 3 لأحدث إصدار من Alpine. هذا يعني أنه في حالة عمل مشروعك مع إصدار صورة أقدم، فقد يتعطل عندما يقوم صيانة صورة Docker بإجراء تحديث. لتجنب مثل هذه السيناريوهات في المستقبل، يوصى دائمًا باختيار العلامات الأكثر تحديدًا للصورة التي تريد استخدامها.
في هذا البرنامج التعليمي، سنستخدم 3.8.12-alpine3.15 كصورة أساسية لتطبيق Django الخاص بنا. سيتم تحديد هذه العلامة المحددة في Dockerfile باستخدام تعليمة FROM. سيكون ملف Dockerfile في دليل المشروع الرئيسي: django_project.
ابدأ بالانتقال خارج دليل Django-polls والعودة إلى دليل django_project :
|
1 |
cd .. |
بمجرد دخولك إلى الدليل، استخدم محرر النصوص المفضل لديك لفتح ملف يسمى Dockerfile :
|
1 |
nano Dockerfile |
بعد ذلك، قم بلصق السطر التالي لتعيين أساس صورتك:
|
1 |
FROM python:3.8.12-alpine3.15 |
تحدد الكلمة المفتاحية FROM نقطة البداية لصورة Docker مخصصة. ومع تحديد ذلك، يمكننا الاستمرار في إضافة التعليمات لإعداد التطبيقات. ستقوم هذه التعليمات بتثبيت التبعيات اللازمة، ونسخ ملفات التطبيق، وإعداد بيئة التشغيل.
أضف مقتطف الكود التالي داخل ملف Dockerfile:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
ADD django-polls/requirements.txt /app/requirements.txt RUN set -ex \ && apk add --no-cache --virtual .build-deps postgresql-dev build-base \ && python -m venv /env \ && /env/bin/pip install --upgrade pip \ && /env/bin/pip install --no-cache-dir -r /app/requirements.txt \ && runDeps="$(scanelf --needed --nobanner --recursive /env \ | awk '{ gsub(/,/, "\nso:", $2); print "so:" $2 }' \ | sort -u \ | xargs -r apk info --installed \ | sort -u)" \ && apk add --virtual rundeps $runDeps \ && apk del .build-deps ADD django-polls /app WORKDIR /app ENV VIRTUAL_ENV /env ENV PATH /env/bin:$PATH EXPOSE 8000 |
في مقتطف الكود هذا، نطلب من Docker نسخ ملف requirements.txt إلى /app/requirements.txt لضمان توفر تبعيات التطبيق على نظام ملفات الصورة. تتضمن المتطلبات جميع حزم Python المطلوبة لتشغيل التطبيق. يتم نسخ التبعيات أولاً حتى يتمكن Docker من تخزين طبقة الصورة مؤقتًا. وذلك لأن Docker يقوم بتخزين كل خطوة في Dockerfile مؤقتًا. عادةً ما يستغرق البناء الأول للصورة وقتًا أطول. سيقوم Docker بتنزيل التبعيات، ثم يقوم بتخزينها مؤقتًا. إذا لم يتغير ملف requirements.txt، فسيقوم Docker بالبناء من التخزين المؤقت، مما يجعل عمليات البناء اللاحقة أسرع.
الخطوة التالية تحتوي على تعليمة RUN التي تنفذ قائمة من أوامر Linux، المتسلسلة باستخدام عامل التشغيل && الخاص بـ Linux. تقوم الأوامر بما يلي:
-
استخدام أداة إدارة الحزم apk الخاصة بـ Alpine لتثبيت ملفات تطوير PostgreSQL وتبعيات البناء الأساسية.
-
إنشاء بيئة افتراضية لـ Python.
-
تثبيت تبعيات Python كما هي محددة في ملف requirements.txt باستخدام pip.
-
تجميع حزم وقت التشغيل اللازمة من خلال تحليل متطلبات حزم Python المثبتة.
-
إزالة أي تبعيات بناء لم تعد ضرورية.
السبب وراء تسلسل الأوامر في خطوة RUN هو تقليل طبقات الصورة. يقوم Docker بإنشاء طبقة صورة جديدة فوق نظام الملفات الحالي في كل مرة يواجه فيها ADD, COPY، أو RUN تعليمات في Dockerfile. سيؤدي ضغط الأوامر حيثما أمكن ذلك إلى تقليل عدد طبقات الصور التي يتم إنشاؤها.
لا يمكن إزالة العناصر المضافة إلى طبقات الصور في طبقة لاحقة. يجب عليك التصريح عن تعليمات لحذف العناصر غير المرغوب فيها قبل الانتقال إلى التعليمة التالية. هذا ضروري لتقليل حجم الصورة. يجب أن تلاحظ أننا أضفنا apk del في نهاية RUN . تم ذلك لإزالة تبعيات البناء بعد استخدامها لبناء حزم التطبيق.
بعد ذلك، لدينا ADD أخرى نستخدمها لنسخ كود التطبيق إلى دليل /app. بعد ذلك، سنستخدم تعليمة WORKDIR لتعيين دليل العمل للصورة إلى دليل /app ، والذي يحتوي الآن على كود التطبيق.
بعد ذلك، لدينا تعليمات ENV التي نستخدمها لتعيين متغيرين للبيئة ستوفرهما الصورة للحاويات قيد التشغيل. أولاً، نقوم بتعيين متغير VIRTUAL_ENV على /env. ثانياً، نقوم بتعيين متغير PATH ليشمل دليل /env/bin. في هذين السطرين، نقوم باستيراد برنامج النصي /env/bin/activate، وهي الطريقة التي ننشط بها بيئة افتراضية في بيئة Linux. يمكنك قراءة المزيد حول العمل مع البيئات الافتراضية في Python على أنظمة التشغيل الأخرى. التعليمة الأخيرة هي أمر EXPOSE الذي يحدد المنفذ 8000 الذي ستستمع إليه الحاوية في وقت التشغيل.
الآن، أصبح ملف Dockerfile الخاص بك مكتملاً تقريباً، باستثناء الأمر الافتراضي الذي سيتم تشغيله عند بدء تشغيل الحاويات. دعنا نحدده في القسم التالي.
-
فهم الأمر الافتراضي لصورة Docker
عند بدء تشغيل حاوية Docker، قد توفر أمراً لتنفيذه. ومع ذلك، إذا لم توفر أمراً، فإن الأمر الافتراضي لصورة Docker سيحدد ما سيحدث عند بدء تشغيل الحاوية. نستخدم تعليمات ENTRYPOINT أو CMD بشكل فردي أو معاً لتحديد أمر افتراضي داخل Dockerfile.
إذا اخترت تحديد كل من ENTRYPOINT و CMD، ففي تعليمة ENTRYPOINT، تحدد الملف القابل للتنفيذ الذي سيتم تشغيله بواسطة الحاوية. وفي تعليمة CMD، حدد قائمة الوسائط الافتراضية للأمر القابل للتنفيذ. يمكنك تجاوز قائمة الوسائط الافتراضية عن طريق إلحاق وسائط بديلة على سطر الأوامر عند تشغيل الحاوية بالتنسيق التالي:
|
1 |
docker run <image> <arguments> |
يمنع هذا التنسيق المطورين من تجاوز أمر ENTRYPOINT بسهولة. يتم تعريف أمر ENTRYPOINT لاستدعاء برنامج نصي يقوم بإعداد البيئة وتنفيذ إجراءات مختلفة بناءً على قائمة الوسائط المقدمة.
يمكنك استخدام تعليمة ENTRYPOINT بمفردها لتكوين الملف القابل للتنفيذ للحاوية. ومع ذلك، لا يسمح هذا التنسيق بتحديد قائمة وسائط افتراضية. يمكنك تقديم وسائط عند تشغيل الحاوية باستخدام أمر docker run .
إذا اخترت استخدام CMD بمفردها، يفسرها Docker على أنها الأمر الافتراضي وقائمة الوسائط، والتي يمكنك تجاوزها في وقت التشغيل. يمكنك العثور على مزيد من المعلومات في وثائق مرجع Dockerfile الرسمية.
دعنا نرى كيف يمكننا تطبيق المعلومات التي تعلمتها حول الأوامر الافتراضية على مثال الحاوية الخاص بنا. نريد تشغيل التطبيق افتراضياً باستخدام خادم gunicorn. في حين أن قائمة الوسائط التي تم تمريرها إلى خادم gunicorn لا يجب أن تكون قابلة للتكوين في وقت التشغيل، فإننا نريد المرونة في تشغيل أوامر أخرى لأغراض مثل تصحيح الأخطاء أو إدارة التكوينات (تهيئة قاعدة البيانات، وجمع الأصول الثابتة، وما إلى ذلك). كما ترى، فمن مصلحتنا استخدام CMD لتحديد أمر افتراضي يسمح لنا بتجاوزه عند الضرورة.
فيما يلي بعض الصيغ التي يمكنك استخدامها لتحديد أمر CMD :
- CMD ["command", "argument 1", "argument 2", . . . ,"argument n"]: صيغة exec (الصيغة الموصى بها)، تأخذ أمراً وقائمة من الوسائط. وتقوم بتنفيذ الأمر مباشرة دون معالجة من غلاف الأوامر (shell).
- CMD command "argument 1" "argument 2" . . . "الوسيط n": يحدد تنسيق shell أمرًا وقائمة من الوسائط. ويقوم بتمرير قائمة الأوامر إلى shell لمعالجتها. قد تجد هذا مفيدًا إذا كنت تريد استبدال متغيرات البيئة في أمر ما، ومع ذلك، لا يمكن التنبؤ به تمامًا.
- CMD ["الوسيط 1", "الوسيط 2", . . . ,"الوسيط n"]: تنسيق قائمة الوسائط، فهو يحدد فقط قائمة الوسائط الافتراضية ويُستخدم مع ENTRYPOINT تعليمة.
سنقوم باستخدام تنسيق exec لتعريف تعليمتنا النهائية في Dockerfile. أضف السطر التالي في نهاية ملف Dockerfile:
|
1 |
CMD ["gunicorn", "--bind", ":8000", "--workers", "3", "mysite.wsgi:application"] |
يمكنك الآن حفظ وإغلاق ملف Dockerfile.
عند تشغيل الحاويات باستخدام هذه الصورة، ستقوم بتنفيذ gunicorn المرتبط بمنفذ localhost 8000 مع 3 عمال (workers)، واستدعاء دالة application في ملف wsgi.py الموجود في دليل mysite . يمكنك اختيار تقديم أمر مختلف لتجاوز الأمر الافتراضي في وقت التشغيل وتنفيذ عملية مختلفة بدلاً من gunicorn. قد ترغب في معرفة المزيد عن عمال Gunicorn.
ملف Dockerfile الخاص بك جاهز الآن ويمكنك استخدام docker build لبناء صورة التطبيق. يمكنك استخدام docker run لتشغيل الحاوية على جهاز التطوير المحلي الخاص بك.
-
بناء صورة Docker
يقوم الأمر docker build بالبحث عن ملف Dockerfile في الدليل الحالي افتراضيًا للعثور على تعليمات البناء الخاصة به. كما أنه يرسل "سياق" البناء إلى برمجية Docker الخفية (daemon). و سياق البناء هو مجموعة من الملفات التي يجب أن تكون متاحة أثناء عملية البناء. افتراضيًا، يتم تعيين الدليل الحالي الذي تقوم بتشغيل أمر docker build فيه كسياق للبناء.
أثناء وجودك في نفس الدليل الذي يحتوي على ملف Dockerfile، قم بتشغيل الأمر docker build. قم بتوفير صورة وعلامة (tag) باستخدام خيار -t ، وقم بتعيين الدليل الحالي كسياق بناء باستخدام النقطة ( .) في نهاية الأمر:
|
1 |
docker build -t django-polls:v1 . |
في هذا الأمر، قمنا بتسمية الصورة باسم django-polls والعلامة (tag) باسم v1. لاحظ النقطة في نهاية الأمر، فنحن نستخدمها للإشارة إلى الدليل الحالي كسياق للبناء.
عند اكتمال أمر docker build ، يجب أن ترى شيئًا مشابهًا للمخرجات التالية:

صورة Docker الخاصة بك جاهزة الآن. إذا لم نكن قد نقلنا بعض التكوينات إلى متغيرات بيئية خارجية، لكان بإمكانك تشغيل الحاوية بسهولة باستخدام أمر docker run . ومع ذلك، نظرًا لأننا لم نقم بتهيئة متغيرات البيئة الخارجية التي قمنا بإعدادها في ملف settings.py ، فستفشل عملية التشغيل. دعنا ننتهي من ذلك في الخطوة التالية.
الخطوة 8: إعداد بيئة التشغيل واختبار التطبيق
لقد اقتربنا من نهاية هذا البرنامج التعليمي. في هذه الخطوة، سنقوم بتهيئة متغيرات البيئة في ملف env . مع وجود متغيرات ملف env ، يمكننا إنشاء مخطط قاعدة البيانات، وتوليد الملفات الثابتة ورفعها إلى خدمة تخزين الكائنات الخارجية، وأخيرًا اختبار التطبيق.
يأتي Docker بعدة طرق يمكنك استخدامها لـ توفير متغيرات البيئة إلى الحاوية. في حالتنا، نريد تقديم قائمة بمتغيرات البيئة من خلال ملف. وبالتالي، سنستخدم طريقة --env-file .
باستخدام المحرر المفضل لديك، قم بإنشاء ملف باسم env في دليل django_project :
|
1 |
nano env |
قم بلصق قائمة المتغيرات التالية:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
DJANGO_SECRET_KEY=your_secret_key DEBUG= DJANGO_LOGLEVEL=info DJANGO_ALLOWED_HOSTS=عنوان_IP_الخاص_بخادمك DB_ENGINE=postgresql_psycopg2 DB_DATABASE=polls_db DB_USERNAME=hackins DB_PASSWORD=كلمة_مرور_قاعدة_بياناتك DB_HOST=مضيف_قاعدة_بياناتك DB_PORT=منفذ_قاعدة_بياناتك STATIC_DEFAULT_FILE_STORAGE=storages.backends.s3boto3.S3Boto3Storage STATIC_MINIO_BUCKET_NAME=test-bucket MINIO_ACCESS_KEY=مفتاح_وصول_minio_الخاص_بك MINIO_SECRET_KEY=المفتاح_السري_لـ_minio_الخاص_بك MINIO_URL=رابط_url_الخاص_بـ_minio:منفذ_minio_الخاص_بك |
المتغيرات الموجودة في القائمة هي تلك التي قمت بتعريفها في الخطوات السابقة:
-
DJANGO_SECRET_KEY: قم بتوليد قيمة فريدة وغير متوقعة كما هو موضح في مستندات Django. يمكنك استخدام هذا الأمر لتوليد سلسلة عشوائية وتعيينها للمتغير:
|
1 |
python -c 'from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())' |
-
DEBUG: لقد قمنا بتعيين هذه القيمة إلى True، ولكن بالنسبة لنشر الإنتاج، تذكر تعيينها إلى False عن طريق تركها فارغة.
-
DJANGO_LOGLEVEL: لقد قمنا بتعيين هذا إلى info، لا تتردد في ضبطه على المستوى الذي تريده.
-
DJANGO_ALLOWED_HOSTS: اضبط هذه القيمة على عنوان IP لخادم Ubuntu الذي يقوم بتشغيل حاويات Docker الخاصة بك. اختياريًا، اضبطها على *، وهي علامة بديلة تطابق جميع المضيفين إذا كنت في وضع التطوير.
-
DB_DATABASE: إذا استخدمت اسمًا مختلفًا لقاعدة البيانات، فاضبطه هنا بشكل مناسب.
-
DB_USERNAME: اضبط هذا على اسم المستخدم الذي اخترته لقاعدة بياناتك.
-
DB_PASSWORD: اضبط هذا على كلمة المرور التي اخترتها لقاعدة بياناتك.
-
DB_HOST: اضبط هذا على المضيف الذي يقوم بتشغيل مثيل قاعدة البيانات الخاصة بك كما قمت بإعداده في الخطوة الأولى.
-
DB_PORT: اضبط هذا على منفذ قاعدة بياناتك.
-
STATIC_MINIO_BUCKET_NAME: اضبط هذا على اسم السلة (bucket) الذي أنشأته في حساب تخزين MinIO السحابي الخاص بك.
احفظ الملف وأغلقه عند الانتهاء من التعديل.
إعدادات البيئة جاهزة الآن. نحتاج إلى تشغيل الحاوية وتمرير الوسائط لتجاوز أمر CMD الافتراضي وإنشاء مخطط قاعدة البيانات باستخدام أمري manage.py makemigrations و manage.py migrate.
إليك الأمر:
|
1 |
docker run --env-file env django-polls:v1 sh -c "python manage.py makemigrations && python manage.py migrate" |
في هذا الأمر، نقوم بتشغيل django-polls:v1 صورة الحاوية، باستخدام –env-file علامة لتمرير ملف متغيرات البيئة. نقوم أيضًا بتجاوز أمر CMD الافتراضي بـ sh -c "python manage.py makemigrations && python manage.py migrate" عند تشغيل هذا الأمر لبدء الحاوية، سيقوم بإنشاء مخطط قاعدة البيانات كما هو محدد في كود التطبيق.
إذا نجح الأمر، يجب أن ترى مخرجات مشابهة لما يلي:

تشير المخرجات إلى أنه تم إنشاء مخطط قاعدة البيانات بنجاح.
الخطوة التالية هي إنشاء مستخدم مسؤول لتطبيق Django. سنقوم بتشغيل الحاوية وبدء واجهة تفاعلية (shell) داخلها باستخدام الأمر التالي:
|
1 |
docker run -i -t --env-file env django-polls:v1 sh |
يبدأ الأمر تشغيل الحاوية مع موجه أوامر (shell prompt) يمكنك استخدامه للتفاعل مع واجهة Python. لنقم بإنشاء مستخدم:
|
1 |
python manage.py createsuperuser |
اتبع المطالبات لتقديم اسم المستخدم، وعنوان البريد الإلكتروني، وكلمة المرور، وإعادة كتابة كلمة المرور، واضغط على enter لإنشاء المستخدم. اخرج من الواجهة وأوقف الحاوية بالضغط على CTRL+D.
بعد ذلك، نحتاج إلى تشغيل الحاوية مرة أخرى، مع تجاوز الأمر الافتراضي بأمر collectstatic الخاص بـ Django لإنشاء الملفات الثابتة للتطبيق ورفعها إلى خدمة تخزين MinIO السحابية الخاصة بك:
|
1 |
docker run --env-file env django-polls:v1 sh -c "python manage.py collectstatic --noinput" |
عند اكتماله، يجب أن ترى مخرجات مشابهة لما يلي، مما يشير إلى أن حاويتك اتصلت بنجاح بخدمة تخزين MinIO وقامت برفع الملفات الثابتة:
![]()
تبدو حاوية التخزين لدينا الآن على هذا النحو، مع المجلدات التي أنشأها Django:

أخيرًا، يمكننا الآن تشغيل التطبيق باستخدام الأمر:
|
1 |
docker run --env-file env -p 80:8000 django-polls:v1 |
إليك المخرجات:

عند تنفيذ الأمر أعلاه، فإنه يقوم بتشغيل أمر CMD الافتراضي في صورتك ويكشف المنفذ 8000 كما هو محدد. الآن، يتم تعيين Ubuntu على المنفذ 80 إلى المنفذ 8000 الخاص بحاوية django-polls:v1 .
يمكننا الآن اختبار التطبيق في المتصفح. انتقل إلى عنوان IP العام لخادمك في المتصفح: http://your_server_public_ip.
توقع العثور على خطأ 404 الصفحة غير موجودة، لأنه وفقًا لـ برنامج Django التعليمي، لم نقم بتعريف مسار لـ / المسار:

لدينا المتغير DEBUG معينًا على True، ولهذا السبب نرى صفحة الخطأ هذه التي تحتوي على الكثير من المعلومات الهامة. دعنا نلغي تعيين المتغير DEBUG . أولاً، ستحتاج إلى إيقاف الحاوية قيد التشغيل باستخدام CTRL+C. ثم افتح ملف env :
|
1 |
nano env |
بعد ذلك، ابحث عن المتغير DEBUG وقم بإلغاء تعيينه، أو اتركه فارغًا. نتركه فارغًا لأن الدالة getenv تفسر False كسلسلة نصية، وبالتالي تعيد القيمة true:
|
1 |
DEBUG= |
احفظ الملف وشغّل الحاوية مرة أخرى باستخدام الأمر:
|
1 |
docker run --env-file env -p 80:8000 django-polls:v1 |
إذا قمت بزيارة http://your_server_public_ip في متصفحك، فمن المفترض أن ترى صفحة 404 الافتراضية:

لقد رأيت كيف يمكنك التلاعب بسلوك تشغيل تطبيق Django الخاص بك باستخدام متغيرات البيئة، دون تعديل الكود المصدري.
انتقل إلى http://your_server_public_ip/polls لرؤية الصفحة الرئيسية للاستطلاعات:

ليس لدينا أي استطلاعات لأننا قمنا للتو بنشر التطبيق.
انتقل إلى واجهة المسؤول: http://your_server_public_ip/admin لعرض نافذة مصادقة المسؤول:

أدخل بيانات الاعتماد التي قمت بتعيينها باستخدام الأمر createsuperuser لتسجيل الدخول. يجب أن تكون الآن في واجهة صفحة الإدارة:

لاحظ أنه يتم تقديم جميع الملفات الثابتة من خدمة التخزين الخارجية التي قمنا بإعدادها. يمكنك النقر بزر الماوس الأيمن في نافذة متصفحك واختيار عرض مصدر الصفحة:

يمكنك إضافة بعض الأسئلة والخيارات واختبار الأداء العام للتطبيق:

ارجع إلى فهرس الاستطلاعات http://your_server_public_ip/polls وحاول التصويت على السؤال:

بعد اختبار كل شيء والتأكد من أنه يعمل كما هو متوقع، يمكنك إنهاء الحاوية.
الخاتمة
لقد قمت بنجاح بتهيئة تطبيق ويب Django ليعمل بشكل جيد في بيئة قائمة على الحاويات. وتضمن ذلك تكييف التطبيق للعمل مع متغيرات البيئة الخارجية، وإعداد التطبيق لاستخدام خدمة تخزين سحابية للملفات الثابتة، وإنشاء Dockerfile لصورة الحاوية. يمكنك عرض التغييرات التي أجريناها لتحويل التطبيق إلى حاوية (Dockerize) على فرع django-polls-docker الخاص بمستودع django-polls على GitHub.
من هنا، الاحتمالات محدودة فقط بخيالك. يمكنك إعداد وكيل عكسي Nginx ليكون بين العملاء وخادم Gunicorn. يمكنك أيضًا إضافة Certbot للحصول على شهادات TLS لتأمين خادم Nginx الخاص بك. نوصي بإضافة وكيل HTTP لدرء بطء العملاء وحماية خادم Gunicorn الخاص بك من هجمات حجب الخدمة.
بينما قمنا بتعريف 3 عمال (workers) في أمر بدء التشغيل الخاص بـ Dockerfile، يمكنك تعيين الرقم المفضل لديك اعتمادًا على الموارد المتاحة على خادمك. يمكنك العثور على مزيد من المعلومات في وثائق تصميم Gunicorn الرسمية. إذا كنت ترغب في ذلك، يمكنك دفع صورة Docker التي قمت ببنائها إلى Dockerhub ومحاولة نشرها على بيئات متعددة تم تثبيت Docker عليها. إذا كنت ترغب في معرفة المزيد، فاستمر في مراجعة مدونة البرامج التعليمية الخاصة بنا حيث سنقوم بتقديم برنامج تعليمي للمتابعة لجعل تطبيق Django آمنًا باستخدام Nginx و Let’s Encrypt.
أخيرًا، إليك المزيد من الموارد التي ستساعدك على الاستفادة من Docker:
- كيفية استضافة مستودع صور Docker وبناء صور Docker باستخدام نسخة GitLab المدارة ذاتيًا على Ubuntu 20.04
- العمل مع مجلدات بيانات Docker على Ubuntu 20.04
- بناء ونشر تطبيق Flask باستخدام Docker على Ubuntu 20.04
- كيفية نشر WordPress باستخدام حاويات Docker على Ubuntu 20.04
حوسبة سعيدة!
التعليقات
لا توجد تعليقات بعد. كن أول من يعلق.