"نحن بحاجة DevOps!"(العبارة الأكثر شعبية في نهاية أي hackathon)
أولا ، بعض الأغاني.
عندما يكون المطور مطورًا ممتازًا يمكنه نشر أفكاره على أي جهاز تحت أي OC ، فإن هذا يعد ميزة إضافية. ومع ذلك ، إذا لم يفهم شيئًا أكثر من IDE الخاص به ، فهذا ليس ناقصًا - في النهاية ، يتم دفعه مقابل الكود ، وليس لقدرته على نشره. ويقدر اختصاصي ضيق عميق في السوق أعلى من متوسط مهارة "جاك لجميع الصفقات". بالنسبة لأشخاص مثلنا ، "مستخدمو IDE" ، توصل الأشخاص الطيبون إلى Docker.
مبدأ Docker هو ما يلي: "إنه يعمل بالنسبة لي - إنه يعمل في كل مكان." البرنامج الوحيد المطلوب لنشر نسخة من التطبيق الخاص بك في أي مكان هو Docker. إذا قمت بتشغيل التطبيق الخاص بك في عامل ميناء على جهازك ، فمن المضمون أن تعمل بنفس النجاح في أي عامل ميناء آخر. ولا شيء سوى عامل الميناء يحتاج إلى تثبيت. على سبيل المثال ، ليس لدي جافا على الخادم الظاهري.
كيف يعمل عامل ميناء؟
يقوم Docker بإنشاء صورة لجهاز افتراضي مع تطبيقات مثبتة فيه. علاوة على ذلك ، تتكشف هذه الصورة كجهاز افتراضي مستقل تمامًا. وتسمى نسخة تشغيل الصورة "الحاوية". يمكنك تشغيل أي عدد من الصور على الخادم ، وسيكون كل منها جهازًا افتراضيًا منفصلاً مع بيئته الخاصة.
ما هو الجهاز الظاهري؟ هذا هو الموقع المغلف على الخادم مع نظام التشغيل المثبت عليه التطبيقات. في أي نظام تشغيل ، هناك عدد كبير من التطبيقات تدور عادة ، يوجد لدينا تطبيق واحد.
يمكن تمثيل مخطط نشر الحاوية على النحو التالي:

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

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

هناك العديد من الطرق لتنفيذ مثل هذا الهيكل. نحن ننفذ واحد منهم. سننشئ صورتين ، ونطلق حاويتين منها ، وسوف تتصل الواجهة الخلفية بقاعدة البيانات المثبتة على خادم معين في مكان ما على الإنترنت (نعم ، لن تسير استعلامات قاعدة البيانات هذه بسرعة ، لكننا لا ننطلق من العطش نحو التحسين ، ولكن الاهتمام العلمي).
سيتم تقسيم المشاركة إلى أجزاء:
0. تثبيت عامل الميناء.
1. نكتب التطبيقات.
2. نقوم بجمع الصور وإطلاق الحاويات.
3. جمع الصور وإطلاق الحاويات على خادم بعيد.
4. حل مشاكل الشبكة.
0. تثبيت عامل الميناء
لتثبيت Docker ، تحتاج إلى الانتقال إلى
الموقع ومتابعة ما هو مكتوب هناك. عند تثبيت Docker على خادم بعيد ، كن مستعدًا لحقيقة أن Docker قد لا تعمل مع الخوادم على OpenVZ. كذلك قد تكون هناك مشاكل إذا لم يكن لديك iptables ممكّنة. يُنصح ببدء تشغيل الخادم على KVM باستخدام iptables. ولكن هذه هي توصياتي. إذا كان كل شيء يعمل من أجلك ، وهكذا ، سأكون سعيدًا لأنك لم تقضي وقتًا طويلاً في اكتشاف سبب عدم نجاحه ، وكيف اضطررت للقيام بذلك.
1. نكتب التطبيقات
دعنا نكتب تطبيقًا بسيطًا ذو الواجهة الأكثر بدائية على Spring Boot ، وواجهة بسيطة جدًا على ReactJS وقاعدة بيانات MySQL. سيكون للتطبيق صفحة واحدة بها زر واحد يسجل وقت النقر عليه في قاعدة البيانات.
أنا أعتمد على حقيقة أنك تعرف بالفعل كيفية كتابة التطبيقات على التمهيد ، ولكن إذا لم يكن كذلك ، يمكنك استنساخ المشروع النهائي. جميع الروابط في نهاية المقال.
الخلفية في الربيع الحذاء
build.gradle:
plugins { id 'org.springframework.boot' version '2.1.4.RELEASE' id 'java' } apply plugin: 'io.spring.dependency-management' group = 'ru.xpendence' version = '0.0.2' sourceCompatibility = '1.8' repositories { mavenCentral() } dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-web' runtimeOnly 'mysql:mysql-connector-java' testImplementation 'org.springframework.boot:spring-boot-starter-test' }
سجل الكيان:
package ru.xpendence.rebounder.entity; import com.fasterxml.jackson.annotation.JsonFormat; import javax.persistence.*; import java.io.Serializable; import java.time.LocalDateTime; import java.util.Objects; @Entity @Table(name = "request_logs") public class Log implements Serializable { private Long id; private LocalDateTime created; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) public Long getId() { return id; } @Column @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss.SSS") public LocalDateTime getCreated() { return created; } @PrePersist public void prePersist() { this.created = LocalDateTime.now(); }
LogController ، والتي ستعمل على منطق مبسط والكتابة على الفور إلى قاعدة البيانات. نحذف الخدمة.
package ru.xpendence.rebounder.controller; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import ru.xpendence.rebounder.entity.Log; import ru.xpendence.rebounder.repository.LogRepository; import java.util.logging.Logger; @RestController @RequestMapping("/log") public class LogController { private final static Logger LOG = Logger.getLogger(LogController.class.getName()); private final LogRepository repository; @Autowired public LogController(LogRepository repository) { this.repository = repository; } @GetMapping public ResponseEntity<Log> log() { Log log = repository.save(new Log()); LOG.info("saved new log: " + log.toString()); return ResponseEntity.ok(log); } }
كل شيء ، كما نرى ، بسيط للغاية. بناءً على طلب GET ، نكتب إلى قاعدة البيانات ونعيد النتيجة.
سنناقش ملف إعدادات التطبيق بشكل منفصل. هناك اثنان منهم.
application.yml:
spring: profiles: active: remote
تطبيق remote.yml:
spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://my-remote-server-database:3306/rebounder_database?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC username: admin password: 12345 jpa: hibernate: ddl-auto: update show-sql: true properties: hibernate.dialect: org.hibernate.dialect.MySQL5Dialect server: port: 8099
كيف يعمل هذا ، ربما تعلم أن Spring يقوم أولاً بفحص ملف application.properties أو application.yml - أي ملف يجده. نشير فيه إلى إعداد واحد - هو الملف الشخصي الذي سنستخدمه. عادةً ، أثناء التطوير ، أقوم بتجميع العديد من الملفات الشخصية ، ومن السهل جدًا تبديلها باستخدام ملف التعريف الافتراضي. المقبل ، يجد الربيع application.yml مع لاحقة المطلوب ويستخدمه.
حددنا مصدر البيانات ، وإعدادات JPA ، والأهم من ذلك ، المنفذ الخارجي للخلفية الخاصة بنا.
ReactJS Frontend
يمكنك أيضًا رؤية الواجهة الأمامية في مشروع على بوابة ، أو حتى لا يمكنك مشاهدته ، ولكن يمكنك استنساخه وتشغيله.
يمكنك التحقق من العمل الفردي للواجهة الأمامية عن طريق تنزيل المشروع والانتقال إلى مجلد جذر المشروع في الجهاز الطرفي (حيث يوجد ملف package.json) وتنفيذ أمرين بالتسلسل:
npm install // , maven npm start //
بالطبع ، تحتاج إلى تثبيت Node Package Manager (npm) ، وهذه هي الطريقة الأكثر صعوبة التي نتجنبها باستخدام Docker. إذا كنت لا تزال تبدأ المشروع ، فسترى النافذة التالية:

حسناً ، لقد حان الوقت لإلقاء نظرة على الكود. سأشير فقط إلى الجزء الذي يشير إلى الواجهة الخلفية.
export default class Api { _apiPath = 'http://localhost:8099'; _logUrl = '/log'; getResource = async () => { const res = await fetch(`${this._apiPath}${this._logUrl}`); if (!res.ok) { throw new Error(`Could not fetch ${this._logUrl}` + `, received ${res.status}`) } return await res.json(); }; };
الواجهة الأمامية تعمل بشكل متوقع. نحن نتبع الرابط ، انتظر الإجابة ونعرضها على الشاشة.

يجدر التركيز على النقاط التالية:
- الجبهة مفتوحة للعالم الخارجي من خلال منفذ 3000. هذا هو المنفذ الافتراضي ل React.
- يتم فتح الجزء الخلفي على المنفذ 8099. وضعناها في إعدادات التطبيق.
- الظهر يطرق قاعدة البيانات عبر الإنترنت الخارجي.
التطبيق جاهز
2. جمع الصور وإطلاق الحاويات
هيكل الجمعية لدينا سيكون على النحو التالي. سنقوم بإنشاء صورتين - الواجهة الأمامية والخلفية ، والتي ستتواصل مع بعضها البعض من خلال المنافذ الخارجية. بالنسبة للقاعدة ، لن نقوم بإنشاء صورة ، سنقوم بتثبيتها بشكل منفصل. لماذا هذا لماذا لا نخلق صورة للقاعدة؟ لدينا تطبيقان يتغيران باستمرار ولا يخزنان البيانات بأنفسنا. تخزن قاعدة البيانات البيانات في حد ذاتها ، وقد يكون هذا نتيجة لعدة أشهر من تشغيل التطبيق. علاوة على ذلك ، يمكن الوصول إلى قاعدة البيانات هذه ليس فقط عن طريق تطبيق الواجهة الخلفية لدينا ، ولكن أيضًا عن طريق العديد من الآخرين - لأنها أيضًا قاعدة بيانات ، ولن نقوم بإعادة تجميعها باستمرار. مرة أخرى ، هذه فرصة للعمل مع واجهة برمجة تطبيقات خارجية ، والتي ، بالطبع ، هي الاتصال بقاعدة البيانات الخاصة بنا.
الجمعية الأمامية النهاية
لتشغيل كل تطبيق (سواء أكان أمامي أم خلفي) ، فأنت بحاجة إلى تسلسل معيّن من الإجراءات. لتشغيل التطبيق على React ، نحتاج إلى القيام بما يلي (بشرط أن يكون لدينا بالفعل Linux):
- تثبيت NodeJS.
- نسخ التطبيق إلى مجلد معين.
- قم بتثبيت الحزم المطلوبة (أمر تثبيت npm).
- قم بتشغيل التطبيق باستخدام الأمر npm start.
هذا هو تسلسل الإجراءات الذي يتعين علينا القيام به في عامل الميناء. للقيام بذلك ، في جذر المشروع (في نفس المكان مثل package.json) ، يجب أن نضع Dockerfile بالمحتويات التالية:
FROM node:alpine WORKDIR /usr/app/front EXPOSE 3000 COPY ./ ./ RUN npm install CMD ["npm", "start"]
دعونا نرى ما يعنيه كل سطر.
FROM node:alpine
من خلال هذا الخط ، نوضح للعامل أن عند بدء تشغيل الحاوية ، فإن أول ما عليك فعله هو تنزيل Docker من المستودع وتثبيت NodeJS ، والأخف وزناً (تُسمى جميع أخف الإصدارات من الأُطُر الشائعة والمكتبات في عامل الإرساء بالألبي).
WORKDIR /usr/app/front
في حاوية Linux ، سيتم إنشاء المجلدات القياسية نفسها كما في مجلدات Linux الأخرى - / opt ، / home ، / etc ، / usr وما إلى ذلك. وضعنا دليل العمل الذي سنعمل به - / usr / app / front.
EXPOSE 3000
نفتح المنفذ 3000. سوف يحدث مزيد من الاتصالات مع التطبيق الذي يتم تشغيله في الحاوية من خلال هذا المنفذ.
COPY ./ ./
نسخ محتويات المشروع المصدر إلى مجلد العمل الحاوية.
RUN npm install
قم بتثبيت جميع الحزم اللازمة لتشغيل التطبيق.
CMD ["npm", "start"]
نبدأ التطبيق باستخدام الأمر npm start.
سيتم تنفيذ هذا السيناريو في طلبنا عندما تبدأ الحاوية.
دعونا الحصول على الجبهة مباشرة. للقيام بذلك ، في المحطة ، في المجلد الجذر للمشروع (حيث يوجد Dockerfile) ، قم بتنفيذ الأمر:
docker build -t rebounder-chain-frontend .
قيم الأوامر:
عامل ميناء هو دعوة لتطبيق عامل ميناء ، حسنا ، أنت تعرف ذلك.
بناء - بناء صورة من المواد المستهدفة.
-t <name> - في المستقبل ، سيكون التطبيق متاحًا بواسطة العلامة المحددة هنا. يمكنك حذف هذا ، ثم Docker ستنشئ العلامة الخاصة بها ، ولكن سيكون من المستحيل التمييز بينها وبين الآخرين.
. - يشير إلى أنك بحاجة إلى جمع المشروع من المجلد الحالي.

نتيجة لذلك ، يجب أن ينتهي التجميع بالنص:
Step 7/7 : CMD ["npm", "start"] ---> Running in ee0e8a9066dc Removing intermediate container ee0e8a9066dc ---> b208c4184766 Successfully built b208c4184766 Successfully tagged rebounder-chain-frontend:latest
إذا رأينا أن الخطوة الأخيرة قد اكتملت وأن كل شيء يسير بنجاح ، فلدينا صورة. يمكننا التحقق من ذلك عن طريق تشغيله:
docker run -p 8080:3000 rebounder-chain-frontend
أعتقد أن معنى هذا الأمر مفهوم بشكل عام ، باستثناء الإدخال -8080: 3000.
docker run rebounder-chain-frontend - يعني أننا نطلق صورة مرساة كهذه ، والتي أطلقنا عليها اسم rebounder-chain-frontend. ولكن مثل هذه الحاوية لن يكون لها منفذ ، فهي بحاجة إلى تعيين منفذ. إنه الفريق الذي يحددها أدناه. نتذكر أن تطبيق React الخاص بنا يعمل على المنفذ 3000. يخبر الأمر -p 8080: 3000 عامل الميناء أن يأخذ المنفذ 3000 ويحيله إلى المنفذ 8080 (والذي سيكون مفتوحًا). وبالتالي ، سيتم فتح تطبيق يعمل على المنفذ 3000 على المنفذ 8080 ، وسيكون متاحًا على الجهاز المحلي على هذا المنفذ.
, : Mac-mini-Vaceslav:rebounder-chain-frontend xpendence$ docker run -p 8080:3000 rebounder-chain-frontend > rebounder-chain-frontend@0.1.0 start /usr/app/front > react-scripts start Starting the development server... Compiled successfully! You can now view rebounder-chain-frontend in the browser. Local: http://localhost:3000/ On Your Network: http://172.17.0.2:3000/ Note that the development build is not optimized. To create a production build, use npm run build.
لا تدع السجل يزعجك
Local: http://localhost:3000/ On Your Network: http://172.17.0.2:3000/
رد فعل يعتقد ذلك. إنه متوفر بالفعل داخل الحاوية على المنفذ 3000 ، لكننا قمنا بإعادة توجيه هذا المنفذ إلى المنفذ 8080 ، ومن الحاوية يتم تشغيل التطبيق على المنفذ 8080. يمكنك تشغيل التطبيق محليًا والتحقق من ذلك.
لذلك ، لدينا حاوية جاهزة مع تطبيق الواجهة الأمامية ، والآن دعونا جمع الخلفية.
بناء الخلفية.
يختلف البرنامج النصي لبدء تشغيل تطبيق في Java بشكل كبير عن التجميع السابق. يتكون من العناصر التالية:
- تثبيت JVM.
- نحن نجمع أرشيف جرة.
- نطلقه.
في Dockerfile ، تبدو هذه العملية كما يلي:
إن عملية تجميع الصورة مع تضمين dzharnik في بعض النقاط تشبه ذلك بالنسبة لنا.
عملية تجميع وإطلاق الصورة الثانية هي في الأساس نفس عملية تجميع وإطلاق الصورة الأولى.
docker build -t rebounder-chain-backend . docker run -p 8099:8099 rebounder-chain-backend
الآن ، إذا كان لديك كلتا الحاويتين قيد التشغيل وكانت الواجهة الخلفية متصلة بقاعدة البيانات ، فسيعمل كل شيء. أذكرك بأنه يجب عليك تسجيل الاتصال بقاعدة البيانات من الجهة الخلفية بنفسك ، ويجب أن تعمل من خلال شبكة خارجية.
3. جمع الصور وتشغيل الحاويات على خادم بعيد
لكي يعمل كل شيء على خادم بعيد ، نحتاج إلى تثبيت Docker بالفعل عليه ، وبعد ذلك ، قم فقط بتشغيل الصور. سنذهب في الطريق الصحيح ونلزم صورنا بحسابنا في سحابة Docker ، وبعد ذلك ستكون متاحة من أي مكان في العالم. بالطبع ، هناك الكثير من البدائل لهذا النهج ، بالإضافة إلى كل ما هو موضح في المنشور ، ولكن دعنا ندفعه أكثر قليلاً ونقوم بعملنا بشكل جيد. سيء ، كما قال أندريه ميرونوف ، لدينا دائمًا وقت للقيام بذلك.
إنشاء حساب على لوحة الوصل
أول ما عليك فعله هو الحصول على حساب على لوحة الوصل. للقيام بذلك ، انتقل إلى
المحور والتسجيل. انها ليست صعبة.
بعد ذلك ، نحتاج إلى الانتقال إلى المحطة الطرفية وتسجيل الدخول إلى Docker.
docker login
سيُطلب منك إدخال اسم المستخدم وكلمة المرور. إذا كان كل شيء على ما يرام ، فسيظهر إشعار في المحطة الطرفية التي نجح تسجيل الدخول.
نقل الصور إلى Docker Hub
بعد ذلك ، نحتاج إلى تمييز صورنا وإلزامها بالمركز. يتم ذلك بواسطة الفريق وفقًا للمخطط التالي:
docker tag /_:
وبالتالي ، نحتاج إلى تحديد اسم صورتنا وتسجيل الدخول / المستودع والعلامة التي سيتم بموجبها نقل صورتنا إلى المحور.
في حالتي ، بدا الأمر كما يلي:

يمكننا التحقق من وجود هذه الصورة في المستودع المحلي باستخدام الأمر:
Mac-mini-Vaceslav:rebounder-chain-backend xpendence$ docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE xpendence/rebounder-chain-backend 0.0.2 c8f5b99e15a1 About an hour ago 141MB
صورتنا جاهزة للالتزام. الالتزام:
docker push xpendence/rebounder-chain-backend:0.0.2
يجب أن يظهر سجل الالتزام الناجح.
افعل نفس الشيء مع الواجهة الأمامية:
docker tag rebounder-chain-frontend xpendence/rebounder-chain-frontend:0.0.1 docker push xpendence/rebounder-chain-frontend:0.0.1
الآن ، إذا ذهبنا إلى hub.docker.com ، فسوف نرى صورتين مغلقتين. التي تتوفر من أي مكان.


ألف مبروك. علينا فقط الانتقال إلى الجزء الأخير من عملنا - لإطلاق الصور على خادم بعيد.
قم بتشغيل الصور على خادم بعيد
الآن يمكننا تشغيل صورتنا على أي جهاز باستخدام Docker من خلال استكمال سطر واحد فقط في الجهاز (في حالتنا ، نحتاج إلى تنفيذ سطرين في محطات مختلفة - واحد لكل صورة).
docker run -p 8099:8099 xpendence/rebounder-chain-backend:0.0.2 docker run -p 8080:3000 xpendence/rebounder-chain-frontend:0.0.1
هذا الاطلاق ، ومع ذلك ، ناقص واحد. عند إغلاق الجهاز ، ستنتهي العملية وسيتوقف التطبيق عن العمل. لتجنب ذلك ، يمكننا تشغيل التطبيق في وضع "منفصل":
docker run -d -p 8099:8099 xpendence/rebounder-chain-backend:0.0.2 docker run -d -p 8080:3000 xpendence/rebounder-chain-frontend:0.0.1
الآن لن يصدر التطبيق سجلًا إلى الجهاز الطرفي (يمكن ، مرة أخرى ، تكوينه بشكل منفصل) ، ولكن حتى عندما يتم إغلاق الجهاز ، فلن يتوقف عن العمل.
4. حل مشاكل الشبكة
إذا فعلت كل شيء بشكل صحيح ، فقد تتوقع أكبر خيبة أمل على طول الطريق لمتابعة هذا المنشور - قد يتضح أنه لا يوجد شيء ناجح. على سبيل المثال ، كان كل شيء يعمل بشكل مثالي من أجلك وعمل على الجهاز المحلي (على سبيل المثال ، على جهاز Mac) ، ولكن عند نشره على خادم بعيد ، توقفت الحاويات عن رؤية بعضها البعض (على سبيل المثال ، على خادم بعيد على نظام Linux). ما هي المشكلة؟ لكن المشكلة تكمن في هذا ، وفي البداية أشرت إلى ذلك. كما ذكرنا سابقًا ، عند بدء تشغيل الحاوية ، يقوم Docker بإنشاء جهاز ظاهري منفصل ، ويقوم بلف نظام Linux هناك ، ثم يقوم بتثبيت التطبيق على نظام Linux. هذا يعني أن مضيف محلي مشروط للحاوية قيد التشغيل يقتصر على الحاوية نفسها ، والتطبيق ليس على علم بوجود شبكات أخرى. لكننا بحاجة إلى:
أ) شهدت الحاويات بعضها البعض.
ب) رأى الخلفية قاعدة البيانات.
هناك حلان للمشكلة.
1. إنشاء شبكة داخلية.
2. إحضار الحاويات إلى مستوى المضيف.
1. على مستوى Docker ، يمكنك إنشاء شبكات ، علاوة على ذلك ، ثلاثة منها بشكل افتراضي -
جسر ،
بلا ،
مضيف .
Bridge هي شبكة داخلية Docker معزولة عن الشبكة المضيفة. يمكنك الوصول إلى الحاويات فقط من خلال المنافذ التي تفتحها عندما تبدأ الحاوية بالأمر
-p . يمكنك إنشاء أي عدد من الشبكات مثل
الجسر .
لا شيء عبارة عن شبكة منفصلة لحاوية معينة.
المضيف هو الشبكة المضيفة. عند اختيار هذه الشبكة ، يمكن الوصول إلى الحاوية الخاصة بك بشكل كامل من خلال المضيف - الأمر -
p ببساطة لا يعمل هنا ، وإذا قمت بنشر الحاوية على هذه الشبكة ، فلن تحتاج إلى تحديد منفذ خارجي - يمكن الوصول إلى الحاوية بواسطة منفذها الداخلي. على سبيل المثال ، إذا تم تعيين Dockerfile EXPOSE على 8090 ، فسيكون التطبيق متاحًا من خلال هذا المنفذ.

نظرًا لأننا نحتاج إلى الوصول إلى قاعدة بيانات الخادم ، فسنستخدم الأسلوب الأخير ونضع الحاويات على شبكة الخادم عن بُعد.
يتم ذلك ببساطة شديدة ، نزيل ذكر المنافذ من أمر إطلاق الحاوية ونحدد الشبكة المضيفة:
docker run --net=host xpendence/rebounder-chain-frontend:0.0.8
اتصال إلى القاعدة أشرت
localhost:3306
يجب تحديد اتصال الجبهة بالظهر بالكامل ، خارجي:
http://<__:__>
إذا قمت بإعادة توجيه المنفذ الداخلي إلى المنفذ الخارجي ، وهو ما يحدث غالبًا للخوادم البعيدة ، فستحتاج إلى تحديد المنفذ الداخلي لقاعدة البيانات ، والمنفذ الخارجي للحاوية.
إذا كنت ترغب في تجربة الاتصالات ، فيمكنك تنزيل وبناء مشروع كتبته خصيصًا لاختبار الاتصال بين الحاويات. فقط أدخل العنوان المطلوب ، اضغط على إرسال وفي وضع التصحيح ، راجع ما عاد.
المشروع يكمن
هنا .
استنتاج
هناك العديد من الطرق لإنشاء صورة Docker وتشغيلها. للمهتمين ، أنصحك أن تتعلم إنشاء عامل ميناء. لقد درسنا هنا واحدة فقط من طرق العمل مع عامل الميناء. بالطبع ، هذا النهج في البداية لا يبدو بهذه البساطة. ولكن هنا مثال - أثناء كتابة منشور ، كان لدي اتصالات صادرة على خادم بعيد. وأثناء عملية تصحيح الأخطاء ، اضطررت إلى تغيير إعدادات اتصال قاعدة البيانات عدة مرات. يتلاءم التجميع والنشر الكاملان في مجموعة الخطوط المكونة من 4 خطوط ، بعد الدخول التي رأيتها النتيجة على خادم بعيد. في وضع البرمجة المتطرفة ، Docker أمر لا غنى عنه.
كما وعدت ، أنشر مصادر التطبيق:
الخلفيةالواجهة