فحص أفضل ممارسات Dockerfile مع أرقام الأسطر
يفحص مدقق أفضل ممارسات Dockerfile ثلاث مشكلات شائعة قبل وصول الصورة إلى نظام البناء. فهو يبلغ عن غياب WORKDIR، وصور الأساس التي تستخدم وسم latest القابل للتغير، وتعليمات RUN المتتالية التي قد تنشئ طبقات غير ضرورية. ويتضمن كل اكتشاف رقم سطر المصدر ونوعا ثابتا وشرحا واضحا، ولذلك تصلح النتيجة لمراجعتكم اليدوية للملف وللفحص الآلي ضمن التكامل المستمر على السواء.
شغّل الأداة مجانًا
احصلوا على تقرير موجز وقابل للتنفيذ
ألصقوا محتوى Dockerfile كاملا في حقل النص ثم شغلوا الفحص. تبين الاستجابة نجاح الملف، وتعرض عدد الاكتشافات، وتسرد كل مشكلة برقم سطر يبدأ من 1 ونوع ثابت مناسب للمعالجة الآلية ورسالة موجزة. يركز المدقق عمدا على ثلاثة مخاطر صيانة متكررة ولا يدعي أنه بديل عن حزمة شاملة لأمن الحاويات. يبلغ عن WORKDIR المفقود في السطر 1 لأن الغياب يتعلق بالملف كله. وتبلغ تعليمة FROM في سطرها عندما تستخدم الصورة latest صراحة أو تحذف الوسم، فتؤول إلى latest. وعندما تتوالى تعليمتا RUN، يبلغ عن الثانية مع الإشارة إلى السطر السابق. لا تقطع التعليقات والأسطر الفارغة هذه العلاقة. يعيد الملف السليم مصفوفة findings فارغة، ولذلك يمكن استخدام valid مباشرة شرطا للنجاح في برنامج آلي. تعامل الأسطر المستمرة بشرطة مائلة عكسية على أنها تعليمة منطقية واحدة، مع إبقاء أول سطر فعلي موقعا للتقرير كي يطابق المحرر ومراجعة الشفرة.
افهموا أهمية الممارسات الثلاث
تحدد WORKDIR سياق نظام الملفات بوضوح لتعليمات RUN وCOPY وCMD وENTRYPOINT اللاحقة. ومن دونها يرث البناء بصمت دليلا اختارته صورة الأساس، وقد يتغير ذلك الدليل عند تحديثها. يساعد تثبيت صورة FROM بوسم ذي إصدار أو بصمة غير قابلة للتغيير على إعادة إنتاج عمليات البناء. فقد تشير الصورة التي لا تحمل وسما والصورة الموسومة latest إلى محتوى مختلف رغم بقاء Dockerfile من دون تعديل. وتنشئ كل تعليمة RUN عادة طبقة في نظام الملفات. وغالبا ما يكون من الأنسب جمع أوامر التثبيت والتنظيف والإعداد المتتالية في عملية shell واحدة، كي تحذف الملفات المؤقتة داخل الطبقة نفسها ويبقى السجل أوضح. يصاغ الاكتشاف كتوصية لأن فصل تعليمات RUN قد يكون مقصودا عندما تفيد حدود التخزين المؤقت سير عمل معتمدا. لا تعيد الأداة كتابة الأوامر ولا تزعم أن كل دمج آمن. ويظل القرار النهائي لمن يعرف عملية البناء واستراتيجية التخزين المؤقت وسلوك الأوامر عند الفشل.
شغلوا الفحص قبل بناء الصور المكلف
استخدموا المدقق من المحرر أو قبل الإيداع أو في بداية التكامل المستمر، قبل تنزيل صور الأساس وتجميع التطبيق. أرسلوا نص المصدر الأصلي بدلا من تمثيل محلل، للمحافظة على الأسطر الفعلية والتعليمات المستمرة. تعمل الخوارزمية بصورة حتمية؛ فالإدخال نفسه ينتج الإخراج نفسه دائما، من دون شبكة أو ساعة أو عشوائية أو Docker daemon أو حالة خاصة بالبيئة. لذلك تناسب ملفات Dockerfile المولدة أيضا. تعاملوا مع التقرير على أنه مؤشر أساسي لقابلية الصيانة، لا دليلا على أمان الصورة أو إمكانية بنائها. لا تنفذ الأداة أوامر shell، ولا تحل المتغيرات في أسماء الصور، ولا تفحص الحزم، ولا تتحقق من مصادر COPY، ولا تفرض USER غير ذي امتيازات، ولا تبحث عن الثغرات. اجمعوا هذا الفحص النصي السريع مع بناء فعلي ومسح للصورة وتطبيق للسياسات واختبارات للعملية الناتجة. وإذا لم يحتو الإدخال إلا على فراغات أو تعليقات، يفشل الطلب لعدم وجود تعليمات Dockerfile يمكن تقييمها.
حالات الاستخدام
راجعوا Dockerfile قبل الإيداع
اكتشفوا المراجع القابلة للتغير وأدلة العمل الغامضة بينما لا تزالون تعدلون الأسطر المعنية.
افحصوا تعريفات الحاويات المولدة
تحققوا من مخرجات القوالب قبل أن ينفق خط المعالجة وقتا على بناء صورة ونشرها.
قيموا مستودع حاويات
أنشئوا اكتشافات متسقة بأرقام الأسطر لترتيب التحسينات البسيطة عبر خدمات متعددة.
الأسئلة الشائعة
ما تكلفة طلب الفحص؟
تبلغ تكلفة كل طلب API مقدار $0.002. ويمكنكم أيضا استخدام نسخة المتصفح مباشرة في هذه الصفحة.
هل تعد الصورة بلا وسم مستخدمة لوسم latest؟
نعم. يعامل Docker الوسم المحذوف على أنه latest، لذلك يوصي المدقق بوسم ذي إصدار أو بصمة.
هل تجمع الأداة تعليمات RUN تلقائيا؟
لا. فهي تبلغ عن تعليمات RUN المتتالية ولا تعيد كتابتها، لأن حدود التخزين المؤقت المنفصلة قد تكون مقصودة.
لماذا يبلغ عن WORKDIR المفقود في السطر 1؟
يتعلق الغياب بالملف كله ولا يملك سطر مصدر خاصا به، ولذلك يمثل السطر 1 موقع المشكلة على مستوى الملف.
هل تتحقق الأداة من الصياغة أو الأمان؟
لا. فهي تطبق ثلاثة فحوص أساسية، وينبغي جمعها مع البناء الفعلي والسياسات ومسح الثغرات.
للمطوّرين — الوصول عبر API
كل ما في هذه الصفحة متاح برمجيًا. هذا القسم موجّه للفرق التقنية التي تريد ربط الأداة بأنظمتها الخاصة؛ بقية المستخدمين يمكنهم استخدام الأداة أعلاه مباشرة دون الحاجة لقراءة ما يلي.
الـEndpoint
صادِق على طلبك بترويسة Bearer، وأرسل طلب POST واحدًا لتدخل مهمتك قائمة التنفيذ فورًا؛ ثم تستلم النتيجة عبر webhook أو رابط موقّع.
استدعِ الخدمة من بيئتك
curl -X POST https://api.kit.forhosting.com/dev2/dockerfile-lint-basic \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"text":"FROM node:20-alpine\nWORKDIR /app\nCOPY package*.json ./\nRUN npm ci && npm cache clean --force\nCOPY . .\nCMD [\"node\", \"server.js\"]"}'const res = await fetch("https://api.kit.forhosting.com/dev2/dockerfile-lint-basic", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"text": "FROM node:20-alpine\nWORKDIR /app\nCOPY package*.json ./\nRUN npm ci && npm cache clean --force\nCOPY . .\nCMD [\"node\", \"server.js\"]"
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/dev2/dockerfile-lint-basic",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"text": "FROM node:20-alpine\nWORKDIR /app\nCOPY package*.json ./\nRUN npm ci && npm cache clean --force\nCOPY . .\nCMD [\"node\", \"server.js\"]"
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/dev2/dockerfile-lint-basic", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"text":"FROM node:20-alpine\\nWORKDIR /app\\nCOPY package*.json ./\\nRUN npm ci && npm cache clean --force\\nCOPY . .\\nCMD [\\"node\\", \\"server.js\\"]"}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"text":"FROM node:20-alpine\nWORKDIR /app\nCOPY package*.json ./\nRUN npm ci && npm cache clean --force\nCOPY . .\nCMD [\"node\", \"server.js\"]"}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/dev2/dockerfile-lint-basic", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)مثال على الطلب
{
"text": "FROM node:20-alpine\nWORKDIR /app\nCOPY package*.json ./\nRUN npm ci && npm cache clean --force\nCOPY . .\nCMD [\"node\", \"server.js\"]"
}مثال على الاستجابة
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "dev2.dockerfile_lint_basic",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}الواجهة غير متزامنة: تستلم task_id فور الإرسال، ويمكنك الاستعلام عن الحالة بمعدل طلب واحد في الثانية.
الأسعار
السعر معلن كما تراه: لا tokens ولا نظام نقاط؛ وإن فشلت المهمة فلن تُحاسَب عليها.
الأخطاء
| HTTP | الرمز | المعنى |
|---|---|---|
401 | unauthorized | مفتاح الوصول مفقود أو غير صالح؛ تحقق من ترويسة Bearer في طلبك. |
402 | insufficient_balance | رصيدك لا يكفي لتنفيذ هذه المهمة؛ أعد شحن الرصيد ثم أعد المحاولة. |
404 | unknown_type | نوع المهمة المطلوب غير موجود في الكتالوج — راجع الاسم المرسل في الطلب. |
429 | rate_limited | تجاوزت الحد المسموح من الطلبات؛ انتظر قليلًا ثم أعد المحاولة. |