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

> نصب داکر روی اوبونتو 24.04 و 26.04 از مخزن رسمی، تنظیمات بعد از نصب، مثال Docker Compose، میرور داکر برای سرور ایران و رفع خطاهای رایج.

- صفحه: https://hakanserver.com/install-docker-ubuntu/
- تاریخ انتشار: ۷ آبان ۱۴۰۵ (2026-10-29)
- دسته: سرور
- زمان مطالعه: حدود 22 دقیقه

![نهنگ داکر با کانتینرهای روی هم کنار رک سرور با نشان اوبونتو](https://hakanserver.com/wp-content/uploads/2026/10/install-docker-ubuntu.jpg)

برای نصب داکر روی اوبونتو 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 | ۲ هسته | ۲ گیگابایت | ۴۰ گیگابایت |
| چند سرویس یا ساخت ایمیج روی سرور | ۴ هسته | ۴ تا ۸ گیگابایت | ۸۰ گیگابایت به بالا |

دیسک را دست‌کم نگیرید. ایمیج‌ها از چند ده تا چند صد مگابایت حجم دارند و نسخه‌های قدیمی و لاگ‌ها بی‌صدا جمع می‌شوند. برای همهٔ مراحل این راهنما یک [سرور لینوکس](https://hakanserver.com/buy-a-virtual-server/linux-server/) با Ubuntu 24.04 یا 26.04 کافی است.

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

با کاربری که دسترسی `sudo` دارد از طریق SSH وصل شوید ([آموزش اتصال به سرور لینوکسی از طریق SSH](https://hakanserver.com/connect-to-linux-server-via-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  **نکته:** اگر سرور در ایران است و این دستور با `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 داکر](https://docs.docker.com/engine/security/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 را در مقالهٔ [فعال‌سازی فایروال در لینوکس](https://hakanserver.com/enabling-firewall-in-linux/) ببینید.

## اجرای اولین کانتینر با 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 و پروژه‌هایی است که کنترل کامل سرور را لازم دارند. اگر فقط یک سایت وردپرسی ساده می‌خواهید و نمی‌خواهید سرور را خودتان نگه دارید، [هاست وردپرس](https://hakanserver.com/wordpress-hosting/) کم‌دردسرتر است. سه نکتهٔ به‌روز دربارهٔ 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"'  **هشدار:** `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 در لینوکس](https://hakanserver.com/disk-full-error-in-linux/) را ببینید.

### 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های خارجی وابسته است، لوکیشنی مثل [سرور مجازی آلمان](https://hakanserver.com/vps-germany/) کار را ساده‌تر می‌کند. اگر کاربران‌تان در ایران هستند یا داده باید داخل کشور بماند، سرور مجازی ایران همراه با میرور رجیستری معمولاً کافی است. فقط دسترسی به رجیستری‌های دیگر مثل `ghcr.io` را جداگانه بسنجید. فهرست همهٔ لوکیشن‌ها در صفحهٔ [خرید سرور مجازی](https://hakanserver.com/buy-a-virtual-server/) است. اگر کانتینرها بعداً منابع بیشتری خواستند، ارتقای منابع سرویس با ثبت تیکت انجام می‌شود.

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

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

بله. 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 روی اوبونتو](https://docs.docker.com/engine/install/ubuntu/) و [مستندات فایروال داکر](https://docs.docker.com/engine/network/packet-filtering-firewalls/) را ببینید.

- مطلب قبلی: [چرا ایمیل‌ها در cPanel ارسال نمی‌شوند؟حل مشکلات ایمیل](https://hakanserver.com/email-problem-in-cpanel/index.md)
- مطلب بعدی: [SSL چیست؟ انواع گواهی SSL، تفاوت رایگان و پولی و راهنمای انتخاب](https://hakanserver.com/what-is-ssl/index.md)

## مقاله‌های مرتبط

- [کوبرنتیز چیست؟ معماری، تفاوت با داکر و آموزش نصب k3s روی سرور](https://hakanserver.com/what-is-kubernetes/index.md)
- [کدام توزیع لینوکس برای سرور؟ مقایسهٔ اوبونتو، دبیان، آلمالینوکس و راکی](https://hakanserver.com/%D8%A7%D9%86%D9%88%D8%A7%D8%B9-%D8%B3%DB%8C%D8%B3%D8%AA%D9%85-%D8%B9%D8%A7%D9%85%D9%84%D9%87%D8%A7%DB%8C-%D9%82%D8%A7%D8%A8%D9%84-%D9%86%D8%B5%D8%A8-%D8%A8%D8%B1-%D8%B1%D9%88%DB%8C-%D8%B3/index.md)
- [رفع خطای Permission Denied در SSH](https://hakanserver.com/permission-denied-error-in-ssh/index.md)

## سرویس‌های مرتبط هاکان سرور

- [سرور مجازی](https://hakanserver.com/buy-a-virtual-server/index.md): ۵۲ لوکیشن در ایران و خارج
- [سرور اختصاصی](https://hakanserver.com/dedicatedserver/index.md): ایران و ۸ کشور دیگر
- [هاست و دامنه](https://hakanserver.com/buy-hosting-and-domain/index.md): هاست سی‌پنل ایران و اروپا

فهرست همهٔ مقاله‌ها: https://hakanserver.com/blog/index.md
فهرست همهٔ صفحه‌ها و راهنمای سایت: https://hakanserver.com/llms.txt
