يُعرّف الاحتواء ضمن حاوية على أنها عملية تكييف التطبيق ومكوناته لتصبح قادرةً على العمل ضمن بيئة بسيطة أساسية المقومات ندعوها الحاوية لتشكّل بيئةً معزولةً يمكن للمستخدم إزالتها بسهولة وسرعة عندما تنتهي حاجته منها أو عندما يرغب بتعديل بعضًا من أجزائها، كما يمكن الاستفادة منها لتطوير واختبار ونشر التطبيقات ضمن بيئات الإنتاج.
نعمل في هذا المقال على استخدام الأداة دوكر كومبوز Docker Compose لاحتواء تطبيق لارافيل لتطويره ضمن بيئة مستقلة خاصة به. نحصل على تطبيق لارافيل توضيحي موزّع على ثلاث حاويات خدمة معزولة عن بعضها يعضًا على النحو التالي:
- خدمة تطبيق "app" تعمل على PHP7.4-FPM.
- خدمة قاعدة بيانات "db" تحتوي خادم MySQL 5.7.
- خدمة "nginx" تستخدم خدمة "app" من أجل تحليل شيفرة برمجية بلغة PHP قبل تقديم تطبيق لارافيل للمستخدم النهائي.
تُستخدم وحدات التخزين المشتركة Shared Volumes من أجل مزامنة ملفات التطبيق وذلك لتطوير تطبيق بسيط وتصحيح الأخطاء بسهولة؛ كما تُستخدم أوامر docker-compose exec
لتشغيل تعليمات Composer و artisan في حاوية التطبيق.
المتطلبات الأساسية
- الوصول إلى حاسب يعمل بنظام التشغيل لينكس أوبنتو Ubuntu ذي رقم إصدار 20.04 أو إلى خادم تطوير يعمل بنفس نظام التشغيل المذكور بواسطة مستخدم ذي صلاحيات إدارة sudo ولا يفضل استخدام حساب الجذر Root لأسباب تتعلق بأمان الخادم، كما يُفضل وجود جدار حماية firewall مثبت ونشط في حال استخدام خادم بعيد.
- تثبيت الأداة دوكر على الخادم أو الجهاز المحلي.
- تثبيت الأداة دوكر كومبوز Docker Compose على الخادم أو الجهاز المحلي.
الخطوة 1- الحصول على التطبيق التوضيحي
نبدأ بتنزيل تطبيق لارافيل التوضيحي من مخزن غيت هب Github وننتقل إلى الفرع tutorial-01، الذي يتضمن تطبيقًا بسيطًا مبنيًا باستخدام لارافيل. نعتمد في هذا العمل على الإصدار tutorial-1.0.1 والذي نحملّه ضمن المجلد الأساسي للمستخدم بتنفيذ الأمر:
cd ~ curl -L https://github.com/do-community/travellist-laravel-demo/archive/tutorial-1.0.1.zip -o travellist.zip
يبدأ تنزيل الملف المضغوط بصيغة "zip" لذلك يجب عند انتهاء التحميل فك الضغط باستخدام الأمر unzip
بعد التأكد من تحديث الحزم الخاصة بنظام التشغيل ما لم تكن محدّثة مؤخرًا. ننفذ الأمر التالي:
sudo apt update
sudo apt install unzip
ننفذ الأوامر التالي لفك ضغط الملف الذي حملناه ونعيد تسمية المجلد لاسم مناسب لسهولة الوصول إليه:
unzip travellist.zip mv travellist-laravel-demo-tutorial-1.0.1 travellist-demo
ننتقل إلى المجلّد "travellist-demo" بتنفيذ الأمر:
cd travellist-demo
الخطوة 2- إعداد ملف الضبط الخاص بالتطبيق
نجد عادةً ملفات الضبط الخاصة بلارافيل ضمن المجلد "config" داخل المجلد الجذر للتطبيق. يحتوي الملف "env." معلومات الضبط المتعلقة بالبيئة، مثل بيانات الاعتماد وكلمات المرور وأية معلومات تختلف بين عمليات نشر التطبيقات، لذلك لا يُضمّن هذا الملف ضمن ملفات التحكم بالإصدارات لكي لا تنتشر هذه المعلومات لجميع المستخدمين الذين يستخدمون صورة التطبيق لاحقًا.
تحذير: يحتوي ملف تهيئة البيئة على معلومات حساسة حول الخادم، بما في ذلك بيانات اعتماد قاعدة البيانات ومفاتيح الأمان، لهذا السبب لا يجب أبدًا مشاركة هذا الملف علنًا.
توجد أولويةٌ للقيم الموجودة في الملف "env." على القيم الموجودة في ملفات التهيئة الأخرى الموجودة في المجلد "config". تتطلب كل عملية تثبيت في بيئة جديدة ملف بيئة مخصص لتعريف معلومات جديدة، مثل إعدادات الاتصال في قاعدة البيانات وخيارات التصحيح ورابط للتطبيق، إضافةً إلى بقية العناصر أو المعلومات التي تختلف تبعًا للبيئة التي يعمل بها التطبيق.
ننشئ ملف "env." جديد لضبط خيارات التهيئة لبيئة التطوير التي نُعدها، ويمكننا نسخ الملف "example.env" المتاح افتراضيًا مع أي تطبيق لارافيل بتنفيذ الأمر:
cp .env.example .env
نحرر الملف باستخدام محرر النصوص نانو nano أو باختيار محرر النصوص المفضّل:
nano .env
يحتوي ملف "env." الحالي من تطبيق "travellist" التوضيحي على إعدادات لاستخدام التطبيق المُحتَوى المتصل بقاعدة بيانات MySQL محلية أي أنها متاحة على المضيف المحلي "127.0.0.1". نحتاج لتعديل قيمة المتغير DB_HOST
لكي يشير إلى قاعدة البيانات التي ننشئها ضمن بيئة دوكر. نعتمد في عملنا على أنّ اسم خدمة قواعد البيانات هو db
. نعدّل محتوى الملف لضبط قيم المتغيرات على النحو التالي:
APP_NAME=Travellist APP_ENV=dev APP_KEY= APP_DEBUG=true APP_URL=http://localhost:8000 LOG_CHANNEL=stack DB_CONNECTION=mysql DB_HOST=db DB_PORT=3306 DB_DATABASE=travellist DB_USERNAME=travellist_user DB_PASSWORD=password ...
نستطيع تغيير القيم الخاصة ببقية المتغيرات، مثل اسم قاعدة البيانات وكلمة المرور واسم المستخدم الذين سيُستخدمان عند إعداد الملف "docker-compose.yml" من أجل تهيئة الخدمات. نضغط على الاختصار "CTRL+X" ثم الحرف "Y" وأخيرًا زر الإدخال "Enter" بعد الانتهاء من تعديل الملف.
الخطوة 3 - إعداد ملف دوكر الخاص بالتطبيق
تستند خدمتا MySQL و Nginx على الصور الافتراضية التي يمكن الحصول عليها من Docker Hub، لكن سنحتاج في مثالنا إلى إنشاء صورة مخصصة لحاوية التطبيق وسننشئ ملف Dockerfile جديد لذلك.
تعتمد صورة التطبيق travillist على صورة PHP الرسمية ذات الاسم php:7.4-fpm والمتاحة ضمن مخزن دوكر هب Docker Hub. نحتاج تثبيت بعض حزم PHP الإضافية باستخدام أداة إدارة الاعتمادية Composer.
ننشئ مستخدم نظام جديد لتنفيذ الأوامر المختلفة مثل أوامر"Composer" و "artisan" أثناء تطوير التطبيق. يضمن إعداد "uid" امتلاك المستخدم الموجود داخل الحاوية نفس معرف المستخدم الخاص بمستخدم النظام على الجهاز المضيف أثناء تشغيل دوكر. تتزامن الملفات التي تُنشأ من الأوامر في جهاز المضيف باستخدام الأذونات الصحيحة، ونستطيع استخدام أي محرر نصوص لتطوير الشيفرة البرمجية للتطبيق داخل الحاويات. ننشئ ملف Dockerfile جديد بتنفيذ الأمر:
nano Dockerfile
ننسخ المحتوى التالي إلى ملف Dockerfile:
FROM php:7.4-fpm # Arguments defined in docker-compose.yml ARG user ARG uid # Install system dependencies RUN apt-get update && apt-get install -y \ git \ curl \ libpng-dev \ libonig-dev \ libxml2-dev \ zip \ unzip # Clear cache RUN apt-get clean && rm -rf /var/lib/apt/lists/* # Install PHP extensions RUN docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath gd # Get latest Composer COPY --from=composer:latest /usr/bin/composer /usr/bin/composer # Create system user to run Composer and Artisan Commands RUN useradd -G www-data,root -u $uid -d /home/$user $user RUN mkdir -p /home/$user/.composer && \ chown -R $user:$user /home/$user # Set working directory WORKDIR /var/www USER $user
نحفظ الملف بعد الانتهاء من التعديل عليه. يبدأ الملف بتحديد الصورة الأساس التي نستخدمها وهي في حالة الملف السابق php:7.4-fpm
. نثبت أداة Composer بنسخ الشكل التنفيذي الخاص بالأمر "composer" والمتاح ضمن أحدث صورة رسمية إلى صورة التطبيق الخاص بنا.
ننشئ مستخدم نظام جديد ونبدأ بإعداد المتغيرينuser
و uid
الذين عرّفناهما في بداية الملف Dockerfile، إذ تُمرَّر هذه المتغيرات إلى الحاوية باستخدام الأداة دوكر كومبوز في وقت البناء.
نحدد مسار العمل الافتراضي "var/www/" ونسجّل الدخول بواسطة المستخدم الذي أنشأناه مؤخرًا للتأكد من الاتصال بقاعدة البيانات بصفة مستخدم عادي وأننا في المسار الصحيح عند استخدام الأوامر المختلفة، مثل أوامر"composer" و "artisan" في حاوية التطبيق.
الخطوة 4 - إعداد ضبط Nginx وملفات إفراغ قاعدة البيانات
يجب مشاركة ملفات الضبط والتهيئة مع حاويات الخدمة عند إنشاء بيئة تطوير باستخدام أداة دوكر كومبوزلإعداد أو التمهيد لهذه الخدمات، إذ يسهّل ذلك إجراء التعديلات على ملفات الضبط وضبط البيئة أثناء تطوير التطبيق. ننشئ مجلد ونضع به الملفات التي تستخدم في تهيئة وبناء حاويات الخدمة. ننشئ مجلد "docker-compose/nginx" ونضع به ملف "travellist.conf" الذي يهيئ آلية تقديم التطبيق وذلك بتنفيذ الأمر التالي:
mkdir -p docker-compose/nginx
نعدّل محتوى الملف "travellist.conf" باستخدام محرر النصوص المفضل عبر تنفيذ الأمر التالي:
nano docker-compose/nginx/travellist.conf
نضيف الشيفرة البرمجية التالية داخله:
server { listen 80; index index.php index.html; error_log /var/log/nginx/error.log; access_log /var/log/nginx/access.log; root /var/www/public; location ~ \.php$ { try_files $uri =404; fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_pass app:9000; fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param PATH_INFO $fastcgi_path_info; } location / { try_files $uri $uri/ /index.php?$query_string; gzip_static on; } }
يضبط الملف السابق خادم Nginx ويجبره على الاستماع للمنفذ 80
ويستخدم الصفحة index.php
لتكون صفحة الدليل الأساسية للتطبيق. نضبط المسار الجذر Root للمستند ليصبح "/var/www/public" ونضبط خادم Nginx ونجبره على استخدام المنفذ "9000" لمعالجة الملفات ذات اللاحقة "php.*". احفظ الملف وأغلقه عند الانتهاء من التعديل.
سنشارك من أجل إكمال إعداد قاعدة البيانات MYSQL ملفًا يتضمن محتوى قاعدة البيانات database dump، الذي سيُستورد محتواه إلى قاعدة البيانات عندما نهيئ الحاوية لأول مرة، وتتوفر هذه الميزة في MySQL 5.7 التي نستخدمها في حاوية التطبيق. ننشئ مجلدًا جديدًا لتهيئة ملفات قاعدة البيانات MySQL داخل المجلد "docker-compose" بتنفيذ الأمر التالي:
mkdir docker-compose/mysql
ننشئ ملف "sql." جديد بتنفيذ الأمر:
nano docker-compose/mysql/init_db.sql
يعتمد ملف قاعدة البيانات MySQL dump التالي على قاعدة البيانات المُنشأة في دليل لارافيل بالاعتماد على LEMP، إذ يُنشئ جدولًا اسمه places
في قاعدة البيانات ثم سيملأ محتوياته بمجموعة من العينات.
اكتب الشيفرة البرمجية التالية في الملف "db_init.sql" ليصبح بالشكل التالي:
DROP TABLE IF EXISTS `places`; CREATE TABLE `places` ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, `name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, `visited` tinyint(1) NOT NULL DEFAULT '0', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; INSERT INTO `places` (name, visited) VALUES ('Berlin',0),('Budapest',0),('Cincinnati',1),('Denver',0),('Helsinki',0),('Lisbon',0),('Moscow',1),('Nairobi',0),('Oslo',1),('Rio',0),('Tokyo',0);
يتضمن الجدول places
ثلاثة حقول id
و name
و visited
وهي على الترتيب معرّف خاص بكل مكان واسم المكان ومتغير يشير إلى زيارة المكان مسبقًا أم لا، ويمكن تعديل أسماء الحقول وإضافة حقول جديدة عند الحاجة.
الخطوة 5 - إنشاء بيئة متعددة الحاويات بواسطة دوكر كومبوز
تُنشئ الأداة دوكر كومبوز بيئات متعددة الحاويات للتطبيقات التي تعمل على دوكر، كما تستخدم تعريفات الخدمة لبناء بيئات قابلة للتخصيص بالكامل مع حاويات متعددة يمكنها مشاركة الشبكات وأحجام البيانات، مما يتيح التكامل السلس بين مكونات التطبيق المختلفة.
ننشئ ملفًا جديدًا يسمى "docker-compose.yml"، والذي يمكن أن يكون موجودًا مسبقًا في مجلد الجذر للتطبيق، إذ يحدد هذا الملف بيئة الحاويات بما في ذلك الصور الأساسية لبناء التطبيق وكيفية تفاعل الخدمات ضمنه.
نحدد ثلاث خدمات مختلفة ضمن ملف "docker-compose.yml"، هي: "app" و "db" و "nginx"؛ إذ تُنشئ خدمة "app" صورةً تسمى "travellist" بناءً على ملف Dockerfile الذي أنشأناه سابقًا، وتُشغّل الحاوية التي تحددها هذه الخدمة خادم "php-fpm" لتحليل شيفرات PHP وتُرسل النتائج مرةً أخرى إلى خدمة "nginx، التي تعمل على حاوية منفصلة. تحدد خدمة "mysql" حاويةً تُشغل خادم MySQL 5.7. تتصل هذه الخدمات فيما بينها باستخدام شبكة جسر أسميناها "travellist".
تُزامن ملفات التطبيق على كل من الخدمتين "app" و "nginx" عبر حوامل الربط، التي تُعد مفيدةً في بيئات التطوير لأنها تتيح مزامنةً ثنائية الاتجاه بين الجهاز المضيف والحاويات. نُنشئ ملفًا جديدًا باسم "docker-compose.yml" في مجلد الجذر للتطبيق بتنفيذ الأمر:
nano docker-compose.yml
يبدأ ملف "docker-compose.yml" التقليدي برقم الإصدار يليها تعريف الخدمات "services" الخاصة بالتطبيق، كما تُعرَّف الشبكات التي يشاركها التطبيق في نهاية الملف. إذًا، يكون محتوى هذا الملف كما يلي:
version: "3.7" services: networks: travellist: driver: bridge
سنعدّل الآن عقدة "services" لتتضمن خدمات "app" و "db" و "nginx".
خدمة التطبيق app
تُعِد خدمة "app" حاويةً باسم "travellist-app" وتبني صورة دوكر جديدة بناءً على Dockerfile الموجود في نفس مسار الملف "docker-compose.yml" وتُحفظ الصورة محليًا باسم "travellist". نحتاج تواجد ملفات التطبيق ضمن حاوية التطبيق "app" حتى ولو كانت هذه الملفات موجودةً في جذر المستند الذي جرى تقديمه على أنه تطبيق موجود في حاوية "nginx"، ونحتاج ذلك من أجل تنفيذ أوامر "artisan" الخاصة بإطار عمل لارافيل على هذه الملفات. نضيف البيانات التالية إلى الملف "docker-compose.yml":
app: build: args: user: sammy uid: 1000 context: ./ dockerfile: Dockerfile image: travellist container_name: travellist-app restart: unless-stopped working_dir: /var/www/ volumes: - ./:/var/www networks: - travellist
تحقق هذه الإعدادات ما يلي:
-
build
: يعلِم هذا الضبط أداة دوكر كومبوز ببناء صورة محلية لخدمة التطبيق، باستخدام المسار المحدد context وملف Dockerfile للحصول على التعليمات. تُحقن المتغيراتuser
وuid
في ملف Dockerfile لتخصيص أوامر إنشاء المستخدم في وقت الإنشاء. -
image
: تُعدّ الاسم الذي يستخدم الصورة قيد الإنشاء. -
container_name
: تُعِدّ اسم الحاوية لهذه الخدمة. -
restart
: يعيد التشغيل دائمًا، ما لم يحدث إيقافٌ الخدمة. -
working_dir
: يعيّن المجلّد الافتراضي لهذه الخدمة، مثل "/var/www". -
volumes
: يُنشئ وحدة تخزين مشتركة تُزامِن المحتويات من المسار الحالي إلى "/var/www" داخل الحاوية، ويبقى موجودًا في حاوية "nginx". -
networks
: تُعِدّ هذه الخدمة لاستخدام شبكة باسم "travellist".
خدمة قاعدة البيانات db
تستخدم خدمة "db" صورة MySQL 5.7 من مخزن دوكر هب. تحمّل الأداة دوكر كومبوز الملفات المتغيرة "env." الموجودة في نفس المسار الذي يحتوي الملف "docker-compose.yml"، ونحصل على إعدادات قاعدة البيانات ملف "env." الذي قد ولّدناه عند إنشاء تطبيق لارافيل. نضع البيانات التالية بعد البيانات التي وضعناها للخدمة "app":
db: image: mysql:5.7 container_name: travellist-db restart: unless-stopped environment: MYSQL_DATABASE: ${DB_DATABASE} MYSQL_ROOT_PASSWORD: ${DB_PASSWORD} MYSQL_PASSWORD: ${DB_PASSWORD} MYSQL_USER: ${DB_USERNAME} SERVICE_TAGS: dev SERVICE_NAME: mysql volumes: - ./docker-compose/mysql:/docker-entrypoint-initdb.d networks: - travellist
تحقق هذه الإعدادات ما يلي:
-
image
: تحدد صورة دوكر التي ستستخدم في هذه الحاوية. نستخدم صورة MySQL 5.7 من دوكر هب Docker Hub. -
container_name
: اسم الحاويةtravellist-db
. -
restart
: يعيد التشغيل دائمًا، ما لم يحدث إيقاف للخدمة. -
environment
: تُحدد متغيرات البيئة في الحاوية الجديدة. نستخدم القيم التي حصلنا عليها من ملف "env." لإعداد خدمة قاعدة البيانات MySQL والتي تنشئ تلقائيًا قاعدة بيانات ومستخدمًا جديدًا بناءً على متغيرات البيئة المتوفرة. -
volumes
: ينشئ وحدة تخزين لتهيئة قاعدة بيانات التطبيق. تستورد صورة MySQL ملفات"sql." تلقائيًا والتي توجد في المسار/docker-entrypoint-initdb.d
داخل الحاوية. -
network
: تُعِد هذه الخدمة لاستخدام شبكة باسمtravellist
.
الخدمة nginx
تستخدم خدمة "nginx" صورة Nginx مبنية مسبقًا على توزيعة لينكس اسمها Alpine. تنشئ حاوية باسم "travellist-nginx" وتُعيد التوجيه من المنفذ "8000" الى المنفذ "80" داخل الحاوية. نضع البيانات التالية بعد بيانات خدمة "db":
nginx: image: nginx:1.17-alpine container_name: travellist-nginx restart: unless-stopped ports: - 8000:80 volumes: - ./:/var/www - ./docker-compose/nginx:/etc/nginx/conf.d networks: - travellist
تحقق هذه الإعدادات ما يلي:
-
image
: اسم صورة دوكر التي تستخدم في هذه الحاوية وهي في هذه الحالة الصورة Alpine Nginx 1.17 . -
container_name
: اسم الحاويةtravellist-nginx
. -
restart
: يعيد التشغيل دائمًا، ما لم يحدث إيقافٌ للخدمة. -
ports
: تعيد توجيه المنفذ الذي يسمح بالوصول الخارجي عبر المنفذ8000
إلى خادم الويب الذي يعمل على المنفذ80
داخل الحاوية. -
volumes
: تنشئ وحدتي تخزين مشتركتين، بحيث تزامن الوحدة الأولى المحتويات من نقطة العمل إلى المسار/var/www
داخل الحاوية ويفيد ذلك بنقل التعديلات المحلية إلى التطبيق الذي يقدّمه Nginx تلقائيًا. تنسخ الوحدة الثانية ملفات الإعداد الخاصة بخدمة nginx الموجودة في الملف "docker-compose/nginx/travellist.conf" الى ملفات الإعداد الخاصة بخدمة nginx ضمن الحاوية. -
network
: تُعِد هذه الخدمة لاستخدام شبكة باسمtravellist
.
وعليه يصبح ملف "docker-compose.yml" على الشكل التالي:
version: "3.7" services: app: build: args: user: sammy uid: 1000 context: ./ dockerfile: Dockerfile image: travellist container_name: travellist-app restart: unless-stopped working_dir: /var/www/ volumes: - ./:/var/www networks: - travellist db: image: mysql:5.7 container_name: travellist-db restart: unless-stopped environment: MYSQL_DATABASE: ${DB_DATABASE} MYSQL_ROOT_PASSWORD: ${DB_PASSWORD} MYSQL_PASSWORD: ${DB_PASSWORD} MYSQL_USER: ${DB_USERNAME} SERVICE_TAGS: dev SERVICE_NAME: mysql volumes: - ./docker-compose/mysql:/docker-entrypoint-initdb.d networks: - travellist nginx: image: nginx:alpine container_name: travellist-nginx restart: unless-stopped ports: - 8000:80 volumes: - ./:/var/www - ./docker-compose/nginx:/etc/nginx/conf.d/ networks: - travellist networks: travellist: driver: bridge
نتأكد من حفظ الملف بعد الانتهاء من إجراء التعديلات السابقة.
الخطوة 6 - تشغيل التطبيق عبر أداة دوكر كومبوز
ننشئ صورة تطبيق جديد ونشغّل الخدمات التي حددناها ضمن الإعدادات باستخدام الأمر التالي:
docker-compose build app
يستغرق الأمر بضعة دقائق، ثم يظهر الخرج التالي:
Building app Step 1/11 : FROM php:7.4-fpm ---> fa37bd6db22a Step 2/11 : ARG user ---> Running in f71eb33b7459 Removing intermediate container f71eb33b7459 ---> 533c30216f34 Step 3/11 : ARG uid ---> Running in 60d2d2a84cda Removing intermediate container 60d2d2a84cda ---> 497fbf904605 Step 4/11 : RUN apt-get update && apt-get install -y git curl libpng-dev libonig-dev ... Step 7/11 : COPY --from=composer:latest /usr/bin/composer /usr/bin/composer ---> e499f74896e3 Step 8/11 : RUN useradd -G www-data,root -u $uid -d /home/$user $user ---> Running in 232ef9c7dbd1 Removing intermediate container 232ef9c7dbd1 ---> 870fa3220ffa Step 9/11 : RUN mkdir -p /home/$user/.composer && chown -R $user:$user /home/$user ---> Running in 7ca8c0cb7f09 Removing intermediate container 7ca8c0cb7f09 ---> 3d2ef9519a8e Step 10/11 : WORKDIR /var/www ---> Running in 4a964f91edfa Removing intermediate container 4a964f91edfa ---> 00ada639da21 Step 11/11 : USER $user ---> Running in 9f8e874fede9 Removing intermediate container 9f8e874fede9 ---> fe176ff4702b Successfully built fe176ff4702b Successfully tagged travellist:latest
نُشغّل البيئة بالخلفية بعد الانتهاء من مرحلة الإنشاء بتنفيذ الأمر:
docker-compose up -d
ويكون الخرج على النحو التالي:
Creating travellist-db ... done Creating travellist-app ... done Creating travellist-nginx ... done
نستعرض معلومات حالة الخدمة النشطة حاليًا بتنفيذ الأمر:
docker-compose ps
ويكون الخرج على النحو التالي:
Name Command State Ports -------------------------------------------------------------------------------- travellist-app docker-php-entrypoint php-fpm Up 9000/tcp travellist-db docker-entrypoint.sh mysqld Up 3306/tcp, 33060/tcp travellist-nginx /docker-entrypoint.sh ngin ... Up 0.0.0.0:8000->80/tcp
أصبحت البيئة الآن جاهزة للعمل، ولكن يجب تنفيذ بعض الأوامر قبل انتهاء إعداد التطبيق كاملًا. نستخدم الأمر docker-compose exec
لتنفيذ جميع الأوامر ضمن الحاويات، فلو رغبنا بتنفيذ الأمر ls –l
الذي يظهر معلومات مفصلة حول الملفات في مسار التطبيق، ننفذ الأمر التالي:
docker-compose exec app ls -l
وسيكون خرج شبيهًا بالخرج التالي:
total 260 -rw-rw-r-- 1 sammy sammy 737 Jun 9 11:19 Dockerfile -rw-rw-r-- 1 sammy sammy 101 Jan 7 08:05 README.md drwxrwxr-x 6 sammy sammy 4096 Jan 7 08:05 app -rwxr-xr-x 1 sammy sammy 1686 Jan 7 08:05 artisan drwxrwxr-x 3 sammy sammy 4096 Jan 7 08:05 bootstrap -rw-rw-r-- 1 sammy sammy 1501 Jan 7 08:05 composer.json -rw-rw-r-- 1 sammy sammy 179071 Jan 7 08:05 composer.lock drwxrwxr-x 2 sammy sammy 4096 Jan 7 08:05 config drwxrwxr-x 5 sammy sammy 4096 Jan 7 08:05 database drwxrwxr-x 4 sammy sammy 4096 Jun 9 11:19 docker-compose -rw-rw-r-- 1 sammy sammy 965 Jun 9 11:27 docker-compose.yml -rw-rw-r-- 1 sammy sammy 1013 Jan 7 08:05 package.json -rw-rw-r-- 1 sammy sammy 1405 Jan 7 08:05 phpunit.xml drwxrwxr-x 2 sammy sammy 4096 Jan 7 08:05 public -rw-rw-r-- 1 sammy sammy 273 Jan 7 08:05 readme.md drwxrwxr-x 6 sammy sammy 4096 Jan 7 08:05 resources drwxrwxr-x 2 sammy sammy 4096 Jan 7 08:05 routes -rw-rw-r-- 1 sammy sammy 563 Jan 7 08:05 server.php drwxrwxr-x 5 sammy sammy 4096 Jan 7 08:05 storage drwxrwxr-x 4 sammy sammy 4096 Jan 7 08:05 tests drwxrwxr-x 41 sammy sammy 4096 Jun 9 11:32 vendor -rw-rw-r-- 1 sammy sammy 538 Jan 7 08:05 webpack.mix.js
نشغّل الأداة composer install
لتثبيت اعتماديات التطبيق كما يلي:
docker-compose exec app composer install
يظهر الخرج التالي بعد إتمام العملية:
Loading composer repositories with package information Installing dependencies (including require-dev) from lock file Package operations: 85 installs, 0 updates, 0 removals - Installing doctrine/inflector (1.3.1): Downloading (100%) - Installing doctrine/lexer (1.2.0): Downloading (100%) - Installing dragonmantank/cron-expression (v2.3.0): Downloading (100%) - Installing erusev/parsedown (1.7.4): Downloading (100%) - Installing symfony/polyfill-ctype (v1.13.1): Downloading (100%) - Installing phpoption/phpoption (1.7.2): Downloading (100%) - Installing vlucas/phpdotenv (v3.6.0): Downloading (100%) - Installing symfony/css-selector (v5.0.2): Downloading (100%) … Generating optimized autoload files > Illuminate\Foundation\ComposerScripts::postAutoloadDump > @php artisan package:discover --ansi Discovered Package: facade/ignition Discovered Package: fideloper/proxy Discovered Package: laravel/tinker Discovered Package: nesbot/carbon Discovered Package: nunomaduro/collision Package manifest generated successfully.
يجب أن نولد مفتاح التطبيق الفريد باستخدام الأداة artisan
الخاصة بلارافيل قبل أن نختبر التطبيق الذي طورناه، إذ يشفّر هذا المفتاح جلسات المستخدم والبيانات الحساسة الأخرى.
ننفذ الأمر التالي:
docker-compose exec app php artisan key:generate
ويكون الخرج على النحو التالي:
Application key set successfully.
نطلب الرابط التالي من المتصفح:
http://server_domain_or_IP:8000
ملاحظة: نطلب العنوان المحلي "http://localhost:8000" في حالة العمل على حاسب محلي ضمن المتصفح لتشغيل التطبيق التوضيحي الذي نطوّره.
يظهر عندها الخرج التالي:
نستطيع استخدام الأمر logs
لفحص السجلات التي تولّدها الخدمة بتنفيذ الأمر التالي:
docker-compose logs nginx
Attaching to travellist-nginx … travellist-nginx | /docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh travellist-nginx | /docker-entrypoint.sh: Configuration complete; ready for start up travellist-nginx | 192.168.0.1 - - [09/Jun/2020:11:46:34 +0000] "GET / HTTP/1.1" 200 627 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36" travellist-nginx | 192.168.0.1 - - [09/Jun/2020:11:46:35 +0000] "GET / HTTP/1.1" 200 627 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36" …
نستطيع إيقاف العمل مؤقتًا لبيئة دوكر كومبوز مع الحفاظ على حالة الخدمات بتشغيل الأمر:
docker-compose pause
ليكون الخرج على النحو التالي:
Pausing travellist-db ... done Pausing travellist-nginx ... done Pausing travellist-app ... done
نستطيع استئناف العمل بتنفيذ الأمر:
docker-compose unpause
ويكون الخرج على النحو التالي:
Unpausing travellist-app ... done Unpausing travellist-nginx ... done Unpausing travellist-db ... done
نستطيع إيقاف عمل بيئة دوكر كومبوز ونزيل جميع حاوياتها وشبكاتها ووحدات تخزينها بتنفيذ الأمر التالي:
docker-compose down
ويكون الخرج على النحو التالي:
Stopping travellist-nginx ... done Stopping travellist-db ... done Stopping travellist-app ... done Removing travellist-nginx ... done Removing travellist-db ... done Removing travellist-app ... done Removing network travellist-laravel-demo_travellist
الخاتمة
أعددنا بيئة دوكر بثلاث حاويات باستخدام أداة دوكر كومبوز Docker Compose وحددنا بنيته الأساسية في ملف YAML. يمكن العمل على تطبيق لارافيل Laravel دون الحاجة إلى تثبيت خادم ويب محلي وإعداده للتطوير والاختبار، ويتحقق كل ذلك باستخدام بيئة معزولة يمكن تكرارها وإعادة إنشائها بسهولة حتى الوصول إلى التطبيق المطلوب تثبيته ضمن بيئات الإنتاج.
ترجمة وبتصرف للمقال How To Install and Set Up Laravel with Docker Compose on Ubuntu 20.04 لصاحبه Erika Heidi.
أفضل التعليقات
انضم إلى النقاش
يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.