إرساء تطبيق مبني على أساس React و Express و MongoDB

يريد كاتب مقال نترجمه اليوم أن يتحدث عن كيفية حزم تطبيقات الويب المستندة إلى React و Express و MongoDB في حاويات Docker. سننظر هنا في ميزات تشكيل بنية الملفات والمجلدات الخاصة بهذه المشاريع ، وإنشاء الملفات Dockerfileواستخدام تقنية Docker Compose.



بداية العمل


من أجل البساطة ، أفترض أن لديك بالفعل تطبيق فعال ، مقدم من قبل العميل والخادم ، متصل بقاعدة البيانات.

من الأفضل أن يكون رمز العميل والخادم موجودًا في نفس المجلد. يمكن وضع الرمز في مستودع واحد ، ولكن يمكن تخزينه في مستودعات مختلفة. في هذه الحالة ، يجب دمج المشاريع في مجلد واحد باستخدام الأمر git submodule. لقد فعلت ذلك.


شجرة ملف المستودع الأصل

تطبيق رد الفعل


لقد استخدمت هنا مشروعًا تم إنشاؤه باستخدام تطبيق Create React وتم تكوينه لدعم TypeScript. هذه مدونة بسيطة تحتوي على العديد من العناصر المرئية.

أولاً ، قم بإنشاء ملف Dockerfileفي الدليل الجذر client. للقيام بذلك ، فقط قم بتشغيل الأمر التالي:

$ touch Dockerfile

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

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

FROM node:12-alpine as builder
WORKDIR /app
COPY package.json /app/package.json
RUN npm install --only=prod
COPY . /app
RUN npm run build

هكذا يبدأ عملنا Dockerfile. يأتي الفريق أولاً node:12-alpine as builder. ثم نضع دليل العمل - في حالتنا ، هذا /app. ونتيجة لذلك ، سيتم إنشاء مجلد جديد في الحاوية. في مجلد الحاوية هذا ، قم بنسخ package.jsonوتثبيت التبعيات. ثم /appنقوم بنسخ كل شيء من المجلد /services/client. يتم الانتهاء من العمل من قبل الجمعية العامة للمشروع.

تحتاج الآن إلى تنظيم الاستضافة للتجميع الذي تم إنشاؤه حديثًا. للقيام بذلك ، استخدم NGINX. ومرة أخرى ، ستكون هذه هي النسخة الألبية من النظام. نفعل ذلك ، كما كان من قبل ، لتوفير مساحة.

FROM nginx:1.16.0-alpine
COPY --from=builder /app/build /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

هنا ، nginxيتم نسخ نتائج تجميع المشروع التي تم الحصول عليها في الخطوة السابقة إلى المجلد . ثم افتح المنفذ 80. في هذا المنفذ ، ستنتظر الحاوية للاتصالات. يتم استخدام السطر الأخير من الملف لبدء NGINX.

هذا هو كل ما هو مطلوب لرسو جزء العميل من التطبيق. Dockerfileستظهر النتيجة كما يلي:

FROM node:12-alpine as build
WORKDIR /app
COPY package.json /app/package.json
RUN npm install --only=prod
COPY . /app
RUN npm run build
FROM nginx:1.16.0-alpine
COPY --from=build /app/build /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

Express API


واجهة برمجة تطبيقات Express الخاصة بنا بسيطة للغاية. هنا ، لتنظيم نقاط النهاية ، يتم استخدام تقنية RESTful. تُستخدم نقاط النهاية لإنشاء منشورات ودعم التفويض ولحل المشكلات الأخرى. لنبدأ بالإنشاء Dockerfileفي الدليل الجذر api. سنعمل كما كان من قبل.

أثناء تطوير جانب الخادم من التطبيق ، استخدمت إمكانات ES6. لذلك ، لتشغيل التعليمات البرمجية ، أحتاج إلى تجميعها. قررت معالجة الكود باستخدام بابل. كما كنت قد خمنت ، هنا مرة أخرى سيتم استخدام عملية التجميع متعددة المراحل.

FROM node:12-alpine as builder
WORKDIR /app
COPY package.json /app/package.json
RUN apk --no-cache add --virtual builds-deps build-base python
RUN npm install
COPY . /app
RUN npm run build

كل شيء هنا مشابه جدًا للذي Dockerfileاستخدمناه في جزء العميل من المشروع ، لذلك لن نتطرق إلى التفاصيل. ومع ذلك ، هناك ميزة واحدة:

RUN apk --no-cache add --virtual builds-deps build-base python

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

node-pre-gyp WARN Pre-built binaries not found for bcrypt@3.0.8 and node@12.16.1 (node-v72 ABI, musl) (falling back to source compile with node-gyp)
npm ERR! Failed at the bcrypt@3.0.8 install script.

هذه مشكلة معروفة على نطاق واسع. حلها هو تثبيت حزم إضافية و Python قبل تثبيت حزم npm.

الخطوة التالية في بناء الصورة ، كما هو الحال في حالة العميل ، هي أخذ ما تم تشكيله في الخطوة السابقة وبدء استخدامه باستخدام Node.js.

FROM node:12-alpine
WORKDIR /app
COPY --from=builder /app/dist /app
COPY package.json /app/package.json
RUN apk --no-cache add --virtual builds-deps build-base python
RUN npm install --only=prod
EXPOSE 8080 
USER node
CMD ["node", "index.js"]

هناك ميزة أخرى هنا ، تتمثل في تثبيت الحزم المصممة فقط للمشروع للعمل في الإنتاج. لم نعد بحاجة إلى بابل - بعد كل شيء ، تم تجميع كل شيء بالفعل في الخطوة الأولى للتجمع. بعد ذلك ، نفتح المنفذ 8080الذي سينتظر عليه جانب الخادم من التطبيق وصول الطلبات ، وتشغيل Node.js.

هنا هو الملخص Dockerfile:

FROM node:12-alpine as builder
WORKDIR /app
COPY package.json /app/package.json
RUN apk --no-cache add --virtual builds-deps build-base python
RUN npm install
COPY . /app
RUN npm run build
FROM node:12-alpine
WORKDIR /app
COPY --from=builder /app/dist /app
COPY package.json /app/package.json
RUN apk --no-cache add --virtual builds-deps build-base python
RUN npm install --only=prod
EXPOSE 8080 
USER node
CMD ["node", "index.js"]

يؤلف عامل الميناء


المرحلة الأخيرة من عملنا هو جلب الحاويات apiو clientالحاوية التي تحتوي على MongoDB. للقيام بذلك ، سنستخدم الملف docker-compose.ymlالموجود في الدليل الجذر للمستودع الأصلي. يتم ذلك بسبب حقيقة أنه من هذا المكان هناك وصول إلى الملفات Dockerfileالخاصة بأجزاء العميل والخادم من المشروع.

قم بإنشاء ملف docker-compose.yml:

$ touch docker-compose.yml

يجب أن يبدو هيكل ملف المشروع الآن كما هو موضح أدناه.


الهيكل النهائي لملفات المشروع

الآن سنضيف إلىdocker-compose.ymlالأوامر التالية:

version: "3"
services:
  api:
    build: ./services/api
    ports:
      - "8080:8080"
    depends_on:
      - db
    container_name: blog-api
  client:
    build: ./services/client
    ports:
      - "80:80"
    container_name: blog-client
  db:
    image: mongo
    ports:
      - "27017:27017"
    container_name: blog-db

يتم ترتيب كل شيء ببساطة شديدة. لدينا ثلاث خدمات: client، apiو db. لا يوجد اختيار لـ MongoDB Dockerfile- Docker سيقوم بتنزيل الصورة المناسبة من مركزه وإنشاء حاوية منه. هذا يعني أن قاعدة البيانات الخاصة بنا ستكون فارغة ، ولكن بالنسبة للمبتدئين ، فإن هذا سوف يناسبنا.

في الفروع apiو clientليس هناك مفتاح buildالذي يحتوي على المسار إلى الملفات من قيمة Dockerfileالخدمات المقابلة (إلى الدلائل الجذر apiو client). Dockerfileسيتم فتح منافذ الحاوية المخصصة في الملفات على شبكة Docker Compose المستضافة. سيسمح هذا للتطبيقات بالتفاعل. عند تكوين الخدمة api، بالإضافة إلى ذلك ، يتم استخدام المفتاحdepends_on. أخبر Docker أنه قبل بدء هذه الخدمة ، عليك الانتظار حتى تبدأ الحاوية بالكامل db. بفضل هذا ، يمكننا منع الأخطاء في الحاوية api.

و - هنا شيء صغير آخر يتعلق بـ MongoDB. في قاعدة كود الواجهة الخلفية ، تحتاج إلى تحديث سلسلة اتصال قاعدة البيانات. عادة ما يشير إلى localhost:

mongodb://localhost:27017/blog

ولكن ، باستخدام تقنية Docker Compose ، علينا أن نجعلها تشير إلى اسم الحاوية:

mongodb://blog-db:27017/blog

الخطوة الأخيرة من عملنا هي بدء كل هذا بتنفيذ docker-compose.ymlالأمر التالي في مجلد جذر المشروع (حيث يوجد الملف ):

$ docker-compose up

ملخص


نظرنا إلى تقنية بسيطة لحاوية التطبيقات على أساس React و Node.js و MongoDB. نعتقد أنه إذا كنت في حاجة إليها ، يمكنك تكييفها بسهولة لمشروعاتك.

PS أطلقنا السوق على موقع RUVDS. يتم تثبيت صورة Docker هناك بنقرة واحدة. يمكنك التحقق من تشغيل الحاويات على VPS . يتم منح العملاء الجدد 3 أيام مجانًا للاختبارات.

القراء الأعزاء! هل تستخدم Docker Compose؟


All Articles