إدارة مساحة التخزين في Docker: دليل شامل لحذف صور Docker مع أمثلة عملية

دقائق القراءة: 6

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

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


SELECT tag, title, answer_count, favorite_count, score, view_count VIEWS
FROM (
  SELECT title, answer_count, favorite_count, view_count, score,
  SPLIT (tags, '|' ) tags
  FROM `bigquery-public-data.stackoverflow.posts_questions` posts_questions),
UNNEST (tags) tag
WHERE tag = 'docker'
AND title LIKE '%space left%'
ORDER BY VIEWS DESC

نتائج الاستعلام:

نتائج استعلام StackOverflow حول مشكلات مساحة Docker

يتضح من عدد المشاهدات الهائل لهذه المنشورات على StackOverflow (أكثر من 465 ألف مشاهدة للاستعلام المطابق) أن مشكلة نقص المساحة ليست مقتصرة على شخص واحد. لحسن الحظ، سنستعرض اليوم أمثلة سهلة الاستخدام حول كيفية حذف صور Docker المعلقة (dangling) وغير المستخدمة (unused) لمساعدتك في استعادة مساحة التخزين الثمينة.

ما هي صور Docker المعلقة وغير المستخدمة؟

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

  • الصور المعلقة (Dangling Images): هي صور تم بناؤها حديثًا ولكن لم يتم منحها اسمًا أو وسمًا (tag) جديدًا. فكر فيها كصور قديمة منسية لا يعرف أحد ما يجب فعله بها بعد الآن. تظهر هذه الصور بدون وسم (<none>) في عمودي REPOSITORY و TAG عند تشغيل الأمر docker images. غالبًا ما تنتج عن إعادة بناء صورة بنفس الاسم والوسم دون تنظيف الإصدارات القديمة.
  • الصور غير المستخدمة (Unused Images): هي صور لم يتم تعيينها أو استخدامها بواسطة أي حاوية (container) حاليًا. على سبيل المثال، عند تشغيل الأمر docker ps -a، سيعرض لك جميع الحاويات قيد التشغيل بالإضافة إلى الحاويات المتوقفة. أي صور تُستخدم داخل أي من هذه الحاويات تُعتبر “صورًا مستخدمة”، وأي صور أخرى لا ترتبط بأي حاوية هي “صور غير مستخدمة”.

رسم توضيحي للفرق بين صور Docker المعلقة وغير المستخدمة

كيفية حذف صور Docker

الآن، دعنا ننتقل إلى الأمثلة العملية لكيفية حذف صور Docker.

دراسة حالة: شركة Busy Cat Corp

تخيل شركة Busy Cat Corp، وهي شركة خيالية تجمع بيانات سلوك القطط وتقدم توصيات لأصحابها لجعل حيواناتهم الأليفة أكثر نشاطًا وسعادة. تعتمد جميع أعباء عملهم على الحاويات (containerized)، ويستخدمون صور قواعد البيانات التالية: cassandra، postgres، mysql، و mongo. يواجه مطوروهم باستمرار مشكلة نقص المساحة على أجهزتهم، وهم من المستخدمين النشطين لـ StackOverflow. لقد طلبوا منا بعض الأمثلة السريعة حول كيفية حذف بعض الصور واستعادة مساحتهم.

قطة مشغولة تمثل شركة Busy Cat Corp الخيالية

لنلقِ نظرة أولاً على جهاز أحد مطوريهم:


docker images

الناتج:


REPOSITORY        TAG                 IMAGE ID            CREATED             SIZE
<none>            <none>              9c872a6119cc        About a minute ago  384MB
mysql             latest              5ac22cccc3ae        43 hours ago        544MB
cassandra         3                   9fab0c92a93d        4 days ago          384MB
adoptopenjdk      8-jre...            2bf0172ac69b        4 days ago          210MB
mongo             latest              6d11486a97a7        2 weeks ago         388MB
postgres          latest              b97bae343e06        6 weeks ago         313MB

لديهم جميع صور أعباء عملهم، ولكن لاحظ أن المساحة الكلية تتجاوز 2 جيجابايت! دعنا نرى ما يمكننا فعله لمساعدتهم.

حذف صور Docker المعلقة (Dangling Images)

سنبدأ بالبحث عن الصور المعلقة. يمكننا استخدام الأمر التالي لعرضها:


docker images -qf "dangling=true"

الناتج:


REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
<none>              <none>              9c872a6119cc        About a minute ago  384MB

لدينا صورة معلقة واحدة، وسنقوم بحذفها الآن. لحذف جميع الصور المعلقة، استخدم الأمر:


docker rmi $(docker images -qf "dangling=true")

صورة توضيحية لإتمام عملية حذف صور Docker المعلقة بنجاح

حذف صور Docker غير المستخدمة (Unused Images)

بعد ذلك، سنبحث عن الصور غير المستخدمة. أولاً، دعنا نتحقق من الحاويات قيد التشغيل أو المتوقفة:


docker ps -a

الناتج:


CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
b6387b343b81        mysql               "docker-entrypoint..." 16 minutes ago      Up 16 minutes       3306/tcp            some-mysql

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


# Get all the images currently in use
USED_IMAGES=(\$( \
docker ps -a --format '{{.Image}}' | \
sort -u | \
uniq | \
awk -F ':' '$2{print $1":"$2}!$2{print $1":latest"}' \
))

# Get all the images currently available
ALL_IMAGES=(\$( \
docker images --format '{{.Repository}}:{{.Tag}}' | \
sort -u \
))

# Print the unused images
for i in "${ALL_IMAGES[@]}" ; do
  UNUSED=true
  for j in "${USED_IMAGES[@]}" ; do
    if [[ "$i" == "$j" ]]; then
      UNUSED=false
    fi
  done
  if [[ "$UNUSED" == true ]]; then
    echo "$i is not being used."
  fi
done

الناتج:


adoptopenjdk:8-jre-hotspot-bionic is not being used.
cassandra:3 is not being used.
mongo:latest is not being used.
postgres:latest is not being used.

ثم يقوم السكربت بحذف الصور غير المستخدمة:


# Get all the images currently in use
USED_IMAGES=(\$( \
docker ps -a --format '{{.Image}}' | \
sort -u | \
uniq | \
awk -F ':' '$2{print $1":"$2}!$2{print $1":latest"}' \
))

# Get all the images currently available
ALL_IMAGES=(\$( \
docker images --format '{{.Repository}}:{{.Tag}}' | \
sort -u \
))

# Remove the unused images
for i in "${ALL_IMAGES[@]}" ; do
  UNUSED=true
  for j in "${USED_IMAGES[@]}" ; do
    if [[ "$i" == "$j" ]]; then
      UNUSED=false
    fi
  done
  if [[ "$UNUSED" == true ]]; then
    docker rmi "$i"
  fi
done

بعد حذف كل من الصور المعلقة وغير المستخدمة، يمكننا التحقق مما تبقى:


docker images

الناتج:


REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
mysql               latest              5ac22cccc3ae        43 hours ago        544MB

رائع! لقد تبقت لدينا فقط صورة mysql المستخدمة.

صورة توضيحية لإتمام عملية حذف صور Docker غير المستخدمة بنجاح

حذف جميع صور Docker القديمة باستخدام أمر Prune

قد تبدو الأوامر السابقة رائعة، ولكن قد يقول مطور آخر إنه لا يهتم بالفروق بين الصور المعلقة وغير المستخدمة. كل ما يريده هو مسح الصور القديمة واستعادة مساحة القرص. شخصيًا، هذا ما أفعله عادةً. يمكننا ببساطة استخدام أوامر prune الخاصة بـ Docker، والتي توفر طريقة شاملة وسهلة لتنظيف مساحة التخزين.

الخطوات هي كالتالي:


# أولاً، احذف جميع الحاويات المتوقفة
docker container prune

# ثم احذف كل من الصور المعلقة وغير المستخدمة
docker image prune --all

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

الخلاصة التقنية

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

توفر سجلات الحاويات مثل Google Cloud Platform مع Artifact Registry، و Docker Enterprise مع Docker Trusted Registry، و Docker Hub (للمشاريع مفتوحة المصدر) إدارة قوية وآمنة لصور Docker، بما في ذلك التحكم في الإصدارات، والمسح الأمني، والوصول الموثوق. إن فهم هذه الفروق وتبني أفضل الممارسات يضمن بيئة تطوير نظيفة وفعالة، ويؤدي إلى نشر تطبيقات مستقرة وآمنة في بيئات الإنتاج.

اترك تعليقاً

لن يتم نشر عنوان بريدك الإلكتروني. الحقول الإلزامية مشار إليها بـ *