الأدلة التقنية

تثبيت Docker Engine وDocker Compose على Ubuntu 24.04

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

تثبيت Docker Engine وDocker Compose على Ubuntu 24.04

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

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

وسوف نناقش في هذا المقال ما يلي:

  • الفرق بين Docker Engine وDocker Desktop، ولماذا لا نثبت حزمة docker.io من Ubuntu أو سكربت get.docker.com على سيرفر الإنتاج.
  • تثبيت Docker Engine من المستودع الرسمي لـ Docker Official Repository خطوة بخطوة.
  • ثلاثة أمور يغفلها كثيرون بعد التثبيت: تشغيل الأوامر دون sudo مع فهم ما يعنيه ذلك أمنياً، وتدوير السجلات Log Rotation حتى لا يمتلئ القرص، وطريقة تعامل Docker مع جدار الحماية Firewall ufw.
  • التحقق من التثبيت، والنسخ الاحتياطي، والتحديث، وأشهر المشكلات وحلولها.

وإذا أردت بعد ذلك إدارة ال Containers من المتصفح عبر واجهة ويب Web UI، فراجع دليل تثبيت Portainer بعد أن تنتهي من هذا الدليل.

Docker Engine أم Docker Desktop؟

Docker Engine هو المحرك نفسه، أي خدمة تعمل في الخلفية على السيرفر وتتعامل معها من سطر الأوامر Command Line، وهذا كل ما تحتاجه على أي سيرفر.

أما Docker Desktop فهو تطبيق بواجهة رسومية GUI لأجهزة المطورين على Windows وmacOS وLinux، حيث يشغل Docker Engine داخل جهاز افتراضي VM صغير ويضيف فوقه أدوات تساعد في التطوير، ولكنه ليس مصمماً للسيرفرات، وبالإضافة إلى ذلك فهو يحتاج إلى اشتراك مدفوع Subscription في الجهات الحكومية، وفي الشركات التي يبلغ عدد موظفيها 250 أو أكثر أو إيراداتها السنوية 10 ملايين دولار أو أكثر. لذلك سوف نثبت هنا Docker Engine وحده.

لماذا لا نثبت حزمة docker.io من Ubuntu؟

وقد يتساءل البعض: لماذا كل هذه الخطوات، وحزمة docker.io موجودة أصلاً في مستودعات Ubuntu وتثبيتها يحتاج أمراً واحداً؟ والإجابة أن هذه الحزمة يجهزها فريق Ubuntu وتتبع جدوله في التحديث، أما المستودع الرسمي لـ Docker فيعطيك أحدث إصدار مستقر Stable Release، ومعه الإضافتان Plugins docker compose وbuildx، وتصلك تحديثاته الأمنية Security Updates عبر apt مع باقي النظام، وبالتالي فأنت تعمل على نفس الإصدار الذي يشرحه التوثيق الرسمي وتصلك إصلاحاته مباشرة.

وماذا عن سكربت get.docker.com؟

الحل السريع الثاني هو السكربت السريع Convenience Script الذي توفره Docker، حيث يثبت كل شيء بأمرين: curl -fsSL https://get.docker.com -o get-docker.sh ثم sudo sh get-docker.sh، والنتيجة قريبة من الطريقة اليدوية لأنه يضيف المستودع نفسه ويثبت الحزم نفسها. ولكن Docker نفسها لا تنصح به على سيرفرات الإنتاج Production، والسبب أنه:

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

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

ما تحتاجه قبل أن تبدأ Requirements

  • سيرفر يعمل بنظام Ubuntu Server 24.04 LTS بمعمارية Architecture amd64 أو arm64، وإذا لم تختر سيرفرك بعد فابدأ بدليل كيف تختار خادماً افتراضياً VPS، ثم تأمين خادم VPS من أول دخول.
  • مستخدم عادي Non-root User يملك صلاحية sudo، وتدخل به عبر SSH بمفتاح SSH Key وليس بكلمة مرور.
  • Docker نفسه خفيف، فخطط الموارد Resources بحسب التطبيقات التي سوف تشغلها، وكبداية معقولة: 2 GB من الذاكرة RAM و20 GB من القرص.
  • اتصال بالإنترنت يصل إلى download.docker.com.

إزالة الحزم المتعارضة Conflicting Packages

إذا كانت حزمة docker.io أو docker-buildx أو podman-docker مثبتة من مستودعات Ubuntu، فسوف تتعارض مع حزم Docker الرسمية، لذلك نبدأ بإزالتها. والأمر التالي يزيل ما هو مثبت منها ويتجاهل الباقي، ولاحظ أنه لا يمس ال Containers وال Images المحفوظة في /var/lib/docker:

for pkg in docker.io docker-doc docker-compose docker-compose-v2 docker-buildx podman-docker containerd runc; do sudo apt-get remove -y $pkg; done

إضافة مستودع Docker الرسمي

الطريقة القديمة كانت تضيف مفتاح التوقيع Signing Key بالأمر apt-key add، والمشكلة فيها أنها تجعل المفتاح موثوقاً لكل المستودعات وليس لمستودع Docker وحده، ولهذا ألغتها إصدارات Ubuntu الحديثة. أما الطريقة الحالية فتحفظ المفتاح في /etc/apt/keyrings وتربطه بمستودع Docker وحده عبر Signed-By. ابدأ بتحديث فهرس الحزم Package Index وتثبيت الأدوات اللازمة:

sudo apt update
sudo apt install -y ca-certificates curl

بعد ذلك نزل مفتاح Docker واجعله قابلاً للقراءة من قبل apt:

sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

الآن سوف نضيف المستودع بصيغة deb822 الحديثة كما يلي:

sudo tee /etc/apt/sources.list.d/docker.sources <<EOF
Types: deb
URIs: https://download.docker.com/linux/ubuntu
Suites: $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}")
Components: stable
Architectures: $(dpkg --print-architecture)
Signed-By: /etc/apt/keyrings/docker.asc
EOF

في الإعداد أعلاه لاحظ التالي:

  • سطر Suites يقرأ اسم الإصدار تلقائياً، وهو noble في Ubuntu 24.04، فلا تحتاج لكتابته بنفسك.
  • سطر Architectures يقرأ معمارية السيرفر تلقائياً، سواءً كانت amd64 أو arm64.
  • سطر Signed-By هو الذي يربط المفتاح بهذا المستودع وحده.

حدث الفهرس، ثم تأكد من أن الحزمة سوف تأتي من مستودع Docker:

sudo apt update
apt-cache policy docker-ce | head -n 5

والمخرج سوف يكون كما يلي، مع العلم أن رقم الإصدار يتغير بمرور الوقت:

docker-ce:
  Installed: (none)
  Candidate: 5:29.8.2-1~ubuntu.24.04~noble
  Version table:
     5:29.8.2-1~ubuntu.24.04~noble 500

تثبيت Docker Engine وإضافة Compose

سوف نثبت خمس حزم معاً: المحرك Engine، وأداة سطر الأوامر CLI، وcontainerd، وbuildx لبناء ال Images، وإضافة Compose التي توفر الأمر docker compose، ولاحظ أنه بمسافة وليس بشرطة كما في الإصدار القديم.

sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

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

apt list --all-versions docker-ce
VERSION_STRING=5:29.8.2-1~ubuntu.24.04~noble
sudo apt install -y docker-ce=$VERSION_STRING docker-ce-cli=$VERSION_STRING containerd.io docker-buildx-plugin docker-compose-plugin

الخدمة تبدأ تلقائياً بعد التثبيت على Ubuntu، ولكن تأكد من أنها مفعلة عند الإقلاع Boot وأنها تعمل فعلاً:

sudo systemctl enable --now docker containerd
sudo systemctl status docker --no-pager

ثم اختبر المحرك وتحقق من أرقام الإصدارات:

sudo docker run --rm hello-world
docker --version
docker compose version

والمخرج سوف يكون كما يلي:

Hello from Docker!
This message shows that your installation appears to be working correctly.
...
Docker version 29.8.1, build 4a63305
Docker Compose version v5.6.0

تشغيل docker دون sudo

كتابة sudo قبل كل أمر تصبح مرهقة بسرعة، خصوصاً عندما تنساها للمرة العاشرة في نفس اليوم وتعيد كتابة الأمر من جديد. ولتشغيل الأوامر بمستخدمك مباشرة أضفه إلى مجموعة Group docker، ثم اخرج من جلسة SSH وادخل من جديد (أو نفذ newgrp docker) حتى تسري العضوية Membership:

sudo usermod -aG docker $USER
newgrp docker
docker info --format '{{.ServerVersion}} {{.Driver}}'
🛑
لا تمنح العضوية في مجموعة docker إلا لمن تمنحه sudo، والسبب أنها تعادل صلاحية root على السيرفر، حيث يستطيع من يملكها تشغيل Container يركب Mount نظام الملفات Filesystem بأكمله. وتذكر أن نفس الأمر ينطبق على أي Container تتيح له الوصول إلى /var/run/docker.sock، ومنها Portainer.
📌
في أكتوبر 2019 نشر فريق Unit 42 في Palo Alto Networks تحليلاً لدودة Worm أسموها Graboid، كانت تنتشر بين محركات Docker التي تركها أصحابها مكشوفة للإنترنت دون مصادقة Authentication، ووجد الفريق أكثر من 2,000 محرك بهذا الشكل، فكانت الدودة تشغل عليها Containers لتعدين Mining عملة Monero ثم تبحث عن ضحايا جدد. والدرس أن من يصل إلى واجهة Docker يتحكم في السيرفر كله، سواءً وصل إليها عبر الشبكة أو عبر مجموعة docker.

إعدادات المحرك Daemon Configuration: تدوير السجلات وlive-restore

يحفظ Docker سجلات ال Containers افتراضياً بصيغة json-file دون أي حد للحجم، وبالتالي قد يملأ Container كثير الرسائل القرص خلال أسابيع، والحل أن تستخدم مشغل السجلات Logging Driver local الذي يضغط السجلات ويدورها تلقائياً. وسوف نضيف معه خيار live-restore الذي يبقي ال Containers عاملة عندما تعيد تشغيل Restart Docker نفسه، أثناء تحديثه مثلاً.

sudo tee /etc/docker/daemon.json <<'EOF'
{
  "log-driver": "local",
  "log-opts": {
    "max-size": "20m",
    "max-file": "5"
  },
  "live-restore": true
}
EOF

في الإعداد أعلاه لاحظ التالي:

  • السطر "log-driver": "local" يستبدل json-file بمشغل السجلات local.
  • القيمتان max-size وmax-file تعنيان أن سجل كل Container يدور على 5 ملفات حجم كل منها 20 MB، فلا يتجاوز مجموعها 100 MB مهما طال التشغيل.
  • السطر الأخير يفعل live-restore.

تحقق من صحة الملف قبل إعادة التشغيل، والسبب أن خطأ واحداً في صياغة Syntax ملف JSON يكفي لمنع الخدمة من العمل:

sudo dockerd --validate --config-file /etc/docker/daemon.json
sudo systemctl restart docker

تذكر: الإعداد الجديد يسري فقط على ال Containers التي تنشئها بعده، أما الموجودة فأعد إنشاءها Recreate بالأمر docker compose up -d --force-recreate.

انتبه: Docker يتجاوز جدار الحماية ufw

⚠️
لا تنشر على جميع الواجهات Network Interfaces إلا ما يجب أن يكون عاماً، أي المنفذين 80 و443 لل Reverse Proxy، والسبب أنك عندما تنشر Publish منفذاً بالصيغة ports: "8080:8080" يضيف Docker قواعد iptables خاصة به تسبق قواعد ufw، وبالتالي يصبح المنفذ مفتوحاً للإنترنت حتى لو لم تسمح به في ufw. أما المنافذ الإدارية فانشرها على 127.0.0.1 أو على عنوان في شبكة خاصة Private Network أو VPN، مثل "127.0.0.1:8080:8080"، ويمكنك كذلك أن تجعل ال Reverse Proxy يصل إلى ال Container عبر شبكة Docker دون نشر أي منفذ.

كيف تتأكد أن التثبيت نجح؟ Verification

  • الخدمة مفعلة وتعمل: الأمر systemctl is-active docker يعيد القيمة active، والأمر systemctl is-enabled docker يعيد القيمة enabled.
  • المستودع صحيح: الأمر apt-cache policy docker-ce يشير إلى download.docker.com.
  • Compose متاح بالصيغة الجديدة: الأمر docker compose version يعيد الإصدار v5.6.0 أو أحدث.
  • إعداد السجلات مطبق: الأمر docker info --format '{{.LoggingDriver}}' يعيد القيمة local.
  • المحرك يشغل ال Containers فعلاً:
docker run --rm hello-world

وعند تشغيل الأمر سوف تجد رسالة تبدأ بعبارة Hello from Docker!، ثم يحذف Docker ال Container تلقائياً.

النسخ الاحتياطي Backup والاستعادة Restore

Docker نفسه لا يحمل بيانات مهمة سوى إعداداته، أما بياناتك الفعلية فهي في ال Volumes الخاصة بكل تطبيق، ولكل تطبيق طريقة نسخ يشرحها دليله. وعلى مستوى Docker احفظ ما يلي:

  • /etc/docker/daemon.json (إعدادات المحرك).
  • ملفات Compose ومجلدات /opt/<app> لكل خدمة، والأفضل أن تحفظها في Git.

ولنسخ Volume دون الاعتماد على Image التطبيق شغل Container مؤقتاً يضغط محتواه في ملف، وإذا كان التطبيق يكتب فيه باستمرار كقواعد البيانات فأوقفه أولاً:

docker run --rm -v app_data:/data:ro -v "$PWD":/backup alpine:3.24 \
  tar czf /backup/app_data-$(date +%F).tar.gz -C /data .

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

التحديث Upgrade إلى إصدار أحدث

يتحدث Docker مع باقي النظام عبر apt، وإذا تغير الإصدار الرئيسي Major Version فاقرأ ملاحظات الإصدار Release Notes أولاً، ثم نفذ:

sudo apt update
apt list --upgradable 2>/dev/null | grep -E 'docker|containerd'
sudo apt install --only-upgrade docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

ومع live-restore تبقى ال Containers عاملة أثناء التحديث التصحيحي Patch Release، مثل الانتقال من 29.8.1 إلى 29.8.2، أما عند الانتقال إلى إصدار أحدث من ذلك فإن توثيق live-restore لا يضمن بقاءها، لذلك خطط لتوقف قصير. ولاحظ أن unattended-upgrades لا يحدث حزم Docker في إعداده الافتراضي، والسبب أنه يقتصر على مستودعات Ubuntu، فإذا كان السيرفر يحدث نفسه تلقائياً عبر unattended-upgrades بعد أن أضفت إليه مستودع Docker، وأردت أن تختار أنت موعد تحديث Docker، فجمد حزمه Hold ثم حررها في فترة الصيانة Maintenance Window التي تحددها:

sudo apt-mark hold docker-ce docker-ce-cli containerd.io
sudo apt-mark unhold docker-ce docker-ce-cli containerd.io

مشكلات شائعة وحلولها Troubleshooting

permission denied while trying to connect to the Docker daemon socket

هذا الخطأ يعني أن مستخدمك ليس عضواً في مجموعة docker، أو أنك لم تبدأ جلسة جديدة بعد إضافته، لذلك نفذ groups للتأكد، ثم اخرج وادخل من جديد.

Conflicting values set for option Signed-By

سوف ترى هذا الخطأ عندما يبقى تعريف قديم للمستودع من طريقة تثبيت سابقة (مثل /etc/apt/sources.list.d/docker.list)، والحل أن تحذف التعريف القديم وتبقي docker.sources وحده، ثم تنفذ sudo apt update.

لماذا لا تبدأ الخدمة بعد تعديل daemon.json؟

السبب في الغالب خطأ في صياغة JSON، حيث يحدد الأمر sudo dockerd --validate --config-file /etc/docker/daemon.json موضع الخطأ، ويعرض journalctl -u docker -n 50 سبب الفشل.

امتلاء القرص بمرور الوقت

اعرف حجم ما يستهلكه Docker بالأمر docker system df، ثم احذف ال Images غير المستخدمة بالأمر docker image prune -a بعد أن تتأكد أنك لا تحتاجها. ولكن لا تشغل docker system prune --volumes على سيرفر إنتاجي Production Server دون مراجعة، والسبب أنه يحذف كل Volume غير مرتبط بـ Container قائم، وقد يكون فيه بيانات تحتاجها.

الخلاصة

وصلنا لنهاية الموضوع، وأهم ما فيه:

  • ثبت Docker Engine على السيرفر وليس Docker Desktop، ومن المستودع الرسمي وليس من حزمة docker.io أو السكربت السريع، حتى ترى كل خطوة وتصلك التحديثات عبر apt.
  • العضوية في مجموعة docker تعادل صلاحية root، فلا تمنحها إلا لمن تمنحه sudo.
  • فعل مشغل السجلات local وlive-restore من اليوم الأول، حتى لا يمتلئ القرص بالسجلات.
  • Docker يتجاوز ufw عند نشر المنافذ، فانشر المنافذ الإدارية على 127.0.0.1 فقط.
  • بياناتك في ال Volumes وليست في Docker نفسه، فانسخها وانقل النسخة إلى خارج السيرفر.

سجل التحديثات (Changelog)

  • سبتمبر 2026: كتابة الدليل واختباره على Docker Engine 29.8.1 وDocker Compose v5.5.1 على Ubuntu 24.04.
  • أكتوبر 2026: مراجعة الدليل وتحديثه إلى Docker Engine 29.8.2، وهو إصدار يصلح ثغرات أمنية، وإلى Docker Compose v5.6.0. وأضفنا حزمة docker-buildx إلى قائمة الحزم المتعارضة كما في التوثيق الرسمي، ووضحنا حدود live-restore عند التحديث.
نشرة عرب رووت | ArabRoot

معرفة تستحق مكاناً في بريدك.

مقالات مختارة وأدوات مفيدة وأفكار لمشروعك القادم، في رسالة واحدة كل أسبوع.

يمكنك إلغاء الاشتراك متى شئت. الخصوصية

تم استلام طلبك. افتح بريدك واضغط رابط التأكيد لإتمام الاشتراك.