في الأسبوع الماضي، كنت أستكشف أخطاء مستودع Laravel/Next.js أحادي لعميل حجز سيارات ليموزين في أبو ظبي. كانت تبعيات PHP معطلة، وكانت الواجهة الأمامية تتلقى أخطاء 502، وكان إصدار PHP المحلي على جهازي Mac يتعارض مع Docker. هذا هو السبب في أننا نستخدم الحاويات - ولكن الحصول على الإعداد الصحيح استغرق مني 3 أيام كاملة وكمية من القهوة أكثر مما أود الاعتراف به. اسمحوا لي أن أشرح لكم ما يعمل بالفعل.
لماذا Docker يجعل حياتي أسهل (في الغالب)
قبل ثلاث سنوات، قمت بإطلاق Tawasul Limo باستخدام Laravel للحجوزات و Next.js للوحة تحكم المسؤول. لم يكن Docker خياري الأول، ولكن العميل كان بحاجة إلى بيئات تطوير وإنتاج متطابقة لتجنب فوضى "يعمل على جهازي".
متطلباتي الرئيسية:
- •تشغيل Laravel (مع MySQL 8.0 و Redis) و Next.js (مع Node 18) جنبًا إلى جنب
- •مشاركة التعليمات البرمجية بين الحاويات (إعادة التحميل السريع مهم)
- •الحفاظ على متغيرات البيئة DRY (تحية لملفات
.env) - •عدم محاربة الأدوات الأصلية لجهازي (أنا أنظر إليك، MAMP)
أصبح Docker Compose أفضل صديق لي - ولكن فقط بعد أن توقفت عن محاولة حشر كل شيء في ملف docker-compose.yml واحد.
هيكل المجلدات الذي يوفر لي ساعات
إليكم ما أفعله للمستودعات الأحادية (مثل Tawasul Limo) ومشاريع الخدمات المتعددة:
project-root/
├── backend/ # Laravel app
│ ├── Dockerfile
├── frontend/ # Next.js app
│ ├── Dockerfile
├── docker-compose.yml
└── shared/ # Shared config or componentsفي البداية، حاولت تحميل المستودع بأكمله كوحدة تخزين - لكن التغييرات في /shared لم تنتشر بشكل نظيف. الآن أقوم بتحميل ما أحتاجه فقط. بالنسبة إلى Laravel، هذا يعني:
volumes:
- ./backend:/var/www/html
- ./backend/storage:/var/www/html/storageتطلب Next.js تعديلًا: chokidar لا يحب وحدات تخزين Docker. انتهى بي الأمر باستخدام rsync لمزامنة أسرع للملفات.
Dockerfiles: اجعلها بسيطة وسريعة
Backend (Laravel) Dockerfile
FROM php:8.2-fpm-alpine3.18
RUN docker-php-ext-install pdo pdo_mysql
WORKDIR /var/www/html
COPY ./backend /var/www/html
RUN composer install --no-devبسيطة، لكنها لدغتني في عام 2024 عندما استمر النص العربي الخاص بأحد عملاء دبي في التعطل. لم يتم تعيين ترتيب MySQL بشكل صحيح - درس تعلمته: تحقق دائمًا من دعمutf8mb4 في صورة PHP الخاصة بك.
Frontend (Next.js) Dockerfile
FROM node:18-alpine3.18
WORKDIR /app
COPY ./frontend /app
RUN npm install --production
CMD ["npm", "run", "dev"]لقد استخدمت --no-cache للإنشاءات. ثم أدركت أن خادم CI يكرهني بسبب ذلك. الآن أقوم بتخزين node_modules مؤقتًا ما لم أكن أصحح أخطاء تعارضات الحزم.
Docker Compose: الغراء الذي يربط كل شيء ببعضه
version: '3.8'
services:
laravel:
build: ./backend
ports:
- "9000:9000"
volumes:
- ./backend:/var/www/html
environment:
- DB_HOST=mysql
nextjs:
build: ./frontend
ports:
- "3000:3000"
volumes:
- ./frontend:/app
depends_on:
- laravel
mysql:
image: mysql:8.0
ports:
- "3306:3306"
environment:
- MYSQL_ROOT_PASSWORD=secretنعم، قمت بتعيين منفذ MySQL إلى المضيف الخاص بي. نعم، هذا خطر أمني. ولكن عندما تقوم بتصحيح أخطاء اتصالات قاعدة بيانات Laravel في Dev (ولست تعرض هذا في الإنتاج - أليس كذلك؟)، فهذا منقذ للحياة.
نقطة مهمة: كان PHP-FPM يتعطل بسبب أذونات المستخدم. أضفت خطوة Dockerfile لتعيين المستخدم الصحيح:
RUN useradd -u 1000 app && chown -R app /var/www/html
USER appمشكلات قاعدة البيانات والتخزين المؤقت (الأشياء التي تلدغك يوم الجمعة الساعة 6 مساءً)
أقوم دائمًا بتضمين Redis في المكدس، حتى لو لم يكن العميل بحاجة إليه بعد. تحسبًا للمستقبل.
services:
redis:
image: redis:alpine3.18
ports:
- "6379:6379"ذات مرة، تعطل موقع تجريبي لعميل عقاري لأنني نسيت تعيين REDIS_HOST=redis في ملف .env الخاص بـ Laravel. لا تشترك البيئات المجهزة بـ Docker في نفس الشبكة مثل جهازك تحقق دائمًا من أسماء المضيفين في ملفات التهيئة.
التطوير المحلي مقابل الإنتاج: ما هو المختلف فعليًا
أحتفظ بملفات .env و docker-compose منفصلة للتطوير والإنتاج. على سبيل المثال:
Dev .env:
DB_HOST=mysql
REDIS_HOST=redisProd .env:
DB_HOST=aws-rds-instance.region
REDIS_HOST=elasticache-endpointأستخدم أسرار Docker في الإنتاج، لكن هذا مبالغة بالنسبة للتطوير المحلي. تبديل سريع لعلامة --env-file في أوامر تشغيل Docker يعالج 90٪ من احتياجاتي.
الأسئلة الشائعة
هل يجب علي تشغيل MySQL في نفس إعداد Docker مثل حاويات التطبيق الخاصة بي؟
نعم، ما لم تكن تقوم بالتحسين من أجل نقاء DevOps. لقد قتلت عمليات MySQL المحلية عدة مرات في منتصف sprint - تجهيز قاعدة البيانات بـ docker يمنحني إعادة تعيين حالة نظيفة دون كسر المشاريع الأخرى.
كيف يمكنني تصحيح أخطاء تطبيق Laravel يعمل في Docker؟
استخدم xdebug، ولكن كن حذرًا: فسوف يبطئ الأمور. أقوم بتعيين المنفذ 9003 وتعيين XDEBUG_MODE=debug:
ENV PHP_XDEBUG_REMOTE_PORT=9003هل يبطئ Docker إعادة التحميل السريع لـ Next.js على جهاز M1 Mac?
حدث ذلك في عام 2023. تم التبديل إلى docker context use desktop-linux، والأمر أفضل الآن. لا يزال ليس بالسرعة الأصلية لـ Node، ولكنه مقبول لعروض العملاء التوضيحية.
كيفية التعامل مع حزم NPM التي تتطلب Python/Rust في إصدارات Docker؟
استخدم إصدارات متعددة المراحل. أولاً، قم بتثبيت تبعيات النظام في Dockerfile الخاص بك (RUN apk add --no-cache python3 py3-pip)، ثم COPY --from=build_stage. مؤلم؟ نعم. هل يهدد الحياة؟ لا.
هل تريد المزيد من النصائح الملموسة حول Docker لمشاريع PHP/JS؟ أرسل لي ملاحظة أو احجز جلسة مجانية لمدة 30 دقيقة. لقد أمضيت أكثر من 7 سنوات في مصارعة إعدادات Docker للشركات الناشئة في الإمارات العربية المتحدة وعملاء المؤسسات - لنتجاوز التجربة والخطأ.