Docker: مستودع الصور الخاص

آخر تحديث: 2026-08-26

لا تريد دفع كود شركتك إلى Docker Hub العام؟ أعد مستودع صور خاص في 5 دقائق.

1. ما ستتعلمه



2. قصة حقيقية لقائد فريق

(1) نقطة الألم: لا يمكن دفع الكود إلى مستودع عام

لا تريد أليس دفع كود الشركة إلى Docker Hub العام — قد تحتوي الصور على معلومات حساسة مثل ملفات الإعدادات وقيم متغيرات البيئة الافتراضية. ومع ذلك، يحتاج الفريق إلى مستودع صور لمشاركة نواتج البناء؛ النقل اليدوي بـ docker save/load غير فعال للغاية — يستغرق خمسة مطورين 30 دقيقة في كل مرة لنقل صورة.

(2) حلول المستودعات الخاصة

أعددت مستودعًا خاصًا مع المصادقة باستخدام ثلاثة أسطر فقط من الإعدادات.

BASH
# بدء مستودع خاص مع المصادقة
docker run -d -p 5000:5000 \
  -v registry-data:/var/lib/registry \
  --restart=always \
  --name registry registry:2

(3) الفوائد: مشاركة الصور في 5 دقائق

يمكن للفرق البدء في استخدام المستودعات الخاصة في 5 دقائق. docker push مرة واحدة، والجميع docker pull. انخفض وقت تسليم الصور من 30 دقيقة إلى 30 ثانية.



3. مقارنة حلول مستودعات الصور

(1) مقارنة الخيارات الثلاثة

البُعد Docker Hub (عام) Registry خاص Harbor
التكلفة مجاني مع حدود؛ خطة مدفوعة $5/شهر مجاني تمامًا مجاني ومفتوح المصدر
المصادقة حساب Docker htpasswd/TLS LDAP/OIDC/DB
واجهة ويب
فحص الصور ✅ (مدفوع) ✅ (تكامل Trivy)
صعوبة النشر لا شيء (قيد التشغيل بالفعل) منخفضة (أمر واحد) متوسطة (Docker Compose)
النطاق المناسب أفراد/فرق صغيرة فرق صغيرة إلى متوسطة مؤسسي

(2) اصطلاحات تسمية الصور

TEXT 📖 للعرض فقط
# الصور الرسمية على Docker Hub
docker.io/library/nginx:1.25

# صور المستخدم على Docker Hub
docker.io/myorg/myapp:v2.0

# صور المستودع الخاص
localhost:5000/myapp:v2.0
registry.example.com/team/app:v1.0


4. نشر Registry خاص

▶ مثال: بدء حاوية Registry (الصعوبة: ⭐)

BASH
# بدء مستودع خاص أساسي
docker run -d \
  -p 5000:5000 \
  --name registry \
  --restart=always \
  -v registry-data:/var/lib/registry \
  registry:2

# التحقق من أنه قيد التشغيل
curl http://localhost:5000/v2/_catalog
💻 المخرجات:

TEXT 📖 للعرض فقط
{"repositories":[]}

(1) استمرارية البيانات

الطريقة الأمر الوصف
وحدة تخزين مسماة -v registry-data:/var/lib/registry تخزين دائم يديره Docker
تركيب Bind -v /data/registry:/var/lib/registry تحديد دليل المضيف
الافتراضي (بدون -v) لا استمرارية بيانات الصورة تُفقد عند حذف الحاوية
⚠️ ملاحظة: في بيئة الإنتاج، يجب استخدام وحدة تخزين أو تركيب bind لاستمرار البيانات. وإلا، ستفقد جميع الصور المدفوعة عند حذف حاوية Registry.



5. دفع وسحب الصور

▶ مثال: الدفع إلى مستودع خاص (الصعوبة: ⭐⭐)

BASH
# 1. توسيم صورة للمستودع الخاص
docker tag nginx:1.25-alpine localhost:5000/web/nginx:v1

# 2. دفع الصورة
docker push localhost:5000/web/nginx:v1

# 3. التحقق من وجودها في المستودع
curl http://localhost:5000/v2/web/nginx/tags/list
💻 المخرجات:

TEXT 📖 للعرض فقط
{"name":"web/nginx","tags":["v1"]}

▶ مثال: سحب صورة من مستودع خاص (الصعوبة: ⭐⭐)

BASH
# 1. إزالة النسخة المحلية
docker rmi localhost:5000/web/nginx:v1

# 2. السحب من المستودع الخاص
docker pull localhost:5000/web/nginx:v1

# 3. تشغيل الصورة المسحوبة
docker run --rm localhost:5000/web/nginx:v1 nginx -v
💻 المخرجات:

TEXT 📖 للعرض فقط
nginx version: nginx/1.25.3


6. إعداد مصادقة المستودع

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

▶ مثال: إنشاء ملف كلمة مرور htpasswd (الصعوبة: ⭐⭐⭐)

BASH
# إنشاء دليل لبيانات المصادقة
mkdir -p auth

# إنشاء ملف htpasswd (يتطلب httpd-tools / apache2-utils)
htpasswd -Bbn admin secret123 > auth/htpasswd

# بدء المستودع مع المصادقة
docker run -d \
  -p 5000:5000 \
  --name registry-auth \
  --restart=always \
  -v registry-data:/var/lib/registry \
  -v $(pwd)/auth:/auth \
  -e "REGISTRY_AUTH=htpasswd" \
  -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \
  -e "REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd" \
  registry:2

(1) العمليات بعد المصادقة

BASH
# تسجيل الدخول إلى المستودع الخاص
docker login localhost:5000
# اسم المستخدم: admin
# كلمة المرور: secret123

# دفع (يتطلب تسجيل الدخول)
docker push localhost:5000/myapp:v1

# سحب (يتطلب تسجيل الدخول)
docker pull localhost:5000/myapp:v1

# تسجيل الخروج
docker logout localhost:5000


7. عرض دليل المستودع

▶ مثال: استخدام curl لعرض الفهرس والوسوم (الصعوبة: ⭐⭐)

BASH
# عرض جميع المستودعات
curl -s http://localhost:5000/v2/_catalog | python3 -m json.tool

# عرض وسوم مستودع محدد
curl -s http://localhost:5000/v2/web/nginx/tags/list | python3 -m json.tool

# عرض بيان الصورة (بيانات وصفية مفصلة)
curl -s -H "Accept: application/vnd.docker.distribution.manifest.v2+json" \
  http://localhost:5000/v2/web/nginx/manifests/v1 | python3 -m json.tool
💻 المخرجات:

TEXT 📖 للعرض فقط
# catalog
{
  "repositories": [
    "web/nginx",
    "team/api"
  ]
}

# tags/list
{
  "name": "web/nginx",
  "tags": ["v1", "v2"]
}


8. جمع القمامة

بعد حذف صورة في Registry (إزالة الوسم)، لا تُنظف بيانات الطبقة تلقائيًا. يجب إجراء جمع القمامة يدويًا.

▶ مثال: جمع القمامة (الصعوبة: ⭐⭐⭐)

BASH
# حذف وسم (وضع علامة للحذف)
curl -X DELETE -H "Accept: application/vnd.docker.distribution.manifest.v2+json" \
  http://localhost:5000/v2/web/nginx/manifests/<digest>

# تشغيل جمع القمامة داخل حاوية registry
docker exec registry bin/registry garbage-collect \
  /etc/docker/registry/config.yml

# أو مع dry-run أولاً (معاينة فقط)
docker exec registry bin/registry garbage-collect --dry-run \
  /etc/docker/registry/config.yml


9. مستودعات HTTP مقابل HTTPS

(1) سياسات أمان Docker

افتراضيًا، يسمح Docker فقط باتصالات HTTPS بالمستودع (باستثناء localhost). يجب إعداد المستودعات البعيدة بـ HTTPS، أو إضافة خيار insecure-registries من جانب العميل.

السيناريو مستوى الأمان الإعداد
localhost:5000 HTTP مسموح افتراضيًا لا حاجة لإعداد إضافي
مستودع HTTP بعيد غير آمن، يتطلب إذنًا صريحًا insecure-registries
مستودع HTTPS بعيد ✅ موصى به شهادة TLS

(2) إعداد insecure-registries (لبيئات الاختبار فقط)

JSON
{
  "insecure-registries": ["registry.example.com:5000"]
}
🔒 الأمان: يجب أن تستخدم بيئات الإنتاج HTTPS + شهادة TLS موثوقة. "insecure-registries" مخصص للاختبار الداخلي فقط؛ حركة المرور عرضة لهجمات man-in-the-middle.



10. مثال كامل: نشر مستودع خاص مع المصادقة

BASH
# ============================================
# شرح كامل: مستودع خاص مع المصادقة
# يغطي: النشر، المصادقة، الدفع، السحب، الفهرس، جمع القمامة
# ============================================

# 1. إنشاء أدلة للبيانات الدائمة
mkdir -p auth registry-data

# 2. إنشاء ملف مصادقة htpasswd
htpasswd -Bbn admin secret123 > auth/htpasswd

# 3. بدء المستودع مع المصادقة والاستمرارية
docker run -d \
  -p 5000:5000 \
  --name my-registry \
  --restart=always \
  -v $(pwd)/registry-data:/var/lib/registry \
  -v $(pwd)/auth:/auth \
  -e "REGISTRY_AUTH=htpasswd" \
  -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \
  -e "REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd" \
  registry:2

# 4. تسجيل الدخول إلى المستودع
docker login localhost:5000 -u admin -p secret123

# 5. توسيم ودفع صورة
docker tag nginx:1.25-alpine localhost:5000/web/nginx:v1.0
docker push localhost:5000/web/nginx:v1.0

# 6. التحقق من الدفع
curl -s -u admin:secret123 http://localhost:5000/v2/_catalog
curl -s -u admin:secret123 http://localhost:5000/v2/web/nginx/tags/list

# 7. السحب من جهاز آخر (بعد تسجيل الدخول)
docker pull localhost:5000/web/nginx:v1.0

# 8. التنظيف
docker logout localhost:5000
💻 المخرجات (مقتطف):

TEXT 📖 للعرض فقط
# curl catalog
{"repositories":["web/nginx"]}

# curl tags
{"name":"web/nginx","tags":["v1.0"]}

❓ أسئلة شائعة

س كم مساحة التخزين التي يحتاجها المستودع الخاص؟
ج يعتمد على عدد وحجم الصور. الصورة الواحدة تتراوح من 50 إلى 500 ميجابايت، و10 صور تشغل حوالي 1 إلى 5 جيجابايت. نوصي بتخصيص 50 جيجابايت مبدئيًا وتنظيف الإصدارات القديمة بانتظام. للاستخدام المؤسسي، نوصي باستخدام تخزين الكائنات (S3/OSS) كخلفية للمستودع، مع تخزين يتوسع حسب الطلب.
س كيف أعد HTTPS للمستودع؟
ج هناك طريقتان: ① استخدام Nginx أو Caddy كوكيل عكسي وإعداد شهادة TLS (موصى به)؛ ② إعداد TLS مباشرة في Registry. نوصي بنهج الوكيل العكسي — Nginx يتولى إنهاء TLS، بينما يركز Registry على التخزين. Let's Encrypt يوفر شهادات مجانية.
س كيف أنظف عندما يكون هناك عدد كبير جدًا من الصور؟
ج خطوتان: ① استخدم DELETE API لإزالة الوسوم/البيانات غير الضرورية؛ ② شغل registry garbage-collect لتحرير بيانات الطبقات غير المرجعية. نوصي بكتابة برنامج نصي لتنظيف الإصدارات القديمة التي مضى عليها أكثر من N يوم بشكل دوري. Harbor لديه سياسات تنظيف مدمجة.
س هل يمكن للآخرين عرض الصور في المستودع؟
ج بدون مصادقة، يمكن لأي شخص السحب (وصول مجهول). بعد إعداد مصادقة htpasswd، يجب تسجيل الدخول للدفع أو السحب. موصى به لبيئات الإنتاج: صلاحيات قراءة فقط للسحب، وصلاحيات كتابة للدفع (Registry 2.8+ يدعم RBAC).
س أيهما أفضل للاستخدام، Harbor أم Registry؟
ج Registry هو مستودع بسيط (مناسب للفرق الصغيرة و CI)، بينما Harbor هو مستودع على مستوى المؤسسات (واجهة ويب + فحص الصور + RBAC + سجلات التدقيق). الفرق التي يقل عدد أعضائها عن 10 يجب أن تستخدم Registry، بينما التي يزيد عدد أعضائها عن 10 أو لديها متطلبات امتثال يجب أن تستخدم Harbor. Harbor نفسه يُنشر باستخدام Docker Compose ويمكن إعداده في 5 دقائق.

📖 ملخص


📝 تمارين

  1. تمرين أساسي (الصعوبة: ⭐): ابدأ مستودعًا خاصًا باستخدام docker run، وادفع nginx:alpine إلى localhost:5000/test/nginx:v1، ثم اسحبها من جهاز آخر (أو بعد حذف الصورة المحلية) للتحقق.
  2. تمرين متقدم (الصعوبة: ⭐⭐): أعد مصادقة htpasswd بحيث تُرفض عمليات الدفع عند عدم تسجيل الدخول، لكنها تنجح بعد تسجيل الدخول.
  3. تحدٍ (الصعوبة: ⭐⭐⭐): استخدم وكيل Nginx العكسي لإعداد HTTPS لـ Registry (يمكن استخدام شهادة موقعة ذاتيًا)، والوصول إلى المستودع عبر https://registry.local/v2/_catalog.
Web-Tutorial.com

فريق Web-Tutorial التقني

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

100%