تخطَّ إلى المحتوى

١٠ يوليو ٢٠٢٦

حل خطأ port is already allocated في Docker بالعربي

شارك المقال:

تشغّل حاويتك بحماس:

docker run -p 3000:3000 my-app

فيرد Docker ببرود:

docker: Error response from daemon: driver failed programming external
connectivity: Bind for 0.0.0.0:3000 failed: port is already allocated.

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

افهم الربط أولًا: host:container

-p 3000:3000
   ─┬── ─┬──
    │     └─ منفذ الحاوية: ما يستمع عليه تطبيقك بالداخل
    └─ منفذ المضيف: ما يُفتح على جهازك — هذا هو المتعارَض عليه

التعارض دائمًا في الجهة اليسرى (المضيف). داخل الحاوية لكل حاوية عالمها المعزول ولا تعارض أبدًا.

المشتبه بهم الثلاثة بالترتيب

1) حاوية أخرى تعمل الآن

docker ps --format "table {{.Names}}\t{{.Ports}}"
# NAMES        PORTS
# old-app      0.0.0.0:3000->3000/tcp   ← ها هو الحاجز

وجدتها؟ أوقفها أو احذفها:

docker stop old-app && docker rm old-app

2) حاوية متوقفة لم تُحذف (الفخ الصامت)

docker ps تعرض العاملة فقط — الحاوية المتوقفة قد تبقى حاجزة للربط:

docker ps -a          # اعرض الكل، بما فيها المتوقفة
docker rm old-app     # الحذف يحرر الربط نهائيًا

💡 وقاية: شغّل التجارب دائمًا بـ docker run --rm ... — تُحذف الحاوية تلقائيًا لحظة إيقافها ولا تخلّف حجوزات.

ومع مشاريع compose، الأمر الصحيح لإنهاء كل شيء:

docker compose down   # يوقف ويحذف الحاويات والشبكات معًا

3) برنامج على جهازك نفسه

لا شيء في docker ps -a؟ الحاجز خارج Docker — غالبًا خادم تطوير نسيته:

# لينكس / ماك
sudo lsof -i :3000

# ويندوز (PowerShell)
netstat -ano | findstr :3000    # خذ الـ PID من آخر عمود
tasklist | findstr <PID>        # من هو؟

هذه الحالة هي الشقيقة التوأم لخطأ Node الشهير — شرحناها بتفصيل في حل خطأ EADDRINUSE: المنفذ مستخدم.

الحل الالتفافي الفوري: غيّر جهة المضيف

مستعجل ولا يهمك من الحاجز؟ بدّل الرقم الأيسر فقط:

docker run -p 3001:3000 my-app
# التطبيق داخل الحاوية ما زال على 3000 — وأنت تزوره على localhost:3001

وفي docker-compose.yml:

services:
  web:
    ports:
      - "3001:3000"   # المضيف:الحاوية

قائمة تحقّق سريعة

  • docker ps — حاوية عاملة تحجز المنفذ؟ أوقفها.
  • docker ps -a — حاوية متوقفة منسية؟ docker rm لها.
  • مشروع compose قديم؟ → docker compose down.
  • لا حاويات؟ → lsof -i :PORT أو netstat لكشف برنامج المضيف.
  • مستعجل؟ → غيّر الجهة اليسرى: -p 3001:3000.
  • اجعل --rm عادة في حاويات التجارب.

الخلاصة

port is already allocated نزاع على منفذ المضيف حصرًا: حاوية عاملة، أو جثة حاوية متوقفة، أو برنامج محلي. docker ps -a تكشف الأولَين، وlsof/netstat يكشف الثالث — وتغيير الرقم الأيسر في -p مخرجُ طوارئ دائم الجاهزية.

أكمل الأساس في مسار Docker بالعربي، واقرأ الشقيق المباشر حل خطأ EADDRINUSE في Node.js و حل Permission denied في لينكس لمنافذ النظام المحمية.

📚 مصادر رسمية للتعمّق: التوثيق الرسمي لـ Docker

الأسئلة الشائعة

ما الفرق بين الرقمين في -p 3001:3000؟

الصيغة هي منفذ-المضيف:منفذ-الحاوية. الأيسر (3001) هو ما تفتحه على جهازك وتزوره بالمتصفح، والأيمن (3000) هو ما يستمع عليه التطبيق داخل الحاوية. عند التعارض غيّر الأيسر فقط — التطبيق داخل الحاوية لا يشعر بأي فرق.

أوقفت الحاوية والمنفذ ما زال محجوزًا — لماذا؟

حاوية متوقفة أُنشئت بربط منفذ تبقى حاجزة له حتى تُحذف بـ docker rm (الإيقاف وحده لا يكفي في حالات، خاصة مع إعادة التشغيل التلقائي restart policies). docker ps -a تكشفها، وشغّل حاوياتك التجريبية بـ --rm لتُحذف تلقائيًا عند إيقافها.

كيف أعرف إن كان الحاجز برنامجًا على جهازي وليس حاوية؟

إذا لم تجد شيئًا في docker ps -a فافحص جهازك: على لينكس/ماك sudo lsof -i :3000، وعلى ويندوز netstat -ano | findstr :3000 ثم افتح مدير المهام بالـ PID. غالبًا يكون خادم تطوير npm نسيته يعمل في طرفية أخرى.

اقرأ أيضًا

تصفّح كل المقالات في المدوّنة، أو ابدأ التعلّم من المسارات و خرائط الطريق.