لوگوی هاکان سرور
لوگوی هاکان سرور

نصب داکر روی اوبونتو 24.04 و 26.04 + Docker Compose و میرور ایران

نهنگ داکر با کانتینرهای روی هم کنار رک سرور با نشان اوبونتو
فهرست مطالب
  1. داکر چیست و چه مشکلی را حل می‌کند؟
  2. ۵ مفهوم اصلی داکر به زبان ساده
  3. کانتینر داکر یا ماشین مجازی؟
  4. پیش‌نیازهای نصب داکر روی اوبونتو
  5. نسخهٔ اوبونتو و معماری پردازنده
  6. نوع مجازی‌سازی سرور
  7. منابع پیشنهادی سرور
  8. حذف بسته‌های قدیمی و ناسازگار
  9. نصب داکر از مخزن رسمی، گام‌به‌گام
  10. گام ۱: افزودن کلید و مخزن apt داکر
  11. گام ۲: نصب بسته‌های داکر
  12. گام ۳: بررسی صحت نصب
  13. مقایسهٔ روش‌های نصب داکر
  14. داکر روی سرورهای داخل ایران
  15. چه چیزی مسدود است و چطور تشخیص بدهید؟
  16. نصب موتور داکر بدون دسترسی به مخزن رسمی
  17. تنظیم میرور رجیستری (Registry Mirror)
  18. انتقال ایمیج بدون رجیستری
  19. تنظیمات ضروری بعد از نصب داکر
  20. اجرای داکر بدون sudo
  21. اجرای خودکار داکر بعد از ریبوت
  22. محدود کردن حجم لاگ کانتینرها
  23. داکر و فایروال UFW
  24. اجرای اولین کانتینر با Nginx
  25. دستورات پرکاربرد داکر
  26. Docker Compose با مثال واقعی: وردپرس و MariaDB
  27. ساخت پوشهٔ پروژه و فایل .env
  28. فایل compose.yaml
  29. اجرا و مدیریت پروژه
  30. بکاپ و به‌روزرسانی
  31. رفع خطاهای رایج داکر
  32. permission denied روی docker.sock
  33. خطای toomanyrequests
  34. پورت از قبل اشغال است
  35. no space left on device
  36. Cannot connect to the Docker daemon
  37. خطاهای apt هنگام نصب
  38. امنیت و نگهداری داکر روی سرور
  39. سرور مناسب برای اجرای داکر
  40. پرسش‌های متداول
  41. آیا داکر رایگان است؟
  42. فرق docker.io و docker-ce چیست؟
  43. docker compose با docker-compose چه فرقی دارد؟
  44. چرا docker pull روی سرور ایران خطای 403 می‌دهد؟
  45. برای داکر چقدر رم لازم است؟
  46. چطور داکر را کامل از اوبونتو حذف کنم؟
  47. جمع‌بندی

برای نصب داکر روی اوبونتو 24.04 یا 26.04 کافی است مخزن رسمی apt داکر را اضافه کنید و بسته‌های docker-ce و docker-compose-plugin را نصب کنید. در این راهنما همهٔ دستورها را به ترتیب و با خروجی مورد انتظار می‌بینید، از تنظیمات بعد از نصب تا یک پروژهٔ واقعی با Docker Compose.

بیشتر آموزش‌ها با اجرای hello-world تمام می‌شوند. اما روی سرورهای داخل ایران همین آزمایش ساده معمولاً با خطای 403 شکست می‌خورد، چون Docker Hub آی‌پی‌های ایران را مسدود کرده است. راه‌حل این مشکل هم در ادامه آمده است. دستورها با مستندات رسمی داکر در آبان ۱۴۰۵ تطبیق داده شده‌اند و روی Ubuntu 22.04 هم کار می‌کنند.

به‌طور خلاصه: نصب داکر روی اوبونتو در ۶ گام انجام می‌شود:

  1. بسته‌های ناسازگار مثل docker.io، containerd و runc را حذف کنید.
  2. کلید GPG داکر را در /etc/apt/keyrings/docker.asc ذخیره کنید.
  3. فایل مخزن /etc/apt/sources.list.d/docker.sources را بسازید.
  4. بسته‌های docker-ce، docker-ce-cli، containerd.io، docker-buildx-plugin و docker-compose-plugin را نصب کنید.
  5. اگر سرور داخل ایران است، registry-mirrors را در /etc/docker/daemon.json تنظیم کنید.
  6. کاربرتان را به گروه docker اضافه کنید و حجم لاگ‌ها را محدود کنید.

داکر چیست و چه مشکلی را حل می‌کند؟

داکر (Docker) برنامه را همراه با همهٔ وابستگی‌هایش، مثل نسخهٔ مشخص PHP یا Node.js و کتابخانه‌ها، در یک بستهٔ استاندارد به نام کانتینر (Container) اجرا می‌کند. این بسته روی هر سرور لینوکسی که داکر داشته باشد به یک شکل اجرا می‌شود.

مثال عملی: اگر روی یک سرور دو سایت با نسخه‌های متفاوت PHP دارید، نصب مستقیم روی سیستم‌عامل به تداخل می‌رسد. با داکر هر سرویس در کانتینر خودش اجرا می‌شود و کل پروژه در یک فایل متنی تعریف می‌شود که به‌راحتی به سرور دیگر منتقل می‌شود.

۵ مفهوم اصلی داکر به زبان ساده

مفهوم یعنی چه؟ مثال
ایمیج (Image) قالب فقط‌خواندنی شامل برنامه و وابستگی‌ها nginx:1.30
کانتینر (Container) نمونهٔ در حال اجرای یک ایمیج؛ با حذفش تغییرات داخلش هم پاک می‌شود web
والیوم (Volume) فضای ماندگار بیرون از کانتینر برای داده‌ها db_data
شبکه (Network) شبکهٔ مجازی که کانتینرها در آن یکدیگر را با نام پیدا می‌کنند wordpress_default
رجیستری (Registry) مخزنی که ایمیج‌ها از آن دانلود (pull) می‌شوند Docker Hub

Dockerfile دستور ساخت یک ایمیج اختصاصی است. Docker Compose هم چند کانتینر مرتبط را در یک فایل YAML تعریف و با یک دستور اجرا می‌کند.

کانتینر داکر یا ماشین مجازی؟

ویژگی کانتینر داکر ماشین مجازی (VM)
کرنل مشترک با میزبان سیستم‌عامل کامل و جدا
زمان راه‌اندازی معمولاً چند ثانیه ده‌ها ثانیه تا چند دقیقه
مصرف رم پایه کم به اندازهٔ یک سیستم‌عامل
ایزوله‌سازی کمتر بیشتر

این دو رقیب هم نیستند: سرور مجازی (VPS) خودش یک ماشین مجازی است و داکر داخل آن نصب می‌شود.

پیش‌نیازهای نصب داکر روی اوبونتو

نسخهٔ اوبونتو و معماری پردازنده

مستندات رسمی داکر در زمان نوشتن این مطلب Ubuntu 26.10، 26.04 LTS، 24.04 LTS و 22.04 LTS را پشتیبانی می‌کند، روی معماری‌های amd64، arm64، s390x، ppc64el و armhf (ARM ۳۲ بیتی، فقط ARMv7 به بالا). Ubuntu 20.04 دیگر در فهرست نیست و توزیع‌های مشتق مثل Linux Mint هم رسماً پشتیبانی نمی‌شوند.

. /etc/os-release && echo "$VERSION_ID $VERSION_CODENAME"
dpkg --print-architecture

خروجی روی Ubuntu 24.04 به شکل 24.04 noble و amd64 است. اسم رمز Ubuntu 26.04 هم resolute است.

نوع مجازی‌سازی سرور

داکر به قابلیت‌هایی از کرنل مثل namespaces، cgroups و overlayfs نیاز دارد. روی سرور اختصاصی و سرور مجازی با مجازی‌سازی کامل (KVM، VMware، Hyper-V) مشکلی نیست. اما روی سرورهای کانتینری مثل OpenVZ یا LXC ممکن است اجرا نشود.

systemd-detect-virt

خروجی‌هایی مثل kvm، qemu، xen، vmware، microsoft یا none (سرور اختصاصی) مناسب است. اگر openvz یا lxc دیدید، پیش از ادامه با ارائه‌دهندهٔ سرور هماهنگ کنید.

منابع پیشنهادی سرور

مستندات داکر برای Docker Engine روی لینوکس حداقل رم مشخصی اعلام نمی‌کند. خود داکر سبک است و منابع را کانتینرها تعیین می‌کنند. جدول زیر تخمینی تجربی برای شروع است:

کاربرد پردازنده رم دیسک
یادگیری و چند کانتینر سبک ۱ هسته ۱ گیگابایت ۲۰ گیگابایت
وردپرس و MariaDB ۲ هسته ۲ گیگابایت ۴۰ گیگابایت
چند سرویس یا ساخت ایمیج روی سرور ۴ هسته ۴ تا ۸ گیگابایت ۸۰ گیگابایت به بالا

دیسک را دست‌کم نگیرید. ایمیج‌ها از چند ده تا چند صد مگابایت حجم دارند و نسخه‌های قدیمی و لاگ‌ها بی‌صدا جمع می‌شوند. برای همهٔ مراحل این راهنما یک سرور لینوکس با Ubuntu 24.04 یا 26.04 کافی است.

حذف بسته‌های قدیمی و ناسازگار

با کاربری که دسترسی sudo دارد از طریق SSH وصل شوید (آموزش اتصال به سرور لینوکسی از طریق SSH). بسته‌های غیررسمی داکر در مخزن اوبونتو با بسته‌های رسمی تداخل دارند. این دستور از مستندات رسمی است و فقط بسته‌های نصب‌شده را حذف می‌کند:

sudo apt remove $(dpkg --get-selections docker.io docker-compose docker-compose-v2 docker-doc docker-buildx podman-docker containerd runc | cut -f1)

اگر apt گفت هیچ‌کدام نصب نیستند، مشکلی نیست. داده‌های قبلی در /var/lib/docker با این دستور پاک نمی‌شوند.

نصب داکر از مخزن رسمی، گام‌به‌گام

این روش پیشنهادی داکر برای سرورهاست و به‌روزرسانی‌های بعدی را هم با apt upgrade انجام می‌دهد.

نکته: اگر سرورتان داخل ایران است، پیش از گام ۱ آزمون دسترسی بخش «داکر روی سرورهای داخل ایران» را اجرا کنید. اگر download.docker.com باز نیست، مستقیم سراغ «نصب موتور داکر بدون دسترسی به مخزن رسمی» بروید.

گام ۱: افزودن کلید و مخزن apt داکر

# Add Docker's official GPG key
sudo apt update
sudo apt install ca-certificates curl
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

# Add the repository to apt sources (deb822 format)
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

sudo apt update

دو تفاوت با آموزش‌های قدیمی دارد. فایل مخزن حالا با قالب deb822 و پسوند .sources ساخته می‌شود، نه یک خط در docker.list. اسم رمز توزیع هم از UBUNTU_CODENAME خوانده می‌شود، پس روی 24.04 مقدار noble و روی 26.04 مقدار resolute نوشته می‌شود. برای اطمینان:

apt-cache policy docker-ce

جلوی Candidate باید نسخه‌ای مثل 5:29.9.2-1~ubuntu.24.04~noble از download.docker.com ببینید. Candidate: (none) یعنی مخزن درست اضافه نشده است.

گام ۲: نصب بسته‌های داکر

sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
بسته کاربرد
docker-ce موتور داکر (سرویس dockerd)
docker-ce-cli دستور docker
containerd.io لایهٔ اجرای کانتینر (containerd و runc)
docker-buildx-plugin ساخت ایمیج با BuildKit
docker-compose-plugin دستور docker compose

گام ۳: بررسی صحت نصب

روی اوبونتو سرویس داکر بعد از نصب خودکار اجرا می‌شود:

sudo systemctl is-active docker
docker --version
docker compose version

خروجی در زمان نوشتن این مطلب (نسخهٔ جدیدتر هم طبیعی است):

active
Docker version 29.9.2, build a82e528
Docker Compose version v5.6.1

Compose نسخهٔ v5 طبق مستندات داکر از نظر کارکرد با v2 یکی است. شماره‌گذاری مستقیم به 5 رسیده تا با قالب‌های قدیمی فایل Compose اشتباه نشود. حالا کانتینر آزمایشی را اجرا کنید:

sudo docker run hello-world

اگر همه‌چیز درست باشد، این دو خط را می‌بینید:

Hello from Docker!
This message shows that your installation appears to be working correctly.

نکته: اگر سرور در ایران است و این دستور با 403 Forbidden یا timeout شکست خورد، نصب ایرادی ندارد. فقط دسترسی به Docker Hub بسته است. بخش «داکر روی سرورهای داخل ایران» را در ادامه انجام دهید و دوباره امتحان کنید.

مقایسهٔ روش‌های نصب داکر

روش منبع مناسب برای
مخزن رسمی (همین راهنما) download.docker.com سرور عملیاتی؛ آخرین نسخهٔ پایدار
بستهٔ docker.io مخزن اوبونتو وقتی مخزن داکر در دسترس نیست
اسکریپت get.docker.com مخزن رسمی، خودکار فقط محیط تست، طبق توصیهٔ داکر
فایل‌های .deb دانلود دستی سرور بدون دسترسی به مخزن
Snap Snap Store برای سرور پیشنهاد نمی‌شود

داکر روی سرورهای داخل ایران

چه چیزی مسدود است و چطور تشخیص بدهید؟

Docker Hub به استناد مقررات کنترل صادرات آمریکا آی‌پی‌های واقع در ایران را مسدود می‌کند. پاسخش 403 Forbidden با متن Since Docker is a US company, we must comply with US export control regulations است. این محدودیت docker login را هم شامل می‌شود. دسترسی به download.docker.com روی همهٔ شبکه‌های داخلی یکسان نیست و اختلال‌های اتصال بین‌المللی هم به‌صورت timeout ظاهر می‌شوند. وضعیت سرور خودتان را بسنجید:

curl -sI -m 10 https://download.docker.com/linux/ubuntu/gpg | head -n 1
curl -sI -m 10 https://registry-1.docker.io/v2/ | head -n 1
خروجی معنی
HTTP/2 200 در خط اول مخزن apt داکر در دسترس است
HTTP/2 401 در خط دوم رجیستری در دسترس است؛ 401 اینجا طبیعی است
HTTP/2 403 مسدود به دلیل تحریم
خروجی خالی پس از ۱۰ ثانیه اختلال شبکه یا اتصال بین‌المللی

نصب موتور داکر بدون دسترسی به مخزن رسمی

اگر download.docker.com باز نمی‌شود، از بسته‌های خود اوبونتو استفاده کنید که سرورهای داخل ایران معمولاً از میرور داخلی دریافت می‌کنند. اگر در گام ۱ فایل docker.sources را ساخته‌اید، اول حذفش کنید، وگرنه apt update مدام خطا می‌دهد:

sudo rm -f /etc/apt/sources.list.d/docker.sources /etc/apt/keyrings/docker.asc
sudo apt update
sudo apt install docker.io docker-compose-v2 docker-buildx

در زمان نوشتن این مطلب نسخهٔ docker.io در مخزن به‌روزرسانی‌های Ubuntu 24.04 و 26.04 برابر 29.1.3 و docker-compose-v2 برابر 2.40.3 است. همهٔ دستورهای این مقاله با آن‌ها کار می‌کنند. فقط آن‌ها را با بسته‌های رسمی (docker-ce) هم‌زمان نصب نکنید.

راه دوم نصب از فایل .deb است. روی سیستمی که به سایت داکر دسترسی دارد، فایل‌های containerd.io، docker-ce، docker-ce-cli، docker-buildx-plugin و docker-compose-plugin را از https://download.docker.com/linux/ubuntu/dists/noble/pool/stable/amd64/ دانلود کنید (برای 26.04 به‌جای noble بنویسید resolute) و با scp به سرور ببرید. از همان پوشه با apt نصبشان کنید، نه dpkg -i، تا وابستگی‌هایی مثل iptables از میرور اوبونتو گرفته شود. به‌روزرسانی‌ها در این روش دستی است:

sudo apt install ./containerd.io_*.deb ./docker-ce_*.deb ./docker-ce-cli_*.deb \
  ./docker-buildx-plugin_*.deb ./docker-compose-plugin_*.deb

اگر از یک میرور داخلی مخزن apt داکر استفاده می‌کنید، اثر انگشت کلید را با gpg --show-keys /etc/apt/keyrings/docker.asc ببینید. اثر انگشت کلید رسمی داکر 9DC858229FC7DD38854AE2D88D81803C0EBFCD88 است و اگر چیز دیگری دیدید، از آن مخزن استفاده نکنید.

تنظیم میرور رجیستری (Registry Mirror)

برای دریافت ایمیج‌های Docker Hub روی سرور ایران، داکر را طوری تنظیم کنید که درخواست‌ها را اول به یک میرور بفرستد. چند شرکت ایرانی میرور عمومی Docker Hub دارند. نمونهٔ شناخته‌شده‌اش میرور آروان‌کلاد با آدرس https://docker.arvancloud.ir است که در زمان نوشتن این مطلب پاسخ می‌داد. فایل /etc/docker/daemon.json را با sudo nano بسازید (به‌طور پیش‌فرض وجود ندارد). دو کلید مربوط به لاگ را هم از همین حالا بگذارید. توضیحشان در بخش بعد آمده است:

{
  "registry-mirrors": ["https://docker.arvancloud.ir"],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3"
  }
}
sudo dockerd --validate --config-file=/etc/docker/daemon.json
sudo systemctl restart docker
sudo docker info | grep -A1 "Registry Mirrors"
sudo docker pull hello-world

خروجی docker info باید آدرس میرور را نشان دهد و docker pull باید کامل شود. تا کاربرتان عضو گروه docker نشده است (بخش بعد)، دستورهای داکر را با sudo اجرا کنید. چند نکته:

  • registry-mirrors فقط برای ایمیج‌های Docker Hub کار می‌کند. ایمیج‌های ghcr.io، quay.io و رجیستری‌های دیگر از میرور عبور نمی‌کنند و دسترسی به آن‌ها را باید جداگانه آزمایش کنید.
  • می‌توانید چند میرور را به ترتیب در آرایه بنویسید. اگر میرور اول پاسخ ندهد، داکر سراغ بعدی و در آخر سراغ خود Docker Hub می‌رود.
  • میرور واسطهٔ شخص ثالث است. فقط از اپراتورهای شناخته‌شده و ایمیج‌های رسمی با تگ مشخص استفاده کنید.

انتقال ایمیج بدون رجیستری

ایمیج را روی سیستمی با دسترسی به Docker Hub (مثلاً سروری خارج از ایران) دانلود و به‌صورت فایل منتقل کنید. اگر مبدأ مک با تراشهٔ Apple است، پلتفرم را صریح بنویسید. گزینهٔ --platform در docker save از Docker 28 به بعد وجود دارد:

# On a machine with Docker Hub access
docker pull --platform linux/amd64 nginx:1.30
docker save --platform linux/amd64 -o nginx-1.30.tar nginx:1.30
scp nginx-1.30.tar user@SERVER_IP:/tmp/

# On the server
sudo docker load -i /tmp/nginx-1.30.tar

تنظیمات ضروری بعد از نصب داکر

اجرای داکر بدون sudo

سوکت داکر (/var/run/docker.sock) فقط برای root و اعضای گروه docker باز است. بستهٔ رسمی این گروه را می‌سازد و کافی است کاربرتان را اضافه کنید:

sudo usermod -aG docker $USER
newgrp docker
docker ps

اگر docker ps بدون sudo یک جدول خالی (فقط سرستون‌ها) نشان داد، دسترسی درست است. newgrp عضویت را فقط در همان ترمینال فعال می‌کند. برای اعمال کامل یک بار از SSH خارج و دوباره وارد شوید.

هشدار: عضویت در گروه docker عملاً معادل دسترسی root است، چون هر عضو می‌تواند کانتینری بسازد که فایل‌سیستم میزبان را mount کند. فقط کاربرهای مورد اعتماد را عضو کنید. برای ایزوله‌سازی بیشتر، حالت Rootless داکر را ببینید.

اجرای خودکار داکر بعد از ریبوت

روی اوبونتو سرویس‌های docker و containerd به‌طور پیش‌فرض هنگام بوت فعال‌اند. خروجی systemctl is-enabled docker containerd باید دو بار enabled باشد. اگر نبود، sudo systemctl enable --now docker containerd را بزنید. اما کانتینرها فقط وقتی بعد از ریبوت بالا می‌آیند که سیاست ری‌استارت (restart policy) مثل unless-stopped داشته باشند. مقدار پیش‌فرض این سیاست no است.

همین قاعده برای ری‌استارت خود سرویس داکر هم برقرار است. هر ری‌استارت، چه بعد از تغییر daemon.json و چه هنگام ارتقای بسته، همهٔ کانتینرها را متوقف می‌کند و فقط کانتینرهای دارای سیاست ری‌استارت دوباره بالا می‌آیند. روی سرور عملیاتی می‌توانید "live-restore": true را به daemon.json اضافه کنید و با sudo systemctl reload docker اعمال کنید. با این گزینه کانتینرها هنگام ری‌استارت سرویس و ارتقاهای وصله‌ای (مثلاً 29.9.1 به 29.9.2) اجرا می‌مانند.

محدود کردن حجم لاگ کانتینرها

درایور لاگ پیش‌فرض داکر (json-file) بدون تنظیم، لاگ را بدون سقف نگه می‌دارد و یک کانتینر پرحرف می‌تواند دیسک را پر کند. اگر در بخش قبل daemon.json را با میرور ساختید، این کلیدها در آن هستند. در غیر این صورت /etc/docker/daemon.json را با این محتوا بسازید:

{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3"
  }
}

هر کانتینر حداکثر ۳ فایل ۱۰ مگابایتی نگه می‌دارد. مقدارها، حتی عدد ۳، باید داخل علامت نقل‌قول انگلیسی (") باشند. پیش از ری‌استارت فایل را اعتبارسنجی کنید تا یک ویرگول جاافتاده سرویس را از کار نیندازد:

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

خروجی سالم configuration OK است. تنظیم فقط روی کانتینرهای جدید اعمال می‌شود. کانتینرهای فعلی را با docker compose up -d --force-recreate دوباره بسازید.

داکر و فایروال UFW

نکتهٔ امنیتی مهم: پورت‌هایی که با -p منتشر می‌کنید، از قوانین UFW عبور می‌کنند. داکر ترافیک کانتینرها را در جدول nat مسیریابی می‌کند، پیش از آنکه به زنجیره‌های UFW برسد. پس اگر دیتابیس را با -p 3306:3306 اجرا کنید، ufw deny 3306 جلوی اینترنت را نمی‌گیرد. راه درست انتشار پورت روی 127.0.0.1 و دسترسی بیرونی از طریق یک پروکسی معکوس (Reverse Proxy) مثل Nginx است:

docker run -d --name web -p 127.0.0.1:8080:80 nginx:1.30
docker ps --format '{{.Names}}  {{.Ports}}'

باید 127.0.0.1:8080->80/tcp ببینید، نه 0.0.0.0:8080. برای قوانین پیشرفته‌تر از زنجیرهٔ DOCKER-USER در iptables استفاده کنید. تنظیمات پایهٔ UFW را در مقالهٔ فعال‌سازی فایروال در لینوکس ببینید.

اجرای اولین کانتینر با Nginx

اگر در بخش فایروال کانتینری با نام web ساختید، اول آن را با docker rm -f web حذف کنید:

docker run -d --name web -p 8080:80 --restart unless-stopped nginx:1.30
curl -I http://localhost:8080

-d کانتینر را در پس‌زمینه اجرا می‌کند، -p 8080:80 پورت 8080 سرور را به پورت 80 کانتینر وصل می‌کند و --restart unless-stopped آن را بعد از ریبوت بالا می‌آورد. خط اول خروجی curl باید HTTP/1.1 200 OK باشد. این کانتینر طبق نکتهٔ UFW از اینترنت هم باز است. بعد از آزمایش حذفش کنید. برای نمایش فایل‌های خودتان، پوشه را فقط‌خواندنی به مسیر پیش‌فرض Nginx وصل کنید:

docker rm -f web
mkdir -p ~/site && echo "it works" > ~/site/index.html
docker run -d --name web -p 127.0.0.1:8080:80 -v ~/site:/usr/share/nginx/html:ro nginx:1.30

همیشه تگ نسخه را بنویسید (nginx:1.30، نه latest) تا هر pull بی‌خبر نسخهٔ اصلی را عوض نکند.

دستورات پرکاربرد داکر

دستور کاربرد
docker ps -a همهٔ کانتینرها، حتی متوقف‌شده‌ها
docker images ایمیج‌های موجود روی سرور
docker logs -f --tail 100 web دیدن زندهٔ ۱۰۰ خط آخر لاگ
docker exec -it web sh باز کردن شل داخل کانتینر
docker stop web / docker start web توقف و اجرای دوباره
docker rm web / docker rmi nginx:1.30 حذف کانتینر / حذف ایمیج
docker stats مصرف لحظه‌ای CPU و رم
docker system df فضای اشغال‌شده توسط داکر

Docker Compose با مثال واقعی: وردپرس و MariaDB

وقتی پروژه بیش از یک کانتینر دارد، Docker Compose همه‌چیز را در یک فایل compose.yaml نگه می‌دارد. این مثال برای یادگیری Compose و پروژه‌هایی است که کنترل کامل سرور را لازم دارند. اگر فقط یک سایت وردپرسی ساده می‌خواهید و نمی‌خواهید سرور را خودتان نگه دارید، هاست وردپرس کم‌دردسرتر است. سه نکتهٔ به‌روز دربارهٔ Compose:

  • دستور درست docker compose (با فاصله) است. ابزار قدیمی docker-compose (نسخهٔ ۱، پایتونی) دیگر پشتیبانی نمی‌شود.
  • نام پیشنهادی فایل compose.yaml است. docker-compose.yml هم برای سازگاری خوانده می‌شود.
  • کلید version: منسوخ شده است و فقط هشدار تولید می‌کند. آن را ننویسید.

ساخت پوشهٔ پروژه و فایل .env

mkdir -p ~/wordpress && cd ~/wordpress
openssl rand -base64 24
nano .env

openssl را دو بار اجرا کنید و دو رمز تصادفی را در .env بگذارید. بعد با chmod 600 .env دسترسی دیگران را ببندید:

MARIADB_ROOT_PASSWORD=PUT-FIRST-RANDOM-PASSWORD-HERE
MARIADB_PASSWORD=PUT-SECOND-RANDOM-PASSWORD-HERE

فایل compose.yaml

services:
  db:
    image: mariadb:12.3
    restart: unless-stopped
    environment:
      MARIADB_DATABASE: wordpress
      MARIADB_USER: wordpress
      MARIADB_PASSWORD: ${MARIADB_PASSWORD}
      MARIADB_ROOT_PASSWORD: ${MARIADB_ROOT_PASSWORD}
    volumes:
      - db_data:/var/lib/mysql
    healthcheck:
      test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
      start_period: 10s
      interval: 10s
      timeout: 5s
      retries: 3

  wordpress:
    image: wordpress:7.1-apache
    restart: unless-stopped
    depends_on:
      db:
        condition: service_healthy
    ports:
      - "127.0.0.1:8080:80"
    environment:
      WORDPRESS_DB_HOST: db
      WORDPRESS_DB_NAME: wordpress
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD: ${MARIADB_PASSWORD}
    volumes:
      - wp_data:/var/www/html

volumes:
  db_data:
  wp_data:
  • تگ‌های ثابت: mariadb:12.3 نسخهٔ LTS فعلی MariaDB است. برای دیتابیس از latest استفاده نکنید، چون ارتقای ناخواستهٔ نسخهٔ اصلی دردسرساز است.
  • healthcheck: اسکریپت healthcheck.sh داخل ایمیج رسمی MariaDB هست. با condition: service_healthy وردپرس تا آماده‌شدن دیتابیس صبر می‌کند و خطای اتصال اولیه نمی‌دهد.
  • WORDPRESS_DB_HOST: db: سرویس‌های یک پروژه همدیگر را با نام پیدا می‌کنند. پورت دیتابیس اصلاً منتشر نشده است.
  • والیوم‌های نام‌دار داده‌ها را هنگام حذف یا به‌روزرسانی کانتینرها نگه می‌دارند و 127.0.0.1:8080 وردپرس را فقط روی خود سرور باز می‌کند.

اجرا و مدیریت پروژه

docker compose config --quiet
docker compose up -d
docker compose ps
docker compose logs -f wordpress

دستور اول فایل را اعتبارسنجی می‌کند و اگر خطایی نباشد چیزی چاپ نمی‌کند. در خروجی docker compose ps باید جلوی سرویس db عبارت (healthy) را ببینید. برای اطمینان از بالا آمدن وردپرس، از کامپیوتر خودتان تونل SSH بزنید و http://localhost:8080 را در مرورگر باز کنید:

ssh -L 8080:127.0.0.1:8080 user@SERVER_IP

هشدار: مراحل نصب وردپرس را از طریق تونل کامل نکنید. وردپرس آدرسی را که هنگام نصب با آن باز شده، به‌عنوان آدرس سایت ذخیره می‌کند و بعداً همهٔ صفحه‌ها به localhost هدایت می‌شوند. اول دامنه و پروکسی معکوس با SSL را جلوی پورت 8080 آماده کنید، بعد نصب را از نشانی https دامنهٔ خودتان انجام دهید.

پروکسی باید نام دامنه و پروتکل را به وردپرس برساند. فایل wp-config.php ایمیج رسمی هدر X-Forwarded-Proto را می‌خواند. در Nginx این خط‌ها را داخل بلوک location / بگذارید:

proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

بکاپ و به‌روزرسانی

نام کامل والیوم از نام پوشهٔ پروژه و نام تعریف‌شده در فایل ساخته می‌شود، اینجا wordpress_wp_data (با docker volume ls ببینید). از داخل پوشهٔ پروژه:

docker compose exec -T db sh -c 'mariadb-dump -uroot -p"$MARIADB_ROOT_PASSWORD" --single-transaction --databases wordpress' > db-$(date +%F).sql
docker run --rm -v wordpress_wp_data:/data -v "$PWD":/backup alpine:3.24 tar czf /backup/wp-files-$(date +%F).tar.gz -C /data .

--single-transaction از جدول‌های InnoDB یک نسخهٔ سازگار می‌گیرد، بی‌آنکه سایت را قفل کند. بکاپی که بازگردانی‌اش را امتحان نکرده‌اید، قابل اتکا نیست. برای بازگردانی، به‌جای تاریخ نمونه نام فایل خودتان را بنویسید:

docker compose exec -T db sh -c 'mariadb -uroot -p"$MARIADB_ROOT_PASSWORD"' < db-2026-10-28.sql
docker run --rm -v wordpress_wp_data:/data -v "$PWD":/backup alpine:3.24 tar xzf /backup/wp-files-2026-10-28.tar.gz -C /data

برای به‌روزرسانی، ایمیج‌ها را دوباره بگیرید و کانتینرها را بازسازی کنید. داده‌ها در والیوم‌ها می‌مانند:

docker compose pull
docker compose up -d
docker image prune -f

این دستورها فقط PHP، Apache و MariaDB را به‌روز می‌کنند. ایمیج رسمی وردپرس فایل‌هایش را فقط بار اول در والیوم wp_data کپی می‌کند. پس هستهٔ وردپرس، افزونه‌ها و پوسته‌ها را باید از پیشخوان وردپرس به‌روز کنید، حتی اگر تگ ایمیج را عوض کرده باشید.

هشدار: docker compose down والیوم‌ها را نگه می‌دارد، اما docker compose down -v آن‌ها را هم پاک می‌کند، یعنی کل دیتابیس و فایل‌های وردپرس از بین می‌روند.

رفع خطاهای رایج داکر

permission denied روی docker.sock

نشانه: permission denied while trying to connect to the docker API at unix:///var/run/docker.sock (در نسخه‌های قدیمی‌تر ...the Docker daemon socket at...). علت: کاربر عضو گروه docker نیست یا بعد از عضویت دوباره وارد نشده است. راه‌حل: sudo usermod -aG docker $USER و خروج و ورود دوباره. سراغ chmod 666 روی سوکت نروید، چون به همهٔ کاربرهای سرور دسترسی root می‌دهد. اگر بعدش خطای دسترسی روی ~/.docker/config.json دیدید، مالکیت را برگردانید: sudo chown "$USER":"$USER" ~/.docker -R

خطای toomanyrequests

نشانه: toomanyrequests: You have reached your pull rate limit با کد پاسخ 429. علت: Docker Hub برای کاربران بدون ورود سقف ۱۰۰ pull در هر ۶ ساعت به ازای هر آی‌پی IPv4 دارد و برای حساب رایگان Personal سقف ۲۰۰ pull در همین بازه. راه‌حل: روی سرور خارج از ایران با docker login وارد شوید، یا از میرور و کش محلی استفاده کنید.

پورت از قبل اشغال است

  • Bind for 0.0.0.0:80 failed: port is already allocated: کانتینر دیگری پورت را گرفته است. با docker ps --filter publish=80 پیدایش کنید.
  • failed to bind host port 0.0.0.0:80/tcp: address already in use: برنامه‌ای روی خود سرور، معمولاً Apache یا Nginx، روی پورت است. با sudo ss -ltnp 'sport = :80' پیدایش کنید.

راه‌حل: آن سرویس را متوقف کنید یا پورت سمت سرور را عوض کنید، مثلاً -p 8081:80. عدد سمت راست (پورت کانتینر) ثابت می‌ماند.

no space left on device

علت: معمولاً ایمیج‌های قدیمی، کش build یا لاگ‌های بدون سقف. راه‌حل: اول ببینید فضا کجا رفته است. روی نصب تازهٔ Docker 29 به بعد، ایمیج‌ها و لایه‌های کانتینر در /var/lib/containerd ذخیره می‌شوند، نه در /var/lib/docker. پس هر دو را بررسی کنید:

df -h /var/lib/docker /var/lib/containerd
sudo du -sh /var/lib/docker /var/lib/containerd
docker system df

docker image prune -a همهٔ ایمیج‌هایی را که هیچ کانتینری (حتی متوقف‌شده) از آن‌ها استفاده نمی‌کند حذف می‌کند و پیش از تأیید فهرستی نشان نمی‌دهد. پس اول با docker image ls و docker ps -a ببینید چه چیزی پاک می‌شود، بعد ایمیج‌ها و کش build را پاک کنید:

docker image prune -a
docker builder prune

با والیوم‌ها محتاط باشید: docker volume prune -a والیوم نام‌دار هر پروژه‌ای را که کانتینرهایش را با docker compose down حذف کرده‌اید هم پاک می‌کند. سپس برای لاگ‌ها سقف بگذارید. اگر دیسک اصلی کوچک است، محل ذخیره را به دیسک دیگری ببرید. کلید data-root در daemon.json فقط /var/lib/docker (والیوم‌ها و لاگ کانتینرها) را جابه‌جا می‌کند. برای ایمیج‌ها باید کلید root را در /etc/containerd/config.toml هم تغییر دهید. برای بقیهٔ فایل‌های حجیم، خطای Disk Full در لینوکس را ببینید.

Cannot connect to the Docker daemon

نشانه: Cannot connect to the Docker daemon at unix:///var/run/docker.sock یا در نسخه‌های جدید failed to connect to the docker API. علت: سرویس اجرا نشده و شایع‌ترین دلیلش خطای نگارشی در daemon.json است. راه‌حل:

sudo systemctl status docker
sudo journalctl -u docker --no-pager -n 50
sudo dockerd --validate --config-file=/etc/docker/daemon.json

خطاهای apt هنگام نصب

  • Conflicting values set for option Signed-By: فایل قدیمی docker.list و فایل جدید docker.sources هر دو وجود دارند. sudo rm /etc/apt/sources.list.d/docker.list و سپس sudo apt update.
  • Unable to locate package docker-ce: مخزن اضافه نشده، بعد از افزودنش apt update اجرا نشده، یا download.docker.com در دسترس نیست. خروجی apt update را برای 403 یا timeout بخوانید.

امنیت و نگهداری داکر روی سرور

  • سوکت داکر را به کانتینرها ندهید، مگر واقعاً لازم باشد. mount کردن /var/run/docker.sock یعنی دسترسی root سرور برای آن کانتینر.
  • فقط ایمیج رسمی یا معتبر با تگ ثابت استفاده کنید. ایمیج‌های ناشناس ممکن است بدافزار داشته باشند.
  • به‌روز بمانید: موتور داکر با sudo apt update && sudo apt upgrade و کانتینرها با docker compose pull. ارتقای docker-ce سرویس را ری‌استارت می‌کند و بدون live-restore کانتینرها لحظاتی قطع می‌شوند، پس آن را در ساعت کم‌ترافیک انجام دهید.
  • والیوم بکاپ نیست. با از دست رفتن دیسک، والیوم هم از بین می‌رود. بکاپ منظم را بیرون از سرور نگه دارید.

سرور مناسب برای اجرای داکر

داکر معمولاً به سرور لینوکس با دسترسی root و مجازی‌سازی کامل (مثل KVM) نیاز دارد و روی هاست اشتراکی نصب نمی‌شود. برای یک سایت ساده، هاست اشتراکی کم‌دردسرتر است. برای چند سرویس، اپ اختصاصی یا محیط توسعه، سرور مجازی منطقی‌تر است. هاکان سرور، سرور مجازی را در ۵۲ لوکیشن ارائه می‌کند. روی همهٔ لوکیشن‌ها همهٔ سیستم‌عامل‌ها، از جمله لینوکس و ویندوز، قابل تحویل است. تحویل سرویس خودکار و کمتر از یک ساعت است.

اگر کارتان مدام به Docker Hub، GitHub یا APIهای خارجی وابسته است، لوکیشنی مثل سرور مجازی آلمان کار را ساده‌تر می‌کند. اگر کاربران‌تان در ایران هستند یا داده باید داخل کشور بماند، سرور مجازی ایران همراه با میرور رجیستری معمولاً کافی است. فقط دسترسی به رجیستری‌های دیگر مثل ghcr.io را جداگانه بسنجید. فهرست همهٔ لوکیشن‌ها در صفحهٔ خرید سرور مجازی است. اگر کانتینرها بعداً منابع بیشتری خواستند، ارتقای منابع سرویس با ثبت تیکت انجام می‌شود.

پرسش‌های متداول

آیا داکر رایگان است؟

بله. Docker Engine که در این راهنما نصب شد متن‌باز (مجوز Apache 2.0) و رایگان است. فقط استفادهٔ تجاری از Docker Desktop در شرکت‌های بزرگ‌تر (بیش از ۲۵۰ کارمند یا درآمد سالانهٔ بیش از ۱۰ میلیون دلار) اشتراک پولی لازم دارد.

فرق docker.io و docker-ce چیست؟

docker-ce بستهٔ رسمی شرکت داکر از download.docker.com است و آخرین نسخه را دارد. docker.io را اوبونتو از همان کد منبع می‌سازد. معمولاً چند نسخه عقب‌تر است اما از میرورهای اوبونتو در دسترس است. هر دو کار می‌کنند، فقط نباید هم‌زمان نصب شوند.

docker compose با docker-compose چه فرقی دارد؟

docker-compose ابزار قدیمی نسخهٔ ۱ است که دیگر پشتیبانی نمی‌شود. docker compose افزونهٔ امروزی داکر (نسخهٔ ۲ و ۵) است که با docker-compose-plugin نصب می‌شود. فایل‌های قدیمی معمولاً بدون تغییر اجرا می‌شوند. فقط version: را حذف کنید.

چرا docker pull روی سرور ایران خطای 403 می‌دهد؟

Docker Hub به دلیل مقررات صادرات آمریکا آی‌پی‌های ایران را مسدود کرده است. متن خطا با Since Docker is a US company شروع می‌شود و نصب شما ایرادی ندارد. راه‌حل: میرور رجیستری، انتقال ایمیج با docker save و docker load، یا سرور خارج از ایران.

برای داکر چقدر رم لازم است؟

برای یادگیری ۱ گیگابایت و برای وردپرس همراه MariaDB حدود ۲ گیگابایت رم نقطهٔ شروع مناسبی است. خود داکر سبک است و مصرف را کانتینرها تعیین می‌کنند. مصرف واقعی هر کانتینر را با docker stats ببینید.

چطور داکر را کامل از اوبونتو حذف کنم؟

بسته‌ها را با sudo apt purge docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin docker-ce-rootless-extras حذف کنید. اگر داده‌ها را هم نمی‌خواهید، /var/lib/docker و /var/lib/containerd را پاک کنید. این کار همهٔ ایمیج‌ها و والیوم‌ها را برای همیشه حذف می‌کند. در آخر /etc/apt/sources.list.d/docker.sources و /etc/apt/keyrings/docker.asc را هم پاک کنید.

جمع‌بندی

نصب داکر روی اوبونتو از مخزن رسمی چند دستور بیشتر نیست. آنچه سرور را قابل اتکا می‌کند تنظیمات بعد از آن است: سقف برای لاگ‌ها، انتشار پورت‌ها روی 127.0.0.1 به دلیل رفتار داکر با UFW، تگ ثابت برای ایمیج‌ها و بکاپ منظم از والیوم‌ها. روی سرورهای ایران هم اول دسترسی به Docker Hub را بسنجید و میرور یا روش انتقال ایمیج را آماده کنید.

قدم بعدی: پروژهٔ وردپرس و MariaDB را بالا بیاورید، یک پروکسی معکوس با SSL جلویش بگذارید و بکاپ‌گیری را در cron زمان‌بندی کنید. برای جزئیات بیشتر، راهنمای رسمی نصب Docker Engine روی اوبونتو و مستندات فایروال داکر را ببینید.