Compose: نفذ الأمر بعد التشغيل

تم إنشاؤها على ٥ أغسطس ٢٠١٥  ·  131تعليقات  ·  مصدر: docker/compose

مرحبا،

سيكون من المفيد جدًا وجود شيء مثل "onrun" في YAML لتتمكن من تشغيل الأوامر بعد التشغيل. شبيه بـ https://github.com/docker/docker/issues/8860

mongodb:
    image: mongo:3.0.2
    hostname: myhostname
    domainname: domain.lan
    volumes:
        - /data/mongodb:/data
    ports:
        - "27017:27017" 
    onrun:
        - mongodump --host db2dump.domain.lan --port 27017 --out /data/mongodb/dumps/latest
        - mongorestore -d database /data/mongodb/dumps/latest/database

بعد بدء mongodb ، سيتم تفريغ db2dump.domain.lan واستعادته.

عندما أتوقف ثم أبدأ الحاوية ، لن يتم تنفيذ جزء التشغيل للحفاظ على العاطفة.

EDIT 15 يونيو 2020

بعد 5 سنوات ، لا يريد إنشاء "توحيد" المواصفات ،
يرجى مراجعة https://github.com/compose-spec/compose-spec/issues/84

التعليق الأكثر فائدة

لذا ، لإدارة عامل الإرساء الخاص بي ، تقترح علي استخدام Script أو Makefile. فلماذا تم إنشاء التأليف
؟ يمكننا إدارة وتوسيع نطاق الحاوية مع البرنامج النصي || ملف عامل ميناء؟

حسنًا ، آخذ هذا المثال ، إنه ما استخدمته لنشر بيئة اختبار التطبيق في عملية CI.

rabbitmq:
    image: rabbitmq:3.5.1-management
    environment:
        RABBITMQ_NODENAME: rabbit
    hostname: rabbitmq
    domainname: domain.lan
    volumes:
        - /data/rabbitmq/db:/var/lib/rabbitmq
    ports:
        - "5672:5672" 
        - "15672:15672"
        - "25672:25672"
        - "4369:4369"

mongodb:
    image: mongo:3.0.2
    hostname: mongo
    domainname: domain.lan
    volumes:
        - /data/mongodb:/data
    ports:
        - "27017:27017" 

appmaster:
    image: appmaster
    hostname: master
    domainname: domain.lan
    environment:
        ...
    ports:
        - "80:80" 
        - "8080:8080"
    links:
        - mongodb
        - rabbitmq

celery:
    image: celery
    hostname: celery
    domainname: domain.lan
    environment:
        ...
    links:
        - rabbitmq

بعد بدء الحاوية ، يجب أن أقوم بتوفير mongodb وإدارة قائمة الانتظار والحساب في rabbitmq

ما أفعله اليوم هو سيناريو به:

#!/bin/bash
PROJECT=appmaster
docker-compose -f appmaster.yml -p appmaster up -d
docker exec appmaster_rabbitmq_1 rabbitmqctl add_user user password
docker exec appmaster_rabbitmq_1 rabbitmqctl add_vhost rabbitmq.domain.lan
docker exec appmaster_rabbitmq_1 rabbitmqctl set_permissions -p rabbitmq.domain.lan password ".*" ".*" ".*"
docker exec appmaster_mongodb_1 mongodump --host mongo-prd.domain.lan --port 27017 --out /data/mongodb/dumps/latest
docker exec appmaster_mongodb_1 mongorestore -d database /data/mongodb/dumps/latest/database

باستخدام تعليمات onrun يمكنني الحصول على docker-compose -f appmaster.yml -p appmaster up -d
ويصبح ملف yml أكثر قابلية للقراءة

rabbitmq:
    ...
    onrun:
        - rabbitmqctl add_user user password
        - rabbitmqctl add_vhost rabbitmq.domain.lan
        - rabbitmqctl set_permissions -p rabbitmq.domain.lan password ".*" ".*" ".*"

mongodb:
    ...
    onrun:
        - mongodump --host mongo-prd.domain.lan --port 27017 --out /data/mongodb/dumps/latest
        - mongorestore -d database /data/mongodb/dumps/latest/database

ال 131 كومينتر

أعتقد أن هذه يجب أن تكون خطوات في Dockerfile

FROM mongo:3.0.2
ADD data/mongodb/dumps/latest /data/mongodb/dumps/latest
RUN mongorestore -d database /data/mongodb/dumps/latest/database

بهذه الطريقة يمكنك أيضًا تخزينها مؤقتًا عند إعادة البناء.

شكراdnephin.
بالطبع يمكنني إنشاء Dockerfile واستخدامه في الإنشاء بدلاً من الصور ، أو يمكنني استخدام docker exec.
MongoDB هو مجرد مثال ، يمكنك الحصول على هذا المثال باستخدام mysql وإنشاء الحساب ، أو باستخدام rabbitmq وإنشاء قائمة الانتظار وما إلى ذلك.

سيسمح onrun بالمرونة في تنسيق الإنشاء ، وسيقرأ الإنشاء قائمة التشغيل ويجعل docker exec لكل عنصر.

النقطة المهمة هي أن وضع الأوامر على docker exec في docker-compose.yml غير ضروري عندما يمكنك القيام بذلك إما في Dockerfile أو في البرنامج النصي لبدء تشغيل الحاوية ، وكلاهما سيجعل حاويتك أكثر فائدة عندما لا _ يجري تشغيله مع Compose.

بدلاً من ذلك ، ابدأ تطبيقك بنص shell أو Makefile الذي يقوم بتشغيل الأوامر المناسبة docker و docker-compose .

لا تستحق الوظيفة الإضافة إلى Compose ما لم تضيف قيمة كبيرة على القيام بأي من هذين ، ولا أعتقد أنها ستكون مفيدة لحالات الاستخدام التي ذكرتها.

لذا ، لإدارة عامل الإرساء الخاص بي ، تقترح علي استخدام Script أو Makefile. فلماذا تم إنشاء التأليف
؟ يمكننا إدارة وتوسيع نطاق الحاوية مع البرنامج النصي || ملف عامل ميناء؟

حسنًا ، آخذ هذا المثال ، إنه ما استخدمته لنشر بيئة اختبار التطبيق في عملية CI.

rabbitmq:
    image: rabbitmq:3.5.1-management
    environment:
        RABBITMQ_NODENAME: rabbit
    hostname: rabbitmq
    domainname: domain.lan
    volumes:
        - /data/rabbitmq/db:/var/lib/rabbitmq
    ports:
        - "5672:5672" 
        - "15672:15672"
        - "25672:25672"
        - "4369:4369"

mongodb:
    image: mongo:3.0.2
    hostname: mongo
    domainname: domain.lan
    volumes:
        - /data/mongodb:/data
    ports:
        - "27017:27017" 

appmaster:
    image: appmaster
    hostname: master
    domainname: domain.lan
    environment:
        ...
    ports:
        - "80:80" 
        - "8080:8080"
    links:
        - mongodb
        - rabbitmq

celery:
    image: celery
    hostname: celery
    domainname: domain.lan
    environment:
        ...
    links:
        - rabbitmq

بعد بدء الحاوية ، يجب أن أقوم بتوفير mongodb وإدارة قائمة الانتظار والحساب في rabbitmq

ما أفعله اليوم هو سيناريو به:

#!/bin/bash
PROJECT=appmaster
docker-compose -f appmaster.yml -p appmaster up -d
docker exec appmaster_rabbitmq_1 rabbitmqctl add_user user password
docker exec appmaster_rabbitmq_1 rabbitmqctl add_vhost rabbitmq.domain.lan
docker exec appmaster_rabbitmq_1 rabbitmqctl set_permissions -p rabbitmq.domain.lan password ".*" ".*" ".*"
docker exec appmaster_mongodb_1 mongodump --host mongo-prd.domain.lan --port 27017 --out /data/mongodb/dumps/latest
docker exec appmaster_mongodb_1 mongorestore -d database /data/mongodb/dumps/latest/database

باستخدام تعليمات onrun يمكنني الحصول على docker-compose -f appmaster.yml -p appmaster up -d
ويصبح ملف yml أكثر قابلية للقراءة

rabbitmq:
    ...
    onrun:
        - rabbitmqctl add_user user password
        - rabbitmqctl add_vhost rabbitmq.domain.lan
        - rabbitmqctl set_permissions -p rabbitmq.domain.lan password ".*" ".*" ".*"

mongodb:
    ...
    onrun:
        - mongodump --host mongo-prd.domain.lan --port 27017 --out /data/mongodb/dumps/latest
        - mongorestore -d database /data/mongodb/dumps/latest/database

قد يكون هذا مفيدًا إلى حد ما ويحل حالة الاستخدام.

: +1:

سيجعل استخدام docker-compose أكثر قابلية للتطبيق للاختبارات المسورة كجزء من خط أنابيب القرص المضغوط

: +1:

هذه نسخة مكررة من # 877 و # 1341 و # 468 (وعدد قليل من الآخرين).

أعتقد أن الطريقة الصحيحة لدعم هذا هي # 1510 والسماح للأدوات الخارجية بأداء العمليات عندما تصل إلى الحدث الذي تريده.

إغلاق كنسخة

هذا من الممكن ان يكون مفيد جدا. لا أفهم حجة "أوه ، يمكنك فعل ذلك بنص باش". بالطبع يمكننا فعل ذلك بنص باش. يمكنني أيضًا أن أفعل كل ما يفعله Docker-compose بنص باش. لكن النقطة المهمة هي أن هناك ملف YAML واحد يتحكم في بيئة الاختبار الخاصة بك ويمكن نسجها باستخدام أمر بسيط docker-compose up .

ليس من اختصاص Compose القيام بكل شيء يمكن القيام به باستخدام برنامج shell script أو Makefile - علينا رسم خط في مكان ما لتحقيق التوازن بين الفائدة وتجنب الانتفاخ.

علاوة على ذلك ، تتمثل إحدى الخصائص المهمة لملف Compose في أنه قابل للتنقل عبر الأجهزة - حتى أجهزة Mac و Linux و Windows. إذا قمنا بتمكين الأشخاص من وضع أوامر shell التعسفية في ملف Compose ، فسيقل تنقلهم كثيرًا.

aanand لكي نكون منصفين ، فإن القدرة على تنفيذ docker exec لا تعني تلقائيًا عدم توافق x-plat.

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

أفهم وجهة نظركaanand. لا يبدو الأمر خارج النطاق بالنسبة لي ، نظرًا لأن docker-compose يقوم بالكثير من الأشياء نفسها التي يقوم بها المحرك العادي docker بالفعل ، مثل command ، expose ، ports ، build ، إلخ. ستؤدي إضافة وظيفة exec إلى إضافة المزيد من القوة إلى docker-compose لجعله مكانًا واحدًا حقيقيًا للإعداد حتى بيئات التطوير.

aanand المشكلة الرئيسية للعديد من devs و CI هي الحصول على بيانات قريبة جدًا من بيئة الإنتاج. مثل تفريغ من قاعدة بيانات. لقد قمت بإنشاء هذه التذكرة منذ عام واحد ولم يتحرك أي شيء في تكوين عامل الميناء.

لذلك تقترح ملف Makefile أو Bashcript فقط لتشغيل بعض exec https://github.com/docker/compose/issues/1809#issuecomment -128073224

ما أقترحه في الأصل هو onrun (أو oncreate) الذي يحافظ على العاطفة. فقط قم بالركض في البداية. إذا تم إيقاف الحاوية أو إيقافها مؤقتًا ، فلن يتم تشغيل البداية الجديدة (أو عند الإنشاء)

أخيرًا ، في مستودع git الخاص بي ، سيكون لدي ملف إنشاء وملف عامل تشغيل وملف makefile بإدارة idempotency (قد يؤدي إنشاء ملف إلى إنشاء ملف حالة). العبقري!

هناك فرق كبير بين command و expose وما إلى ذلك و exec . المجموعة الأولى هي خيارات الحاوية ، exec هي نقطة نهاية أوامر / واجهة برمجة تطبيقات. إنها وظيفة منفصلة ، وليست خيارات لوظيفة إنشاء الحاوية.

توجد بالفعل طريقتان لإنجاز ذلك باستخدام Compose (https://github.com/docker/compose/issues/1809#issuecomment-128059030). onrun موجود بالفعل. إنه command .

فيما يتعلق بالمشكلة المحددة المتمثلة في تفريغ أو تحميل البيانات من قاعدة بيانات ، فهذه مهام أكثر من نوع "سير العمل" أو "أتمتة البناء" ، والتي تتم بشكل عام في ملف Makefile. لقد كنت أقوم بعمل نماذج أولية لأداة لحالات الاستخدام تلك بالضبط تسمى dobi ، والتي تدير جميع المهام في الحاويات. كما أنه يتكامل جيدًا مع Compose. قد تكون مهتمًا بتجربته إذا لم تكن راضيًا عن Makefiles. أنا أعمل على مثال لحالة استخدام بدء / تحميل لقاعدة البيانات.

dnephin onrun ليس أمرًا بسيطًا command لأنك تفتقد إلى العاطفة.

دعنا نتخيل. create عند إنشاء الحاوية ولن يتم تنفيذ الأمر مرة أخرى (تفريغ واستعادة).

exec:
    create:
        - echo baby
    destroy:
        - echo keny
    start:
        - echo start
    stop:
        - echo bye

إذا كنت بحاجة إلى مزيد من الأمثلة:

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

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

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

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

واو أعتقد أننا وصلنا إلى أفضل سوء نية.

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

لذا يمكنك أن تضمن أننا لن نرى أبدًا عبارة "docker compose" التي كتبت في Go Inside في ملف Docker monolithic binary للحفاظ على فلسفة unix؟ https://www.orchardup.com/blog/orchard-is-joining-docker

للاستمرار في تحقيق هذا الهدف الأصلي ، ننضم إلى Docker. من بين أشياء أخرى ، سنواصل العمل على جعل Docker أفضل تجربة تطوير رأيتها على الإطلاق - سواء مع Fig أو من خلال دمج أفضل أجزاء Fig في Docker نفسه.

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

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

بعد كل ما يجب القيام به في وقت الإنشاء قد يكون مختلفًا عما هو مطلوب في وقت التشغيل ، وغالبًا ما يختلف وقت التشغيل حسب بيئة النشر ...

إنه نوع من العمل المزعج لجعل نصوصي الخارجية على دراية بما إذا كان أحدهم سينشئ أو يبدأ الحاويات ...

وهذه هي الأشياء التي يمكن أن تساعد فيها بعض خطاطيف دورة الحياة + الأوامر + متغيرات البيئة.

تراه في أطر إدارة الخدمة وأدوات التنسيق الأخرى ... لماذا لا يكون في Docker-compose؟

قد تكون مهتمًا بـ https://github.com/dnephin/dobi ، وهي أداة كنت أعمل عليها وصُممت لسير العمل.

dnephin توقف عن إرسال بأدواتك . نرى تعليقك من قبل والجواب هو نفسه. من المحتمل أن يكون Makefile / bash أفضل من "أداة تحسين عامل الإرساء".

شكرا لتعليقك البناء. لم أكن أدرك أنني قد ذكرت بالفعل dobi في هذا الموضوع منذ 8 أشهر.

إذا كنت سعيدًا بـ Makefile / bash فهذا رائع! أنا سعيد لأن مشكلتك قد تم حلها.

تمت إضافة تعليق متعلق بهذا الموضوع هنا: https://github.com/docker/compose/issues/1341#issuecomment -295300246

dnephin لهذا ، يمكن تطبيق تعليقي:

من المحزن للغاية أن هذه القضية قد أُغلقت بسبب بعض الانكسار في التطور: محبط:

أعظم قيمة لوجود عامل ميناء هو التوحيد القياسي

هذا هو بيت القصيد. إذا كان بإمكاننا كتابة ملف .sh "فقط" أو أي شيء للقيام بالمهمة دون استخدام Docker Compose ، فلماذا يوجد Docker Compose؟ :مشوش:

يمكننا أن نفهم أن هذه مهمة كبيرة ، كما قال @ shin:

للأسف ، يمثل الدعم عبئًا كبيرًا في تلك المرحلة من المشروع

:قلب:

لكن لا يمكنك قول "إنشاء نص برمجي" ما يعني "مرحبًا ، هذا صعب جدًا ، لن نجعله".

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

في # 1341 ، أرى "فقط" طريقة للكتابة بأوامر docker-compose.yml مثل nmp install والتي سيتم تشغيلها قبل أو بعد بعض الأحداث (مثل إنشاء الحاوية) ، كما تفعل مع docker exec <container id> npm install على سبيل المثال.

حالة الاستخدام

لدي صورة NodeJS مخصصة وأريد تشغيل npm install في الحاوية التي تم إنشاؤها منها ، مع docker-compose up --build .

مشكلتي هي: لم تتم إضافة رمز التطبيق في الحاوية ، بل تم تثبيته فيه مع وحدة تخزين ، محددة في docker-compose.yml :

custom-node:
    build: ../my_app-node/
    tty: true
    #command: bash -c "npm install && node"
    volumes:
     - /var/www/my_app:/usr/share/nginx/html/my_app

لذلك لا يمكنني تشغيل npm install في Dockerfile لأنه يحتاج إلى رمز التطبيق للتحقق من التبعيات. لقد وصفت السلوك هنا: http://stackoverflow.com/questions/43498098/what-is-the-order-of-events-in-docker-compose

لتشغيل npm install ، يجب علي استخدام حل بديل ، عبارة command :

command: bash -c "npm install && node"

وهو ليس نظيفًا حقًا: محبط: والذي لا يمكنني تشغيله على إصدارات Alpine (ليس لديهم Bash مثبتًا فيه).

اعتقدت أن Docker Compose سيوفر طريقة لتشغيل أوامر exec على الحاويات ، eG:

custom-node:
    build: ../my_app-node/
    tty: true
    command: node
    volumes:
     - /var/www/my_app:/usr/share/nginx/html/my_app
    exec:
     - npm install

لكنها ليست كذلك ، وأعتقد أنها مفقودة حقًا!

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

@ lucile-sticky يمكنك استخدام sh -c في جبال الألب.

يبدو أن ما تريده هو "أتمتة البناء" وهو ليس دور عامل البناء. هل نظرت إلى دوبي ؟

سؤالين:

  • لماذا هذا ليس دور Docker Compose؟
  • إذا كانت النقطة هي أن يكون لديك أداة واحدة فقط للحكم عليهم جميعًا ، فلماذا أستخدم أداة أخرى لإكمال مهمة لا يستطيع Docker Compose القيام بها؟

هذه الميزة مطلوبة بشدة!

@ lucile- لزجة

لماذا هذا ليس دور Docker Compose؟

لأن دور Compose محدد بوضوح ولا يشمل تلك الوظائف.

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

إذا كان الهدف هو امتلاك أداة واحدة فقط للحكم عليهم جميعًا ، فلماذا أستخدم أداة أخرى لإكمال مهمة لا يستطيع Docker Compose القيام بها؟

لا نريد أن نكون الأداة الوحيدة لحكمهم جميعًا. نحن نتبع فلسفة UNIX ونؤمن بـ "جعل كل برنامج يقوم بعمل واحد بشكل جيد. للقيام بعمل جديد ، قم بالبناء من جديد بدلاً من تعقيد البرامج القديمة عن طريق إضافة ميزات جديدة."
لا بأس في الاختلاف مع هذه الفلسفة ، ولكن هذه هي الطريقة التي نطور بها في Docker البرمجيات.

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

@قصبة-

لا يمكنك فصل "إنشاء" و "توفير" في أدوات التنسيق.

على سبيل المثال ، قد تعرف أحدهم:

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

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

فلسفة يونكس؟ اسمحوا لي أن أضحك. أشير إلى نفس الإجابة التي قمت بها في هذا العدد https://github.com/docker/compose/issues/1809#issuecomment -237195021.
دعونا نرى كيف ستتطور "moby" في فلسفة Unix.

@ shin- docker-compose لا تلتزم بفلسفة Unix بأي شكل من الأشكال. إذا التزم عامل الإرساء بفلسفة يونكس ، فستكون هناك أوامر منفصلة لكل من الإنشاء ، والتركيب ، والتشغيل ، والبدء ، والتوقف ، وما إلى ذلك ، وسيكون لكل منها أمر قابل للاستخدام ، و stdout ، و stderr يتصرف باستمرار. يقول مسؤول نظام يونكس الذي يتمتع بخبرة تزيد عن 20 عامًا بما في ذلك System V و HP-UX و AIX و Solaris و Linux

دعنا نعود إلى النظرة العامة للتأليف

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

في النهاية ، يعد docker-compose أداة تنسيق لإدارة مجموعة من الخدمات بناءً على الحاويات التي تم إنشاؤها من صور عامل الإرساء. وظائفها الأساسية هي "إنشاء" و "بدء" و "إيقاف" و "مقياس" و "إزالة" الخدمات المحددة في ملف docker-compose.yml.

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

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

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

في نهاية اليوم ، هناك حاجة حقيقية يتم التعبير عنها من قبل مستخدمي Docker - aanand ، dnephin ، @ shin- يبدو أنهم يرفضونها. سيكون من الجميل أن نرى هذا مدرجًا في خارطة الطريق.

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

أعتقد أن هذا سيكون مفيدًا جدًا!

بالنسبة لي ، المشكلة هي أنه عندما يكون هناك حاوية تطبيق ، فإن الخدمة قيد التشغيل "أ" تعتمد على خدمة تشغيل حاوية db ب. ثم تفشل الحاوية ما لم يتم إعدادها.
أفضل استخدام صور Docker hub بدلاً من إعادة كتابة ملفات Dockerfiles الخاصة بي. لكن هذا يعني فشل A وعدم إنشاء حاوية. الخيار الوحيد خلاف ذلك هو

  1. استخدم B كصورة أساسية وقم بإنشاء Dockerfile الخاص بي.
  2. دع A يفشل وقم بتكوين b في البرنامج النصي وأعد تشغيل A.

لدي بالضبط نفس حالة الاستخدام مثل @ lucile-sticky.

lekhnath لحالتي ، لقد قمت بحلها عن طريق تحرير الخيار command في docker-compose.yml :

command: bash -c "npm install && node"

لكنها TT قبيحة جدا

@ lucile-sticky تجدر الإشارة إلى أن هذا يلغي أي أمر تم تعيينه في Dockerfile للحاوية. لقد عملت على حل هذه المشكلة عن طريق تثبيت برنامج نصي مخصص للقشرة باستخدام volumes ، مما يجعل command في ملف Docker Compose الخاص بي يقوم بتشغيل هذا البرنامج النصي ، وتضمينه CMD الأصلي من Dockerfile .

لماذا تم إغلاق هذه القضية؟ _كتابة نص bash_ أو _استخدام هذه الأداة التي كتبتها_ ليس سببًا صالحًا لإغلاق هذه المشكلة.

هذه ميزة مفيدة ومهمة للغاية وهي مطلوبة في كثير من الحالات التي يتم فيها استخدام الإنشاء.

dnephin هل تعتقد أن تشغيل البرامج النصية الخاصة بـ init خارج نطاق عمليات نشر التطبيقات القائمة على الحاوية؟ بعد كل شيء ، الإنشاء هو حول "تحديد وتشغيل التطبيقات متعددة الحاويات باستخدام Docker".

اطلب من شخص ما النظر إلى دوبي إذا لم تكن قد فعلت ذلك من فضلك هنا :)
image

لم يحدث شيء مع هذا التخمين. أود أن أرى نوعًا من الوظائف داخل ملف docker-compose حيث يمكننا كتابة متى يجب تنفيذ أمر ما مثل المثال الذي قدمه @ ahmet2mir .

حزين جدا لرؤية هذه الميزة لا يتم تنفيذها.

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

إنه لأمر لا يصدق أنه لم يتم تنفيذ هذه الميزة حتى الآن!

هذا نموذج سيئ للغايةdnephin. لقد أعاقت تنفيذ مثل هذه الميزة المرغوبة للغاية لما يبدو أنه ترويج ذاتي ، ولا ترغب حتى في مواصلة المحادثة.

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

أوه ، لنجعلها unix-way إذن.
_Just_ (تعدد الإرسال ثم) أنبوب docker-compose up stdin لكل حاوية ' CMD ؟
بحيث يكون هذا ملف yaml

services:
  node:
    command: sh -

سيجعل هذا يعمل: cat provision.sh | docker-compose up
الحاويات لأشياء uting عمال التنفيذ، وأنا لا أرى بشكل أفضل من ستدين من تمرير الأوامر على طول.

يمكن أن يكون البديل:

services:
  node:
    localscript: provision.sh

على الرغم من أنها تتمحور حول الصدفة قليلاً من شأنها أن تحل 99 ٪ من حالات استخدام التزويد.

على الرغم من وجود حالات استخدام صالحة ، والكثير من الأصوات المؤيدة لذلك ... لا يزال يتم رفضه على ما يبدو. عار كما أنا ، مثل كثيرين هنا ، سوف أجد هذا مفيد للغاية.

إضافة +1 إلى المجموعة الكبيرة من + الموجودة

... +1 هنا آخر!

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

+1 +1

أثناء انتظاري لهذه الميزة ، أستخدم البرنامج النصي التالي لأداء مهمة مماثلة:

docker-start.sh

#!/usr/bin/env bash

set -e
set -x

docker-compose up -d
sleep 5

# #Fix1: Fix "iptable service restart" error

echo 'Fix "iptable service restart" error'
echo 'https://github.com/moby/moby/issues/16137#issuecomment-160505686'

for container_id in $(docker ps --filter='ancestor=reduardo7/my-image' -q)
  do
    docker exec $container_id sh -c 'iptables-save > /etc/sysconfig/iptables'
  done

# End #Fix1

echo Done

@ reduardo7 ثم يمكنك أيضًا إسقاط عامل عامل

omeid ، أنت على حق! آسف ، إنه حل بديل لأداء مهمة مماثلة!

@ reduardo7 لا داعي للاعتذار ، فربما يكون ما نشرته مفيدًا لبعض الأشخاص.
كنت أشير للتو إلى أن الإصدار الأصلي لا يزال قائمًا ولا ينبغي إغلاقه. :)

أنا أفهم مواقفdnephin ، يمكن استبدال الوظائف المذكورة هنا بميزات مختلفة بما فيه الكفاية.

ومع ذلك ، إذا تم استخدام هذه الأنماط بشكل متكرر ، فماذا عن تقديم دليل (أو اختبار ما) بحيث يمكن للآخرين استخدامه بسهولة؟

يبدو أنه لا يوجد خلاف على أنه يمكن استخدام هذا النمط بشكل متكرر.

MaybeS الخلاف الوحيد هو أن dnephin بدلاً من رؤية أداة

omeid نعم بالفعل.

مثال اليوم عن الرغبة في طريقة للتأليف لعمل شكل من أشكال onrun

version: "3.3"
services:
  gitlab:
    image: 'gitlab/gitlab-ce:latest'
    restart: always
    hostname: 'gitlab'
    environment:
      GITLAB_OMNIBUS_CONFIG: |
        # NOTE: this URL needs to be right both for users, and for the runner to be able to resolve :() - as its the repo URL that is used for the ci-job, and the pull url for users.
        external_url 'http://gitlab:9090'
        gitlab_rails['gitlab_shell_ssh_port'] = 2224
    ports:
      - '9090:9090'
      - '2224:22'
  gitlab-runner:
    image: gitlab/gitlab-runner:latest
    volumes:
    - /var/run/docker.sock:/var/run/docker.sock

وبالطبع ، العداء غير مسجل - ولكي نفعل ذلك ، نحتاج إلى ذلك

  1. سحب الرمز المميز من قاعدة البيانات في gitlab
  2. قم بتشغيل التسجيل في حاوية عداء

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

export GL_TOKEN=$(docker-compose exec -u gitlab-psql gitlab sh -c 'psql -h /var/opt/gitlab/postgresql/ -d gitlabhq_production -t -A -c "SELECT runners_registration_token FROM application_settings ORDER BY id DESC LIMIT 1"')
docker-compose exec gitlab-runner gitlab-runner register -n \
  --url http://gitlab:9090/ \
  --registration-token ${GL_TOKEN} \
  --executor docker \
  --description "Docker Runner" \
  --docker-image "docker:latest" \
  --docker-volumes /var/run/docker.sock:/var/run/docker.sock \
  --docker-network-mode  "network-based-on-dirname-ew_default"

ط ط ط ، قد أكون قادرًا على اختراق شيء ما ، حيث لدي حاوية أخرى بها مقبس عامل الإرساء ، و docker exec's

ما هو الرهان هناك طريقة ....

على سبيل المثال ، يمكنني إضافة:

  gitlab-initializer:
    image: docker/compose:1.18.0
    restart: "no"
    volumes:
    - /var/run/docker.sock:/var/run/docker.sock
    - ./gitlab-compose.yml:/docker-compose.yml
    entrypoint: bash
    command: -c "sleep 200 && export GL_TOKEN=$(docker-compose -p sima-austral-deployment exec -T -u gitlab-psql gitlab sh -c 'psql -h /var/opt/gitlab/postgresql/ -d gitlabhq_production -t -A -c \"SELECT runners_registration_token FROM application_settings ORDER BY id DESC LIMIT 1\"') && docker-compose exec gitlab-runner gitlab-runner register -n --url http://gitlab:9090/ --registration-token ${GL_TOKEN} --executor docker --description \"Docker Runner\" --docker-image \"docker:latest\" --docker-volumes /var/run/docker.sock:/var/run/docker.sock --docker-network-mode  \"simaaustraldeployment_default\""

إلى ملف الإنشاء - على الرغم من أنني بحاجة إلى نوع من التكرار / الانتظار ، لأن gitlab ليس جاهزًا على الفور - قد لا يكون sleep 200 كافيًا.

لذلك - يمكنك __يمكنك__ اختراق نوع من الأنماط مثل هذا مباشرةً بـ docker-compose.yml - لكن شخصيًا ، أفضل دعمًا أكثر نظافة من هذا :)

SvenDowideit onrun موجود بالفعل ، إنه entrypoint أو cmd .

يوفر البرنامج النصي لنقطة الدخول لهذه الصورة وسيلة ربط لك. يمكن تعيين $GITLAB_POST_RECONFIGURE_SCRIPT على مسار البرنامج النصي الذي سيتم تشغيله بعد اكتمال الإعداد بالكامل (انظر /assets/wrapper في الصورة). اضبط متغير env على مسار البرنامج النصي الذي يقوم بتسجيل psql + وستكون جاهزًا.

حتى لو لم توفر الصورة هذا الخطاف ، يمكن إضافته بسهولة إلى حد ما عن طريق توسيع الصورة.

على الرغم من أنني بحاجة إلى نوع من التكرار / الانتظار ، لأن gitlab ليس جاهزًا على الفور - قد لا يكون النوم 200 كافيًا.

سيكون هذا ضروريًا حتى مع خيار "exec-after-start". نظرًا لأن البرنامج النصي لنقطة الإدخال يوفر فعليًا خطافًا ، أعتقد أنه ربما ليس ضروريًا مع هذا الحل.

كلا ، (أعتقد) أنك فاتتك جزءًا من المشكلة التي أعرضها:

في حالتي ، أحتاج إلى الوصول إلى كلتا الحاوية ، وليس واحدة فقط - لذا فإن نقطة الدخول / الأمر لا يعطيني هذا.

GL_TOKEN من حاوية gitlab ، ثم يتم استخدامه في حاوية gitlab-runner للتسجيل.

لذا فإن الاختراق الذي أقوم به هو استخدام صورة docker/compose لإضافة حاوية ثالثة - هذا ليس شيئًا يمكنك تعديل config / entrypoint / settings له في حاوية واحدة ، وهو تمامًا مثال (تافه) على تنسيق متعدد الحاويات يحتاج إلى المزيد.

لقد كنت أعمل على أشياء لجعلها أكثر سحرية - مما يعني بشكل أساسي أن حاوية التهيئة الخاصة بي بها بعض حلقات النوم ، حيث يستغرق الأمر بعض الوقت حتى يبدأ gitlab نفسه.

TBH ، لقد بدأت أشعر أن استخدام نص برمجي ، يعمل في init-container تستخدم ملف الإنشاء نفسه و docker / compose image ، _ هو الطريقة الصحيحة لإخفاء هذا النوع من التعقيد - لغير الإنتاج "حاول أنا خارج ، وسيعمل فقط "مثل هذه المواقف.

_IF_ كنت سأفكر في بعض السكر النحوي الغريب للمساعدة ، ربما سأختار شيئًا مثل:

gitlab-initializer:
    image: docker/compose:1.18.0
    restart: "no"
    volumes:
    - /var/run/docker.sock:/var/run/docker.sock
    - ./gitlab-compose.yml:/docker-compose.yml
    entrypoint: ['/bin/sh']
    command: ['/init-gitlab.sh']
    file:
      path: /init-gitlab.sh
      content: |
            for i in $(seq 1 10); do
                export GL_TOKEN=$(docker-compose -f gitlab-compose.yml -p sima-austral-deployment exec -T -u gitlab-psql gitlab sh -c 'psql -h /var/opt/gitlab/postgresql/ -d gitlabhq_production -t -A -c "SELECT runners_registration_token FROM application_settings ORDER BY id DESC LIMIT 1"')
                echo "$i: token($?) == $GL_TOKEN"
                ERR=$?

                if [[ "${#GL_TOKEN}" == "20" ]]; then
                    break
                fi
                sleep 10
            done
            echo "GOT IT: token($ERR) == $GL_TOKEN"

            for i in $(seq 1 10); do
                if  docker-compose -f gitlab-compose.yml  -p sima-austral-deployment exec -T gitlab-runner \
                    gitlab-runner register -n \
                    --url http://gitlab:9090/ \
                    --registration-token ${GL_TOKEN} \
                    --executor docker \
                    --description "Docker Runner" \
                    --docker-image "docker:latest" \
                    --docker-volumes '/var/run/docker.sock:/var/run/docker.sock' \
                    --docker-network-mode  "simaaustraldeployment_default" ; then
                        echo "YAY"
                        break
                fi
                sleep 10
            done

على سبيل المثال ، مثل cloud-init: http://cloudinit.readthedocs.io/en/latest/topics/examples.html#writing -out-optary-files

ولكن عندما يتعلق الأمر بذلك - فنحن _لدينا_ حلاً لتنسيق الأشياء المعقدة متعددة الحاويات من داخل docker-compose-yml.

إذا كنت قادرًا على تعيين رمز محدد مسبقًا ، فيمكنك القيام بذلك من برنامج نصي لنقطة الإدخال في gitlab-runner . ألا توجد طريقة لتحديد رأس الوقت؟

dnephin في اللحظة التي تذكر فيها البرنامج النصي ، تكون بعيدًا عن العلامة بسنة ضوئية ثم بعض.

onrun ليس هو نفسه entrypoint أو cmd .

entrypoint / cmd مخصص لتكوين الملف القابل للتنفيذ الذي سيعمل كحاويات init / PID 1.

الفكرة المذكورة في هذه القضية والعديد من القضايا ذات الصلة تدور حول init scripts ، والتي تختلف عن init في سياق التمهيد ، وتتعلق بنصوص بدء التطبيق ، فكر في إعداد قاعدة البيانات.

dnephin من المحتمل أن يكون أكثر فائدة إذا ركزت على مجموعة المشكلات العامة ، بدلاً من محاولة حل مشكلات مجموعة حاوية معينة.

من خلال ما رأيته ، لا ، إنه سر تم إنشاؤه - ولكن في الواقع ، ليس هذا هو المطلب الوحيد للتنسيق متعدد الحاويات في نظام اللعب الصغير هذا الذي من المحتمل أن يتوفر - إنه الأسرع بالنسبة لي النموذج الأولي في الأماكن العامة.

كيف يمكن أن نكون قادرين على تجاوز entrypoint و command في ملف إنشاء منذ الإصدار 1 (https://docs.docker.com/compose/compose-file/compose-file -v1 / # entrypoint) وما زلت لا تملك توجيهًا مثل onrun لتشغيل أمر عندما تكون الحاويات جاهزة؟

TBH ، لا أعتقد حقًا أن onrun معقول - Docker ، أو المنسق لا يعرف معنى "الحاويات كلها جاهزة" - في إحدى حالاتي ، سيفشل HEALTHCHECK ، إلا بعد أن أفعل بعض "الأشياء" الإضافية حيث أحصل على معلومات من حاوية ، وأستخدمها لطرد بعض الأشياء الأخرى في حاويات أخرى.

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

وهذا يبدو لي وكأنه الوظيفة التي يتم حلها بشكل أفضل (في تكوين عامل الميناء) عن طريق حاوية تكوين عامل ميناء مع رمز.

من المحتمل أن ألعب مع كيفية تحويل هذا المشغل بعد ذلك إلى شيء يمكنه التعامل مع مكدسات أسراب الرصيف (بسبب احتياجات المشروع الأخرى).

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

من الواضح أن المطورين لا يريدون الاستماع إلى المستخدمين .. سألقي نظرة على أداة أخرى ... عامل الإرساء يمثل ألمًا كبيرًا .. لا أفهم لماذا لا تفهم أن الشيء الوحيد المفيد الذي يأتي من docker-composer هي أداة بناء ... قضيت الكثير من الوقت في البحث عن كيف يمكنني تشغيل أمر SIMPLE لإضافة أذونات داخل الحاوية إلى مستخدم نشط ..

يبدو أن عامل الإرساء لم يفعل ببساطة حالة ...

أنا أيضًا أريد شيئًا من شأنه أن يكون onrun في ملف الإنشاء الخاص بي

__BUT__ ، لا توجد طريقة لمعرفة معنى onrun ، فلا حاويات ولا إنشاء. هذا هو سبب وجود نمط المشغل ولماذا قمت بعمل الأمثلة في https://github.com/docker/compose/issues/1809#issuecomment -362126930

من الممكن __إمكانية القيام بذلك اليوم - في الأساس ، يمكنك إضافة خدمة onrun تنتظر حتى تصبح أي خدمات أخرى جاهزة بالفعل للتفاعل معها (في حالة gitlab ، يستغرق ذلك وقتًا طويلاً) ، ثم قم بذلك كل ما عليك القيام به لتنسيق الأشياء.

إذا كان هناك _is_ شيء لا يعمل مع ذلك ، فيرجى إخبارنا ، وسنرى ما إذا كان بإمكاننا اكتشاف شيء ما!

أنا أيضًا أريد شيئًا سيتم تشغيله في ملف الإنشاء الخاص بي

ولكن ، لا توجد طريقة لمعرفة معنى "onrun" أو "الحاويات".

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

تم حل مشكلة الدعم عبر الأنظمة الأساسية في وقت سابق ، حيث يمكن أن يكون الأمر محايدًا تمامًا لنظام التشغيل من خلال docker exec ، بنفس الطريقة التي لا يعني بها RUN أمر linux في Dockerfile.
https://docs.microsoft.com/en-us/virtualization/windowscontainers/manage-docker/manage-windows-dockerfile

لا تزال تنتظر ميزة onrun

أحتاج إلى ميزات onrun أيضًا ، اعتقدت أنها موجودة في هذه الأداة. بسبب نقص هذه الميزة الآن ، أحتاج إلى صيانة نصين.

يا رفاق ، ماذا لو صنعت غلافًا حول هذا docker-compose وسمحت بهذه الميزة onrun ؟ هل ستستخدمونها يا رفاق؟

wongjiahau قد يكون شيء من هذا القبيل؟ https://github.com/docker/compose/issues/1809#issuecomment -348497289

@ reduardo7 نعم ، فكرت في docker-composei ، وبواسطة docker-composei.yml التي تحتوي على السمة onrun .
راجع للشغل ، docker-composei يعني docker-compose improved .

ربما يكون الحل الحقيقي هو إنشاء صورة "Orchestrator" تقوم بتشغيل وإدارة (عبر البرامج النصية bash) "صور التطبيق" (ربما باستخدام عامل ميناء) داخليًا. وإلا فإننا سنطلب دائمًا المزيد من الميزات للأداة التي "لا يُقصد منها أن تفعل ما نريدها أن تفعله".

لذلك يجب علينا حتى التفكير في Docker داخل Docker ...

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

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

في حالتي ، تقوم حاويات redis الخاصة بي بتحميل برامج lua النصية بعد بدء خادم redis. في بيئة عادية غير حاوية ، أحصل على systemd لتشغيل برنامج نصي بعد بدء التشغيل. بسيطة ومتسقة مع بنية النظام. يجب أن يوجد مبدأ مشابه للتركيب نظرًا لدوره في إعداد سياق تشغيل الحاويات.

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

لذا فإن الحل (بعد قراءة كل هذا الموضوع) هو استخدام برنامج نصي bash للقيام بالمهمة ... في هذه الحالة سأزيل docker-compose (يمكننا فعل كل شيء باستخدام docker cmd ...)

thx dev للاستماع إلى الأشخاص الذين يستخدمون أشياءك :)

من خلال رؤية كمية الرسائل التي تحتوي على الحجج والحجج المضادة التي تحارب المقترحات البسيطة (مثل وجود حدث onrun ) ،

من فضلك ، دعونا نجعل المصدر المفتوح حقا _فتح_.

أي تحديثات على هذه الميزة؟ ما المشكلة؟

@ v0lume أظن أنك لم تهتم بقراءة الردود فعليًا خلال هذه المقالة

يبدو أنه لا يوجد حل حتى الآن ... أود مشاركة حل بديل رغم ذلك.
من خلال تحديد الإصدار "2.1" في docker-compose.yml ، يمكنك إساءة استخدام اختبار healthcheck لتشغيل رمز إضافي داخل الصورة عند بدء تشغيله. هنا مثال:

version: '2.1'
services:
    elasticsearch:
        image: docker.elastic.co/elasticsearch/elasticsearch:5.4.3
        healthcheck:
            test: |
                curl -X PUT elasticsearch:9200/scheduled_actions -H "ContentType: application/json" -d '{"settings":{"index":{"number_of_shards":'1',"number_of_replicas":'0'}}}' &&
                curl --silent --fail localhost:9200/_cat/health ||
                exit 1
            interval: 11s 
            timeout: 10s 
            retries: 3
        environment:
            - discovery.type=single-node
            - ES_JAVA_OPTS=-Xms1g -Xmx1g
            - xpack.security.enabled=false
    main:
        image: alpine
        depends_on:
            elasticsearch:
                condition: service_healthy

إذا كان البرنامج النصي healthcheck-test الذي تكتبه يخرج مع الرمز> = 1 ، فقد يتم تنفيذه عدة مرات.
لن يتم تنفيذ الفحص الصحي للخدمة إلا إذا كانت خدمة أخرى تعتمد عليها وتحدد حالة service_healthy كما هو موضح في المثال.

أحب نهج @ T-vK وقد استخدمته بنجاح من قبل. لكني أرغب في مشاركة آخر ... هاك:

# Run Docker container here

until echo | nc --send-only 127.0.0.1 <PORT_EXPOSED_BY_DOCKER>; do
  echo "Waiting for <YOUR_DOCKER> to start..."
  sleep 1
done

# Do your docker exec stuff here

+1
أوافق تمامًا على هذا لأن الميزة مطلوبة وقد تم تنفيذها بالفعل بواسطة منسقي عمال الشحن الآخرين مثل kubernetes. يحتوي بالفعل على خطافات دورة حياة للحاويات وموثقة هنا .

ولكن دعني أساهم بحالة استخدام لا يمكنك حلها باستخدام Dockerfiles.

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

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

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

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

أتمنى لك كل خير.

أنا قادر على منحك كل ما تريد (باستثناء صديقتي) إذا تم تنفيذ هذه الميزة وسأكون أسعد شخص في كل الكون :)

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

سيكون ذلك لطيفًا.

للإضافة إلى ذلك ، مع مراعاة ما يلي:

services:
    web:
        image: node:8-alpine
        depends_on:
            - db
    db:
        image: postgres:alpine
        onrun: "echo hi"

هل ستكون إضافة نصوص الأحداث المتقاطعة أكثر من اللازم؟

    web:
        events:
            db_onrun: "connectAndMigrate.sh"

في رأيي ، فإن إضافة هذا إلى docker-compose أمر واضح ليس أنت وحدك ، الذي يستخدم إنشاء ملف وإنشاء مكدس ولكن أيضًا مطورين آخرين في فريقك.

  • باستخدام حاويات منفصلة - يجب أن يعلم الجميع أنه يجب عليهم تشغيلها.
  • اكتب ملف Dockerfile مخصص - لدينا حوالي 20 خدمة ولكل خدمة يجب أن أتجاوز Dockerfile لتشغيل بعض الأوامر.

نحتاج إلى تثبيت وتهيئة mkcert ، على سبيل المثال ، في كل بيئة للحصول على شهادات موثوقة. إنه ليس جزءًا من الحاوية أو Dockerfile لأنه غير ضروري على المسرح / الإنتاج. ما هي الطريقة الصحيحة هنا لتثبيت الأداة وكل شخص يستخدم إنشاء الملف حتى أنه ليس لديه أدنى فكرة عما يحدث وراء الكواليس؟

إضافة حالة استخدام أخرى:

مطلوب مثيل وورد. كتب رسالتي يؤلف. yaml. docker-compose up - عفوًا! تحتاج إلى تعيين أذونات ملف دليل المكونات الإضافية ... لا يمكن العثور على أي طريقة أخرى لجعلها تعمل ، يجب تعيين الأذونات بعد تشغيل الحاوية لأنني أقوم بربط بعض الملفات من المضيف ويبدو أن الطريقة الوحيدة لإصلاح أذونات fs يتم تنفيذ chown -Rf www-data.www-data /var/www/wp-content من داخل الحاوية. اكتب Dockerfile الخاص بي والبناء ، فقط من أجل هذا؟ هذا يبدو غبيا بالنسبة لي.

لحسن الحظ بالنسبة لي ، فإن اختراق healthcheck المقدم أعلاه سمح لي بتنفيذ ذلك. أرى صفحات أخرى على الويب تتحدث عن مسألة أذونات الإعدادات على وحدات تخزين عامل الإرساء ، لكن الحلول المقترحة لم تنجح.

يسعدني أن أرى حراس البوابة ، aanand ، @ shin- ، يحصلون على الكثير من الحرارة لهذا الغرض. إنها تتحدث حقًا عن مجلدات عندما يصرخ مجتمع بأكمله بصوت عالٍ قدر الإمكان ، ويجلس المطورون الأساسيون ويثبتون موقفهم ويرفضون الاستماع. نموذجي جدا جدا. دعونا نحسب ليس فقط عدد الإعجاب ، ولكن أيضًا 34 مستخدمًا ردوا بالقول إن هذا ضروري:
01) شيشوف
02) فيسكوبار
03) ساندور 11
04) ويب تيد
05) v0lume
06) ويببوليس
07) Skull0ne
08) usergoodvery
09) وونغجياهاو
10) MFQ
11) يوسفرو
12) باكرمن
13) دقسم
14) أميد
15) دانتيباربا
16) ويلي يانغ
17) SharpEdgeMarshall
18) فقد الحامل
19) شبح
20) Rodrigorodriguescosta
21) datatypevoid
22) دكسترمب
23) لخناته
24) لوسيل-لزج
25) rav84
26) دوبي
27) ahmet2mir
28) مونتيرا 82
29) ديسكورديانفيش
30) جاسونرهاس
31) فيراريس
32) هايبرجيج
33) صلى الله عليه وسلم
34) شذبة

وعدد الذين قالوا لا؟ ضخم 3:
01) دنيفين
02) أناند
03) شين-

هممم ... 34 إلى 3 ...

@ rm-rf-etc تحليلات جيدة ... لا أعتقد حتى أن dnephin أو aanand يعملان على

إضافة حالة استخدام أخرى:

مطلوب مثيل وورد. كتب رسالتي يؤلف. yaml. docker-compose up - عفوًا! تحتاج إلى تعيين أذونات ملف دليل المكونات الإضافية ... لا يمكن العثور على أي طريقة أخرى لجعلها تعمل ، يجب تعيين الأذونات بعد تشغيل الحاوية لأنني أقوم بربط بعض الملفات من المضيف ويبدو أن الطريقة الوحيدة لإصلاح أذونات fs يتم تنفيذ chown -Rf www-data.www-data /var/www/wp-content من داخل الحاوية.

في هذه الحالة ، يمكنك أيضًا تعيين الخاصية user في ملف الإنشاء

اكتب Dockerfile الخاص بي والبناء ، فقط من أجل هذا؟ هذا يبدو غبيا بالنسبة لي.

يبدو أنك كونت رأيًا قويًا ؛ ولكن من الناحية الواقعية ، لن يكون هناك شيء "غبي" حول كتابة Dockerfile لتعديل صورة أساسية لتناسب احتياجاتك. هذا هو الهدف الأصلي لجميع الصور الأساسية.

لحسن الحظ بالنسبة لي ، أتاح لي اختراق healthcheck المقدم أعلاه تنفيذ ذلك. أرى صفحات أخرى على الويب تتحدث عن مسألة أذونات الإعدادات على وحدات تخزين عامل الإرساء ، لكن الحلول المقترحة لم تنجح.

يسعدني أن أرى حراس البوابة ، aanand ، @ shin- ، يحصلون على الكثير من الحرارة لهذا الغرض.

نعم ، حسن الخلق يا صديقي. :د


@ rm-rf-etc تحليلات جيدة ... لا أعتقد حتى أن dnephin أو aanand يعملان على

نعم ، لقد مرت بضع سنوات حتى الآن - لا داعي للاستمرار في إرسال رسائل إليهم بشأن المشكلات القديمة.

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

🙄

@ shin- لكنك فقط أزعجت ذلك الرد

لقد واجهت هذه المشكلة مؤخرًا مرة أخرى وعلى الرغم من أنه يمكن إجراؤها كما رأينا في الحل البديل الخاص بي ، إلا أن هذا لا يعمل إلا إذا حددت 2.1 ، والذي ينتن imo.

إنه أمر محير بالنسبة لي أن الموقف الرسمي يبدو أنه يجب عليك إنشاء صور عامل الإرساء الخاصة بك لكل شيء.
بالنسبة لي ، هذا يشبه قول "إذا كنت تريد تغيير إعداد في أي برنامج ، عليك تعديل شفرة المصدر وإعادة تجميعها.".
في كل مرة تضيف فيها خدمة جديدة أو تريد الترقية إلى إصدار أحدث من .. على سبيل المثال صورة MongoDB أو MySQL Docker ، يجب عليك إنشاء Dockerfile جديد وإنشائه وربما دفعه إلى السجل الخاص بك.
يعد هذا مضيعة هائلة للوقت والموارد مقارنة بما سيكون عليه الحال إذا كان بإمكانك تغيير image: mongo:3.0.2 إلى image: mongo:3.0.3 في docker-compose.yml.
أنا لا أتحدث عن أوقات الإنشاء الطويلة ، فأنا أصرخ بشأن حقيقة أنه يتعين عليك أن تهتم بملفات Dockerfiles و docker build عندما يكون كل ما تريده هو تحديث أو تغيير معلمة خدمة من المحتمل ألا تكون من المفترض أن تستخدم كصورة أساسية.

والحجة القائلة بأن كل تطبيق يجب أن يفعل شيئًا واحدًا وشيئًا واحدًا فقط ، هو حجة كريهة أيضًا. هذا لا يتعلق حتى بتطبيق ميزة جديدة تمامًا ، بل يتعلق فقط بتمرير معامل آخر إلى docker . هذا يطرح أيضًا السؤال عن سبب كون كل من docker run و docker build و docker exec و docker pull إلخ جزءًا من نفس التطبيق. الحجة تبدو نوعًا من النفاق الآن ، أليس كذلك؟

@ shin- ، لقد اتبعت الرابط الخاص بك ولا أرى كيف تكون خاصية المستخدم ذات صلة بتعيين مالك دليل مُثبت. يبدو أنه مرتبط بالموانئ.

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

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

يبدو أن العودة إلى ملفات عامل الإرساء لتحديث كل منها بنص منفصل للميزات زائدة عن الحاجة. أريد فقط حقن رمز من حاوية أخرى في متغير بيئة حيث كان ملف Dockerfile الخاص بي مرنًا من قبل مقترنًا بإحكام بـ docker-composer.yml والحل لغرض بسيط.

اللعنة ، لقد قرأت الموضوع بأكمله وهو يقفز للعثور على الإجابة "حسنًا يا رفاق ، أدركنا أخيرًا أن هذا رائع وسنقوم بتنفيذه". من المحزن أن نرى أن هذا لم يتحرك إلى الأمام.
+1 للتشغيل!

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

نستخدم المرساة التالية

#### configure a service to run only a single instance until success
x-task: &task
  # for docker stack (not supported by compose)
  deploy:
    restart_policy:
      condition: on-failure
    replicas: 1
  # for compose (not supported by stack)
  restart: on-failure

لتكرار المهام حتى تنجح. نقوم بإنشاء حاويات لعمليات الترحيل ومهام الإعداد التي لها نتائج ثابتة ونقوم بتشغيلها على هذا النحو في تكويننا المحلي وفي مجموعاتنا.

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

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

fabiomolinar ، هذا مثال على كيفية استخدامنا لهذا النهج في خدمات التأليف لدينا ...

#### configure a service to run only a single instance until success
x-task: &task
  # for docker stack (not supported by compose)
  deploy:
    restart_policy:
      condition: on-failure
    replicas: 1
  # for compose (not supported by stack)
  restart: on-failure

#### configure a service to always restart
x-service: &service
  # for docker stack (not supported by compose)
  deploy:
    restart_policy:
      condition: any
  # for compose (not supported by stack)
  restart: always

services: 
  accounts: &accounts
    <<: *service
    image: internal/django
    ports:
      - "9000"
    networks:
      - service
    environment:
      DATABASE_URL: "postgres://postgres-master:5432/accounts"
      REDIS_URL: "hiredis://redis:6379/"

  accounts-migrate:
    <<: *accounts
    <<: *task
    command: ./manage.py migrate --noinput

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

CMD set -m; server $ deploy && fg server

يقوم السطر أعلاه بتعيين وضع شاشة bashes قيد التشغيل ، ثم يبدأ عملية server في الخلفية ، ثم يقوم بتشغيل عملية deploy وأخيراً يتم إحضار عملية server في المقدمة مرة أخرى لتجنب قتل الحاوية Docker .

أثناء مناقشة هذا الأمر ، لدى أي شخص أي نصيحة حول كيفية تشغيل أمر على الحاوية أو المضيف عند تشغيل docker-compose up ؟

أتفهم أن تشغيل أي أمر على المضيف من شأنه أن يضر بطبقات الأمان ، لكنني أود فقط rm دليل قبل أو أثناء بدء تشغيل الحاوية. يمكن الوصول إلى الدليل على كل من المضيف والحاوية. لا أريد إنشاء صورة Docker مخصصة أو أن يكون لدي برنامج نصي يقوم أولاً بـ rm ثم تشغيل docker-compose .

شكر!

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

بعض المشاكل التي يمكن أن تنشأ من نهجك

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

لقد وجدت النهج الذي أوصي به غير بديهي في البداية. لقد نجحت بشكل جيد في الممارسة العملية في بيئات التنمية المحلية لدينا في ظل مجموعات عمال البناء ، وأسراب عمال الرصيف ، ومجموعات mesos / marathon. إنه يعمل أيضًا بشكل فعال حول عدم وجود "onrun".

النهج الذي استخدمته هو في الواقع قبيح للغاية. لقد استخدمته لفترة من الوقت فقط لتشغيل بيئة التطوير الخاصة بي. لكنني قمت بتغيير ذلك بالفعل لاستخدام البرامج النصية لنقاط الإدخال والأمر at لتشغيل البرامج النصية بعد تشغيل الخادم. الآن الحاوية الخاصة بي تعمل بالعملية الصحيحة مثل PID 1 وتستجيب لجميع الإشارات بشكل صحيح.

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

@ victor-perov قم بإنشاء حاوية أخرى لمهمة التجميع وتنفيذها كخدمة منفصلة

فيما يلي بعض المقتطفات من أحد مشاريعنا لإظهار خدمة مهمة لتشغيل ترحيل قاعدة البيانات.

x-task: &task
  # run once deploy policy for tasks
  deploy:
    restart_policy: 
      condition: none
    replicas: 1

service:
  automata-auth-migrate:
    <<: *automata-auth
    <<: *task
    # without the sleep it can't lookup the host postgres.  maybe the command is ran before the network set is complete.
    command: sleep 5 && python /code/manage.py migrate --noinput

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

أنا أيضًا أعتقد أن onrun أو ما يعادله (بعد التشغيل؟) أمر لا بد منه. إن إضافة برنامج نصي مغلف وتنفيذ Docker exec في الحاوية هو مجرد ... قبيح.

كان إنشاء IMO docker بمثابة MVP لتنسيق الحاويات رائعًا لإقناع الناس بأن إدارة الحاويات يمكن أن تكون سهلة. ربما يجب علينا ، كمجتمع ، أن نعتبره في "وضع الصيانة" حيث انتشرت حلول تنسيق جاهزة للإنتاج (مثل kubernetes). عندما تكون لديك ميزات متقدمة مثل تبعيات الحاوية ، جنبًا إلى جنب مع ميزات غائبة مثل "تنفيذ هذا الشيء بعد تشغيل الحاوية" ، يبدو أنها تتناسب مع السرد القائل بأن وتيرة التطوير قد استقرت ببساطة. على أقل تقدير ، ليس من الواضح أن هذه الميزة _يجب اعتبارها _ خارج النطاق.

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

  • تغيير Dockerfile من mysql وإضافة البرنامج النصي الخاص بك إلى الحاوية قبل نقطة الإدخال. لا يمكنك إضافة CMD في Dockerfile ، لأنها ستكون وسيطة لـ ENTRYPOINT .
  • يمكنك تشغيل الحاوية ثم نسخ البرنامج النصي الخاص بك إلى الحاوية قيد التشغيل وتشغيله [ docker cp ، docker exec ].

لهذا السبب أعتقد أيضًا أن ميزة مثل onrun مفيدة لأن تغيير Dockerfile لا يكفي دائمًا.

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

somebi يبدو أن تأليف مغلق ...

فقط سنتان: لقد هبطت هنا لأنني مضطر حاليًا إلى تمكين وحدات Apache يدويًا في كل مرة أقوم فيها بتشغيل الحاوية (لم يتم تمكين SSL افتراضيًا في Docker Hub wordpress image). ليست نهاية العالم ، ولكن كان يأمل في تشغيل بعض الأوامر كلما ارتفعت حتى أتمكن من نقل الحاويات لأعلى ولأسفل بسلاسة دون الاضطرار إلى الدخول.

فقط سنتان: لقد هبطت هنا لأنني مضطر حاليًا إلى تمكين وحدات Apache يدويًا في كل مرة أقوم فيها بتشغيل الحاوية (لم يتم تمكين SSL افتراضيًا في Docker Hub wordpress image). ليست نهاية العالم ، ولكن كان يأمل في تشغيل بعض الأوامر كلما ارتفعت حتى أتمكن من نقل الحاويات لأعلى ولأسفل بسلاسة دون الاضطرار إلى الدخول.

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

FROM wordpress:php7.1
RUN a2enmod ssl

الحل الآخر هو تنزيل ملف Wordpress Dockerfile وإضافة تنشيط الوحدة فيه. ثم قم بإنشاء صورة جديدة لنفسك باستخدام بناء عامل ميناء. على سبيل المثال ، هذا هو Dockerfile لـ wordpress 5.2 مع php 7.1:

Wordpress dockerfile

يمكنك تمكين المزيد من الوحدات النمطية في السطر 63 أو تشغيل إنشاء ssl.

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

سيكون هذا إضافة لطيفة إلى عامل البناء!

الإجابات مثل تلك الموجودة في هذا الموضوع هي السبب في أن Kubernetes تحتفظ بـ "كل" الأموال التي تنتجها Docker (التكنولوجيا) ، وهذا ليس بالأمر السيئ ، ونأمل أن يشتري شخص ما Docker (الشركة) قريبًا ويغير طريقة ترحيب مقترحات المجتمع / الطلبات / تحليل ...

الإجابات مثل تلك الموجودة في هذا الموضوع هي السبب في احتفاظ Kubernetes بـ _ "كل" _ الأموال التي تنتجها Docker (التكنولوجيا) ، وهذا ليس بالأمر السيئ ، ونأمل أن يشتري شخص ما Docker (الشركة) قريبًا ويغير طريقة مقترحات / طلبات المجتمع مرحبًا بك / تم تحليلها ...

لقد كتبت ناقدًا مشابهًا ، دون أي بيان مسيء (كان على غرار مشاريع المصادر المفتوحة التي ليست مفتوحة المصدر تمامًا والتي يتجاهل القائمون عليها بتحدٍ الحجج دون أي سبب آخر سوى إظهار مقدار الأرجون التقني الذي يمتلكونه) ، حصل على الكثير من الدعم ، وتمت إزالة الرسالة.

هذا يدل على نوع الأشخاص المتغطرسين وراء هذا.

عندما يطلب مجتمعك شيئًا لمدة 4 سنوات وأنت (Docker) تغمض عينيك ، فهذا يدل على أنك لا تنظر في نفس الاتجاه مثلهم: /

والآن استسلم عامل الميناء وبيعه.
لأنهم لم يتمكنوا من الاستماع ... فقدوا.

عار - ولكن مهلا هو.

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

بمعنى آخر

services:
  app:
    image: myapp:latest
    hooks:
      onFailure:
        - # Call a monitoring service (from the host machine) to tell it that the service is offline.

قد يكون هذا مفيدًا في الأوقات التي لا يرتبط فيها التطبيق بمقبس / منفذ. من المحتمل أن يكون Kubernetes هو السبيل للذهاب ، هنا ، ولكن هذا تغيير كبير إلى حد ما في البنية التحتية وإفراط في بيئة صغيرة جدًا.

تعديل:
للتغلب على هذا ، انتهى بي الأمر بتحديث نقطة إدخال الحاوية الخاصة بي "لالتفاف" وظيفة المراقبة. بمعنى آخر

# /app/bin/run_with_monitor
#!/bin/bash
set -eE

updateMonitoringSystem() {
 # do something here... This is run from the container, though, unfortunately.
 if [[ $? -eq 1 ]]; then
  # Failed!
 else
  # All is good!
 fi
}

trap 'updateMonitoringSystem' EXIT

$@
# Dockerfile
....
CMD ["/app/bin/run_with_monitor", "./my-app"

ومع ذلك ، سيكون من الجيد القيام بذلك دون الحاجة إلى تعديل الصورة.

: man_shrugging: لقد بحثت عن هذه الوظيفة الأساسية التي يمتلكها المنافس (Kubernetes) ، وبدلاً من ذلك وجدت حريقًا في القمامة.

إنه لعار حقيقي ، الآن عليّ الاحتفاظ بصور منفصلة لرسو السفن للاختبار محليًا.

عام جديد سعيد: roll_eyes:

image

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

يعتمد قدر كبير من البرامج على خدمات معينة عند بدء التشغيل. على سبيل المثال قاعدة بيانات MySQL أو MongoDB.

لذلك لا توجد طريقة عقلانية لاستخدام docker-compose في هذه الحالات.

بدلاً من ذلك ، يُتوقع من المستخدمين:

  • تعرف على كيفية كتابة Dockerfiles (والبرمجة)
  • تعرف على كيفية إنشاء Docker images
  • أنشئ Dockerfiles موروثًا من الصور الأصلية ، مع إضافة كود للتأكد من أن الحاويات تنتظر بعضها البعض
  • تحقق بانتظام من التحديثات الأمنية للصور الأساسية
  • قم بتعديل Dockerfiles بانتظام لتطبيق التحديثات
  • أنشئ بانتظام Docker images من هؤلاء Dockerfiles

وهذا مقرف لأن:

  • أنت تهدر الكثير من الوقت في تعلم أشياء قد لا تحتاجها حتى بخلاف ذلك
  • أنت تهدر بانتظام موارد الأجهزة في بناء وتخزين Docker images بنفسك أو حتى عند تحميلها / تنزيلها (سحبها / دفعها)
  • أنت تضيع الوقت بانتظام في كتابة تلك Dockerfiles ، في بنائها ، واختبارها ، وإصلاحها ، إلخ ...
  • من المحتمل أن تعرض أمان صورك للخطر لأنك لا تعرف ما تفعله
  • تفقد القدرة على التشغيل فقط الذي تم التحقق منه رسميًا / توقيعه Docker images

إذا كان لدينا فحص بدء التشغيل ، فلن يكون كل هذا ضروريًا ويمكننا ببساطة تغيير image: mysql:8.0.18 إلى image: mysql:8.0.19 متى أردنا ذلك وننتهي!

من الناحية الواقعية ، هذا ما يحدث حاليًا في العالم الحقيقي:

  • يقوم الأشخاص بإنشاء Dockerfiles الخاص بهم لإجراء تغييرات حتى يعملوا مع docker-compose
  • يبنون صورهم مرة واحدة
  • ولا ترققهم بانتظام
  • القراصنة يسعدون

ولا يمكنك القول أن docker-compose المفترض أن "يفعل شيئًا واحدًا" لأنه يقوم بالفعل بكل شيء تقريبًا. بما في ذلك سحب الصور وبناءها بشكل أكثر أهمية ، تحديد التبعيات باستخدام خاصية depends_on . هذا لا يتعلق حتى بتطبيق ميزة جديدة تمامًا ، بل يتعلق فقط بتمرير معامل آخر إلى docker .

@ binman-عامل ميناءcrosbymichaeldmcgowanebrineyehazletteunomieguillaumerosejeanlaurentjustincormacklorenrhmanishtomarolegburovroutelastresortspencerhchengStefanSchererthaJeztahtonistiigiulyssessouzaaiordache @ndeloof كريس-شمطاء
يرجى إعادة النظر في هذه الميزة أو دعنا على الأقل نجري مناقشة مناسبة حول هذا الموضوع.

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

هذا سيكون حقا إضافة مفيدة.

أعتقد أنه من الجدير التأكيد على أن Kubernetes لديها هذه الوظيفة من خلال دورة الحياة postStart.

k8s! = تكوين عامل الميناء. قناة خاطئة

آسف لعدم الوضوح ، لكن وجهة نظري كانت: Kubernetes يدعم هذا ، ولأن تأليف Kubernetes و Docker لهما العديد من حالات / أغراض الاستخدام نفسها ، فسيكون ذلك حجة لوجوده في الإنشاء. آسف إذا كنت غير واضح.

أخبار جيدة!!

أعتقد أن عامل الميناء قد سمعنا (حول هذه المسألة وقليل من الآخرين). https://www.docker.com/blog/announcing-the-compose-specification/

دعونا نحاول العمل على المواصفات هناك لتلبية احتياجات المجتمع. يمكننا محاولة جعل هذا المجتمع مفتوحًا وودودًا مع إعادة التشغيل هذه.

أخبار جيدة!!

أعتقد أن عامل الميناء قد سمعنا (حول هذه المسألة وقليل من الآخرين). https://www.docker.com/blog/announcing-the-compose-specification/

دعونا نحاول العمل على المواصفات هناك لتلبية احتياجات المجتمع. يمكننا محاولة جعل هذا المجتمع مفتوحًا وودودًا مع إعادة التشغيل هذه.

هل اقترح أي شخص هذا التغيير حتى الآن؟ القائمة البريدية غير متوفرة حتى الآن ، لذا أعتقد أن أفضل مكان تالي هو هنا: https://github.com/compose-spec/compose-spec

لا أرى مشكلة تصف هذه المشكلة ولكن لست متأكدًا مما إذا كان هذا هو المكان المناسب ...

تحرير: فتحت مشكلة على https://github.com/compose-spec/compose-spec/issues/84.

يمكنك استخدام HEALTHCHECK للقيام بشيء آخر مثل المثال التالي:

الشفرة

Dockerfile

FROM ubuntu

COPY healthcheck.sh /healthcheck.sh
RUN chmod a+x /healthcheck.sh

HEALTHCHECK --interval=5s CMD /healthcheck.sh

CMD bash -c 'set -x; set +e; while true; do cat /test.txt; sleep 3; done'

healthcheck.sh

#/usr/bin/env bash

set -e

FIRST_READY_STATUS_FLAG='/tmp/.FIRST_READY_STATUS_FLAG'

# Health check

echo 'Run command to validate the container status HERE'

# On success
if [ ! -f "${FIRST_READY_STATUS_FLAG}" ]; then
  # On first success...
  touch "${FIRST_READY_STATUS_FLAG}"

  # Run ON_RUN on first health check ok
  if [ ! -z "${DOCKER_ON_RUN}" ]; then
    eval "${DOCKER_ON_RUN}"
  fi
fi
  1. قم بتشغيل فحص الصحة.

    • إذا فشل ، يتم الخروج من البرنامج النصي برمز الخروج 1 .

    • إذا كان _health check_ على ما يرام ، فسيستمر النص.

  2. إذا كان هذا هو أول فحص صحي موافق ، وإذا كان متغير البيئة DOCKER_ON_RUN موجودًا ، فقم بتنفيذه.

مثال

docker-compose.yml

version: "3.7"

services:
  test:
    build:
      context: .
    image: test/on-run
    environment:
      DOCKER_ON_RUN: echo x >> /test.txt

يمكنك استخدام متغير البيئة DOCKER_ON_RUN لتمرير أمر مخصص لتنفيذه بعد التشغيل.

نتيجة التنفيذ

docker-compose build
docker-compose up

انتاج:

Creating network "tmp_default" with the default driver
Creating tmp_test_1 ... done
Attaching to tmp_test_1
test_1  | + set +e
test_1  | + true
test_1  | + cat /test.txt
test_1  | cat: /test.txt: No such file or directory
test_1  | + sleep 3
test_1  | + true
test_1  | + cat /test.txt
test_1  | cat: /test.txt: No such file or directory
test_1  | + sleep 3
test_1  | + true
test_1  | + cat /test.txt
test_1  | x
test_1  | + sleep 3
test_1  | + true
test_1  | + cat /test.txt
test_1  | x
test_1  | + sleep 3
test_1  | + true
test_1  | + cat /test.txt
test_1  | x
test_1  | + sleep 3
  • يمكنك رؤية الخطأ cat: /test.txt: No such file or directory حتى يصبح التحقق من الصحة جاهزًا.
  • يمكنك رؤية x واحد فقط داخل /test.txt بعد التشغيل .

آمل أن يساعد هذا أحدهم.

تحرير 1

إذا لم تكن بحاجة إلى فحص صحي ، يمكنك استخدام باقي النص البرمجي.

تضمين التغريدة
شكرا على الحل الخاص بك.
فقط تريد أن تضيف ، في حالة ما إذا كنت تريد تشغيل أمر واحد ، مثل إنشاء المستخدمين أو غير ذلك ، يمكنك تحميل وحدة تخزين لـ touch "${FIRST_READY_STATUS_FLAG}"

العديد من هذه الحلول حلول صالحة لهذه المشكلة. على سبيل المثال ، يمكن أن يؤدي إنشاء برنامج نصي لنقطة الإدخال إلى حل هذا أيضًا:
ENTRYPOINT ["./entrypoint.sh"]

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

  • قبل الإنشاء
  • قبل البدء
  • بعد البدء
  • قبل التدمير
  • حتى بعد التدمير
  • الخ ...

أعلم أنه ليس كل ما سبق له معنى ولكن آمل أن تحصل على الصورة لأن هذه هي النقطة.
يمكن أيضًا تضمين هذا في docker-compose بتوجيه مثل:

lifecycle:
    before_start: "./beforeStartHook.sh"
    after_destroy: "./afterDestroyHook.sh"

أو حتى من هذا القبيل:

hooks:
    before_destroy: "./beforeDestroyHook.sh"
    before_create: "./fixFsRights.sh"

أنا غير قادر على الكتابة فوق الملف الذي يتطلب إذنًا من الجذر باستخدام نهج البرنامج النصي أو نهج البرنامج النصي bootstrap ، نظرًا لأننا نبدأ الحاوية كمستخدم غير جذر

واو ، هذه الوظيفة الأساسية لا تزال غير مطبقة.

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات