اذهب إلى المحتوى

إعداد حاوية لتطبيق لارافيل باستخدام دوكر كومبوز Docker Compose


سامر سليمان

نعرّف الاحتواء ضمن حاوية Containerization على أنه عملية تكييف التطبيق ومكوناته لتصبح قادرة على العمل ضمن بيئة بسيطة أساسية المقومات ندعوها الحاوية لتشكّل بيئة معزولة يمكن التخلص منها بسهولة عند الرغبة بذلك، كما يمكن الاستفادة منها لتطوير واختبار ونشر التطبيقات ضمن بيئات الإنتاج.

نعمل في هذا المقال على استخدام أداة Docker Compose لاحتواء تطبيق لارافيل بهدف تطويره ضمن بيئة مستقلة خاصة به. نحصل على تطبيق لارافيل توضيحي موزّع على ثلاث حاويات خدمة منفصلة كما يلي:

  • خدمة تطبيق "app" تعمل على PHP7.4-FPM.
  • خدمة قاعدة بيانات "db" تحتوي خادم MySQL 5.7.
  • خدمة "nginx" تستخدم خدمة "app" من أجل تحليل شيفرة برمجية بلغة PHP قبل تقديم تطبيق لارافيل للمستخدم النهائي.

نستخدم وحدات التخزين المشتركة Shared Volumes من أجل مزامنة ملفات التطبيق وذلك لتطوير تطبيق بسيط وتصحيح الأخطاء بسهولة، كما نستخدم أوامر "docker-compose exec" لتشغيل تعليمات "Composer" و "Artisan" في حاوية التطبيق.

المتطلبات الأساسية

  • الوصول إلى حاسب يعمل بنظام التشغيل أوبنتو Ubuntu (استعملنا الإصدار 18.04 في هذا المقال) أو إلى خادم تطوير يعمل بنفس نظام التشغيل المذكور بواسطة مستخدم ذي صلاحيات إدارة sudo، ولا يُفضّل استخدام حساب الجذر Root لأسباب تتعلق بأمان الخادم، كما يُفضّل وجود جدار حماية نشط في حال العمل على خادم بعيد.
  • تثبيت الأداة دوكر على الخادم أو الجهاز المحلي.
  • تثبيت أداة دوكر كومبوز "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

ننفذ الأمر التالي لفك الضغط وتسمية المجلد ليصبح باسم "travellist-demo" بهدف السهولة:

unzip travellist.zip
mv travellist-laravel-demo-tutorial-1.0.1 travellist-demo

ننتقل إلى المجلد "travellist-demo" من خلال الأمر التالي:

cd travellist-demo

الخطوة 2- إعداد ملف الضبط الخاص بالتطبيق

تتواجد ملفات ضبط لارافيل في مجلد يُدعى "config" ضمن مجلد الجذر للتطبيق، إذ يُستخدم الملف "env." لعمليات الضبط المتعلقة بالبيئة، مثل بيانات الاعتماد وأية معلومات تختلف بين عمليات نشر التطبيقات لذلك لا يُضمّن هذا الملف ضمن ملفات التحكم بالإصدارات لكي لا تنتشر هذه المعلومات لجميع المستخدمين الذين يستخدمون صورة التطبيق لاحقًا.

تحذير: يحتوي ملف تهيئة البيئة على معلومات حساسة حول الخادم، بما في ذلك بيانات اعتماد قاعدة البيانات ومفاتيح الأمان، لهذا السبب لا يجب أبدًا مشاركة هذا الملف علنًا.

توجد أولوية للقيم الموجودة في الملف "env." على القيم الموجودة في ملفات التهيئة الأخرى الموجودة في المجلد "config".

تتطلب كل عملية تثبيت في بيئة جديدة ملف بيئة مخصص لتعريف معلومات جديدة، مثل إعدادات الاتصال في قاعدة البيانات، وخيارات التصحيح، ورابط URL للتطبيق، إضافةً لبقية العناصر او المعلومات التي تختلف تبعًا للبيئة التي يعمل بها التطبيق. ننشئ ملف "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- إعداد Dockerfile للتطبيق

تستند خدمتا 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 والمتاح ضمن أحدث صورة رسمية إلى صورة التطبيق الخاص بنا.

ننشئ مستخدم نظام جديد ونبدأ بإعداد المتغيرين user و uid الذين عرّفناهما في بداية الملف Dockerfile إذ تُمرر هذه المتغيرات إلى الحاوية باستخدام الأداة دوكر كومبوز في وقت الإنشاء.

نحدد مسار العمل الافتراضي "www/var/" ونسجل الدخول بواسطة المستخدم الذي أنشأناه مؤخرًا، للتأكد من الاتصال بقاعدة البيانات مثل مستخدم عادي وأننا في المسار الصحيح عند استخدام الأوامر مثل أوامر "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.*".

سنشارك تفريغ قاعدة البيانات database dumpfile التي تستورد عند تهيئة الحاوية لإعداد قاعدة البيانات MySQL، إذ تتوفر هذه الميزة في MySQL 5.7 التي سنستخدمها في حاوية التطبيق. ننشئ مجلدًا جديدًا لتهيئة ملفات MySQL داخل المجلد "docker-compose" بتنفيذ الأمر التالي:

mkdir docker-compose/mysql

ننشئ ملف "sql." جديد بتنفيذ الأمر:

nano docker-compose/mysql/init_db.sql

يعتمد ملف قاعدة البيانات MySQL dump التالي على قاعدة البيانات المُنشأة في مقال لارافيل بالاعتماد على LEMP من ديجيتال أوشن، إذ يُنشئ جدولًا اسمه places في قاعدة البيانات ثم سيملأ محتوياته بمجموعة من العينات. ولضبط بنية هذا الجدول ومحتوياته، نكتب الشيفرة البرمجية التالية في الملف "init_db.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"، والذي يمكن أن يكون موجودًا مسبقًا ضمن مجلد الجذر Root للتطبيق، ويحدد هذا الملف بيئة الحاويات بما في ذلك الصور الأساسية لبناء التطبيق وكيفية تفاعل الخدمات ضمنه.

نحدد ثلاث خدمات مختلفة ضمن ملف "docker-compose.yml" وهي "app" و "db" و "nginx"؛ إذ تُنشئ خدمة "app" صورةً تسمى "travellist" بناءً على ملف Dockerfile الذي أنشأناه مسبقًا، وتُشغّل الحاوية التي تحددها هذه الخدمة خادم "php-fpm" لتحليل شيفرات PHP وتُرسل النتائج مرةً أخرى إلى خدمة "nginx"، التي تعمل على حاوية منفصلة؛ بينما تحدد خدمة "mysql" حاويةً تُشغل خادم MySQL 5.7. تتصل هذه الخدمات فيما بينها باستخدام شبكة جسر أسميناها "travellist".

تُزامن ملفات التطبيق على كل من الخدمتين "app" و "nginx" عبر حوامل الربط ؛ إذ تُعد حوامل الربط مفيدةً في بيئات التطوير لأنها تتيح مزامنةً ثنائية الاتجاه بين الجهاز المضيف والحاويات. نُنشئ ملفًا جديدًا باسم "docker-compose.yml" في مجلد الجذر Root للتطبيق بتنفيذ الأمر التالي:

nano docker-compose.yml

يبدأ ملف "docker-compose.yml" التقليدي برقم الإصدار يليه تعريف الخدمات "services" الخاصة بالتطبيق، كما يُضاف تعريف الشبكات التي يشاركها التطبيق في نهاية الملف، ويكون بالتالي محتوى هذا الملف على النحو التالي:

version: "3.7"
services:


networks:
  travellist:
    driver: bridge

خدمة التطبيق 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 من Docker Hub. نظرًا لأن دوكر كومبوز يحمّل الملفات المتغيرة "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   nginx -g daemon off;            Up      0.0.0.0:8000->80/tcp

بيئتنا الآن قيد التشغيل، لكننا ما زلنا بحاجة إلى تنفيذ أمرين لإنهاء إعداد التطبيق، إذ نستخدم الأمر docker-compose exec لتنفيذ جميع الأوامر ضمن الحاويات، فلو رغبنا بتنفيذ الأمر ls –l الذي يظهر معلومات تفصيلية حول الملفات في مسار التطبيق، ننفذ الأمر التالي وتظهر النتائج كما يلي:

docker-compose exec app ls -l

ويكون الخرج على النحو التالي:

total 256
-rw-rw-r-- 1 sammy 1001    738 Jan 15 16:46 Dockerfile
-rw-rw-r-- 1 sammy 1001    101 Jan  7 08:05 README.md
drwxrwxr-x 6 sammy 1001   4096 Jan  7 08:05 app
-rwxr-xr-x 1 sammy 1001   1686 Jan  7 08:05 artisan
drwxrwxr-x 3 sammy 1001   4096 Jan  7 08:05 bootstrap
-rw-rw-r-- 1 sammy 1001   1501 Jan  7 08:05 composer.json
-rw-rw-r-- 1 sammy 1001 179071 Jan  7 08:05 composer.lock
drwxrwxr-x 2 sammy 1001   4096 Jan  7 08:05 config
drwxrwxr-x 5 sammy 1001   4096 Jan  7 08:05 database
drwxrwxr-x 4 sammy 1001   4096 Jan 15 16:46 docker-compose
-rw-rw-r-- 1 sammy 1001   1015 Jan 15 16:45 docker-compose.yml
-rw-rw-r-- 1 sammy 1001   1013 Jan  7 08:05 package.json
-rw-rw-r-- 1 sammy 1001   1405 Jan  7 08:05 phpunit.xml
drwxrwxr-x 2 sammy 1001   4096 Jan  7 08:05 public
-rw-rw-r-- 1 sammy 1001    273 Jan  7 08:05 readme.md
drwxrwxr-x 6 sammy 1001   4096 Jan  7 08:05 resources
drwxrwxr-x 2 sammy 1001   4096 Jan  7 08:05 routes
-rw-rw-r-- 1 sammy 1001    563 Jan  7 08:05 server.php
drwxrwxr-x 5 sammy 1001   4096 Jan  7 08:05 storage
drwxrwxr-x 4 sammy 1001   4096 Jan  7 08:05 tests
-rw-rw-r-- 1 sammy 1001    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

يظهر عندها الخرج التالي:

browser_responce.jpg

نستطيع استخدام الأمرlogs لفحص السجلات التي تولّدها الخدمة بتنفيذ الأمر التالي:

docker-compose logs nginx

ويكون الخرج على النحو التالي:

Attaching to travellist-nginx
travellist-nginx | 192.168.160.1 - - [23/Jan/2020:13:57:25 +0000] "GET / HTTP/1.1" 200 626 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36"
travellist-nginx | 192.168.160.1 - - [23/Jan/2020:13:57:26 +0000] "GET /favicon.ico HTTP/1.1" 200 0 "http://localhost:8000/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36"
travellist-nginx | 192.168.160.1 - - [23/Jan/2020:13:57:42 +0000] "GET / HTTP/1.1" 200 626 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36"

نستطيع إيقاف العمل مؤقتًا لبيئة دوكر كومبوز مع الحفاظ على حالة الخدمات بتشغيل الأمر:

Docker-compose puse

ويكون الخرج على النحو التالي:

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

الخاتمة

أعددنا بيئة دوكر مكونة من ثلاث حاويات باستخدام الأداة دوكر كومبوز وحددنا بنيته الأساسية في ملف YAML. يمكن العمل على تطبيق لارافيل دون الحاجة إلى تثبيت خادم ويب محلي وإعداده للتطوير والاختبار، ويتحقق كل ذلك باستخدام بيئة معزولة يمكن تكرارها وإعادة إنشائها بسهولة حتى الوصول إلى التطبيق المطلوب تثبيته ضمن بيئات الإنتاج.

ترجمة -وبتصرّف- للمقال How To Containerize a Laravel Application for Development with Docker Compose on Ubuntu 18.04 لصاحبه Erika Heidi.

اقرأ أيضًا


تفاعل الأعضاء

أفضل التعليقات

لا توجد أية تعليقات بعد



انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أضف تعليق

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • أضف...