ملفات Compose وملفات stack
نشر ملف Docker Compose أو ملف stack خاص بـ Swarm - ما يُطبَّق، وما لا يُطبَّق، وما يفعله تطبيق الملف مرة أخرى.
يصف ملف Compose عدّة برامج دفعة واحدة. تقرؤه ISOGrid وتحوّل كل خدمة فيه إلى
تطبيق مستقلّ: النوع نفسه من التطبيقات التي كنت ستنشئها يدويًا، له حجمه وعنوانه
وسجلّاته وتاريخه. ويُقرأ ملف docker stack بالطريقة نفسها.
الملف وسيلة لإنشاء التطبيقات وتحديثها. وليس شيئًا يظلّ يعمل بعد ذلك كمجموعة واحدة.
نوعان من الخدمات، ومساران
الخدمة التي تسمّي image تُسحب صورتها وتُشغَّل. وهذا موضوع هذه الصفحة.
الخدمة التي فيها قسم build: تُبنى من Dockerfile الخاص بها حين تستورد
المستودع. هذا المسار يقرأ الملف بطريقة مختلفة، وتشرحه صفحة
كيف يُكتشف البناء.
قد يضمّ الملف النوعين معًا. وتسلك كل خدمة المسار الذي يناسبها.
من أين يأتي الملف
ملصوق أو مرفوع. التطبيقات، ثم من ملف stack: الصق محتوى YAML أو ارفع الملف.
من مستودع مربوط. حين تختار مستودعًا، تُعرض ملفات YAML التي تسمّي خدماتُها صورًا على أنها ملفات stack. تقرأ المنصّة الملف بنفسها، وتُريك ما قرأته وعند أي commit، وتطبّق ذلك الـ commit نفسه حتى لو دفع أحدهم تغييرًا في الأثناء.
من سطر الأوامر. isogrid stack preview -f compose.yml --stack shop
و isogrid stack apply، مع ملف محلي، أو مجلّد ملفات، أو --repo و --path لملف
في مستودع مربوط. وهذا ما يُشغَّل من CI.
يمكن أن يبلغ حجم الملف 256 كيلوبايت وأن يضمّ حتى 60 خدمة.
المعاينة أولًا
المعاينة لا تغيّر شيئًا. تذكر لكل خدمة هل سيُنشأ تطبيق أم يُحدَّث أم يُتخطّى ولماذا، وأيّ سجلّاتك (registries) يسحب الصورة، وكل ما في الملف ممّا لن يُطبَّق.
ثم تقرّر أنت، لكل خدمة: الحجم (يُقترح أصغر حجم يتّسع لحدود الملف)، والشبكة، والسجلّ حين يطابق أكثر من واحد، والمنفذ، وأين يُسمح لها أن تعمل، أو أن تُترك جانبًا.
تُملأ ${TAG} و ${TAG:-1.4} من المتغيّرات التي تعطيها. والمتغيّر الذي يستخدمه
الملف ولم يقدّمه أحد يُذكر في القائمة، ويمنع التطبيق.
ما يُطبَّق
image، وهو إلزامي.deploy.replicas، من 1 إلى 10.environment.commandوentrypointوuserوhealthcheckوstop_grace_period.deploy.update_configوrollback_configوrestart_policy.loggingمع المشغّلjson-file: يفعّلmax-sizeوmax-fileحفظ السجلّات لذلك التطبيق.portsوexpose، فقط لمعرفة المنفذ الذي يستمع عليه البرنامج.deploy.resources.limits، فقط لاقتراح حجم.networks، وتُطابَق بالاسم مع إحدى شبكاتك. ينضمّ التطبيق إلى شبكة واحدة؛ وتُستخدم الأولى في القائمة.- المراسي (anchors) ومفاتيح الدمج
<<:.
ما لا يُطبَّق، ولماذا
build: بلا صورة. تُتخطّى الخدمة هنا. استورد المستودع لبنائها، أو ادفع
الصورة وسمِّها.
قواعد البيانات وذاكرات التخزين المؤقّت ووسطاء الرسائل وخوادم التخزين. صورة PostgreSQL أو MySQL أو MongoDB أو Redis أو RabbitMQ أو Kafka أو Keycloak أو MinIO وما شابهها تُتخطّى، مع إشارة إلى المقابل المُدار. فلو شُغّلت كتطبيق عادي لما كانت لها نسخ احتياطية ولضاعت بياناتها عند أول انتقال. انظر قواعد البيانات و الخدمات المُدارة.
env_file. لا يُقرأ في هذا المسار. أضف تلك المتغيّرات على التطبيق بعد ذلك،
والأسرار كأسرار.
volumes. لا تُركَّب، سواء كانت مسمّاة أو مرتبطة بمسار. لا تستطيع خدمة أن
تختار مسارات على أجهزة مشتركة. أرفق تخزينًا من صفحة التطبيق بعد تطبيق الملف.
secrets و configs. لا تُنشأ. احفظ القيم كأسرار واربطها بالتطبيق.
المنافذ المنشورة على المستضيف. "80:8080" لا يفتح شيئًا على أي جهاز. يظلّ
التطبيق خاصًّا حتى تجعله عامًّا من إعدادات الإتاحة الخاصة به، وعندها يحصل على
عنوان.
cap_add و privileged و devices و network_mode وما شابهها. لا تُمنح.
وتسرد المعاينة كل مفتاح لم تطبّقه.
depends_on و container_name و hostname و labels و restart في المستوى
الأعلى. تُتجاهل بلا تحذير. لا يُشغَّل شيء بترتيب معيّن: التطبيق الذي يحتاج إلى
تطبيق آخر ينبغي أن يعيد المحاولة حتى يستجيب.
قيود التموضع. إنها تسمّي أجهزة غيرك. ولا يُحتفظ بقيد إلا إذا طابق خيارًا تعرضه المنطقة.
أمور أصغر. mode: global يعمل كنسخ عادية، وحجوزات الموارد تأتي من الحجم،
ومشغّلات السجلّات غير json-file غير متاحة.
الأسماء، وكيف تجد الخدمات بعضها
يُسمّى كل تطبيق <stack>-<service>. وعلى شبكته الخاصة يستجيب أيضًا لاسم الخدمة
المجرّد كما ورد في الملف، فيظلّ http://api:8000 يعمل بين خدمات الشبكة نفسها.
التطبيق الذي يحمل ذلك الاسم أصلًا ولم تُنشئه هذه الـ stack يُترك على حاله.
مثال تقبله المنصّة
services:
api:
image: ghcr.io/acme/api:${TAG:-1.4}
command: ["node", "server.js"]
environment:
LOG_LEVEL: info
ports:
- "8000"
healthcheck:
test: ["CMD", "wget", "-qO-", "http://localhost:8000/health"]
interval: 30s
timeout: 5s
retries: 3
deploy:
replicas: 2
resources:
limits:
cpus: "0.5"
memory: 512M
update_config:
parallelism: 1
order: start-first
failure_action: rollback
monitor: 30s
logging:
driver: json-file
options:
max-size: 10m
max-file: "3"
worker:
image: ghcr.io/acme/api:${TAG:-1.4}
command: ["node", "worker.js"]
تطبيقه مرة أخرى
تطبيق الملف نفسه تحت اسم الـ stack نفسه يحدّث التطبيقات بدل أن ينشئ تطبيقات جديدة.
الغلبة للملف في ما يحدّده. الصورة، وعدد النسخ، والأمر، وفحص السلامة، وإعدادات الطرح والسجلّات تُستبدل بما في الملف.
البيئة تُدمج. متغيّرات الملف تكتب فوق الأسماء نفسها؛ والمتغيّرات التي أضفتها يدويًا تبقى.
عدد النسخ يعود إلى ما في الملف. إن وسّعت تطبيقًا يدويًا، فالتطبيق التالي للملف يُلغي ذلك.
الحجم هو ما يختاره ذلك التطبيق للملف. من سطر الأوامر، مرِّر --size في كل
مرة، وإلا عاد التطبيق إلى الحجم المقترح.
لا يُحذف شيء. الخدمة المحذوفة من الملف تترك تطبيقها يعمل. احذفه بنفسك.
ثم يُنشر كل تطبيق أُنشئ أو حُدّث، حتى إن لم يتغيّر شيء، إلا إذا أوقفت النشر. وفشل خدمة واحدة لا يوقف البقية؛ ويُبلَّغ عن كل واحدة.
الطرح وقراءة السجلّات
يُطرح كل تطبيق بمفرده، وفق الإعدادات التي أعطاه إيّاها الملف.
failure_action: rollback يعود تلقائيًا إلى الإصدار السابق، و pause يترك
القرار لك، و continue لا يفعل هذا ولا ذاك. و monitor هو المدّة التي يجب أن
يبقى فيها الإصدار الجديد سليمًا، بين 5 و 300 ثانية.
isogrid stack apply --wait ينتظر كل نشر ويفشل إن فشل أحدها أو جرى التراجع عنه،
وهذا ما تحتاجه مهمّة CI. و --follow يطبع سجلّات النشر فور ورودها.
تُقرأ السجلّات لكل تطبيق، لا لكل stack: من صفحة التطبيق، أو بالأمر
isogrid apps logs <application>. ومن دون حفظ السجلّات، لا يمكن البحث إلا في ما
تزال النسخ العاملة تحتفظ به.