ورود به پنل ثبت‌ نام

آموزش نصب داکر روی اوبونتو ۲۴.۰۴ از مخزن رسمی

نصب داکر روی اوبونتو از مخزن رسمی؛ Docker Compose، اجرا بدون sudo، فایروال UFW، چرخش لاگ و پاک‌سازی فضای دیسک روی سرور ابری.

تیم ابر سپهر 13 دقیقه مطالعه
آموزش نصب داکر روی اوبونتو ۲۴.۰۴ از مخزن رسمی
در این مقاله

نصب داکر روی اوبونتو نخستین کاری است که بیشتر ما بعد از تحویل‌گرفتن یک سرور ابری تازه انجام می‌دهیم. داکر به شما اجازه می‌دهد هر سرویسی — پایگاه داده، وب‌سرور، صف، ابزار اتوماسیون — را در یک کانتینر جدا اجرا کنید؛ کانتینری که همهٔ وابستگی‌هایش را با خودش حمل می‌کند و با یک دستور ساخته، حذف یا جابه‌جا می‌شود.

مزیت اصلی این روش تمیز ماندن سرور است. وقتی سرویس‌ها را مستقیم روی سیستم‌عامل نصب می‌کنید، بعد از چند ماه با مجموعه‌ای از نسخه‌های PHP، کتابخانه‌های نیمه‌حذف‌شده و فایل‌های پیکربندی سرگردان روبه‌رو می‌شوید که هیچ‌کس دقیقاً نمی‌داند کدام‌شان هنوز لازم است. با داکر، حذف یک سرویس یعنی حذف یک کانتینر؛ سیستم‌عامل میزبان دست‌نخورده باقی می‌ماند. مزیت دوم تکرارپذیری است: همان compose.yaml که روی لپ‌تاپ شما کار می‌کند، روی سرور هم دقیقاً همان رفتار را دارد.

در این مقاله داکر را روی Ubuntu 24.04 LTS و از مخزن رسمی داکر نصب می‌کنیم، آن را برای اجرا بدون sudo تنظیم می‌کنیم، با Docker Compose یک سرویس واقعی بالا می‌آوریم و در پایان سراغ سه چیزی می‌رویم که معمولاً از قلم می‌افتند و بعداً دردسر می‌سازند: رابطهٔ داکر با فایروال، چرخش لاگ‌ها و پر شدن دیسک.

پیش‌نیازها

  • یک سرور ابری با Ubuntu 24.04 LTS (دستورهای این راهنما روی ۲۲.۰۴ هم بدون تغییر کار می‌کنند) و دسترسی root.
  • حداقل ۱ هسته پردازنده و ۱ گیگابایت حافظه برای خودِ داکر کافی است؛ منابع واقعی را سرویس‌هایی تعیین می‌کنند که قرار است داخل کانتینرها اجرا شوند.
  • فضای دیسک آزاد. ایمیج‌های داکر در /var/lib/docker ذخیره می‌شوند و روی سروری با دیسک کوچک، چند ایمیج و چند لایهٔ بی‌استفاده به‌سرعت فضا را پر می‌کنند. به این موضوع در بخش نگهداری برمی‌گردیم.

تمام دستورهای این راهنما با کاربر root اجرا می‌شوند. اگر با کاربر عادی کار می‌کنید، پیش از هر دستور sudo بگذارید.

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

اوبونتو خودش بستهٔ docker.io را در مخزن‌هایش دارد و وسوسه‌انگیز است که کار را با یک apt install docker.io تمام کنید. مشکل اینجاست که آن بسته معمولاً چند نسخه از داکر عقب‌تر است، افزونهٔ docker compose را همراه ندارد و به‌روزرسانی‌هایش به چرخهٔ انتشار اوبونتو گره خورده است، نه به چرخهٔ خود داکر.

مخزن رسمی داکر این هر سه مشکل را حل می‌کند: آخرین نسخهٔ پایدار Docker Engine، افزونه‌های buildx و compose به‌صورت رسمی، و به‌روزرسانی از همان مسیر همیشگی apt upgrade. چند دستور بیشتر می‌گیرد، ولی این کاری است که یک بار انجام می‌دهید و تا پایان عمر سرور با آن زندگی می‌کنید.

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

ابتدا سیستم را به‌روز می‌کنیم:

apt update && apt upgrade -y

اگر پیش‌تر روی این سرور نسخه‌ای از داکر یا بسته‌های شبیه به آن نصب شده، باید حذف شوند؛ وجود هم‌زمان docker.io مخزن اوبونتو و docker-ce مخزن رسمی، تعارض بسته و رفتارهای عجیب می‌سازد:

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

اگر هیچ‌کدام نصب نبودند، apt فقط پیام «بسته نصب نیست» می‌دهد و رد می‌شود؛ جای نگرانی نیست. توجه کنید که این دستور فقط بسته‌ها را حذف می‌کند و به /var/lib/docker — یعنی ایمیج‌ها و والیوم‌های موجود — دست نمی‌زند.

سپس بسته‌های لازم برای افزودن یک مخزن امن را نصب می‌کنیم:

apt install -y ca-certificates curl gnupg

گام ۲: افزودن مخزن رسمی داکر

کلید GPG داکر را دانلود می‌کنیم و در مسیر keyring های سیستم می‌گذاریم. این کلید همان چیزی است که apt با آن امضای بسته‌های دانلودشده را بررسی می‌کند؛ بدون آن، مخزن به شما اعتماد نمی‌دهد:

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

حالا مخزن را به فهرست مخازن سیستم اضافه می‌کنیم:

echo \
  "deb [arch=$(dpkg --print-architecture) \
  signed-by=/etc/apt/keyrings/docker.asc] \
  https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
  tee /etc/apt/sources.list.d/docker.list > /dev/null

دو نکته دربارهٔ این دستور:

  • signed-by= مخزن را به همان یک کلید محدود می‌کند. یعنی این کلید فقط برای بسته‌های داکر معتبر است و نه برای کل سیستم؛ این تفاوت آن با روش قدیمی و منسوخ apt-key add است.
  • $VERSION_CODENAME نام کد نسخهٔ اوبونتو را از /etc/os-release می‌خواند (برای ۲۴.۰۴ می‌شود noble). اگر روی یک توزیع مبتنی بر اوبونتو مثل Linux Mint هستید، این متغیر نام کد همان توزیع را برمی‌گرداند و مخزن داکر آن را نمی‌شناسد؛ در آن صورت باید به‌جایش از UBUNTU_CODENAME استفاده کنید.

گام ۳: نصب داکر انجین

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

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

این پنج بسته چه هستند؟ docker-ce سرویس (دیمن) داکر است که در پس‌زمینه اجرا می‌شود و کانتینرها را می‌سازد؛ docker-ce-cli همان دستور docker است که شما تایپ می‌کنید؛ containerd.io موتور اجرای کانتینر در لایهٔ زیرین است؛ و دو بستهٔ آخر افزونه‌های docker buildx و docker compose را اضافه می‌کنند. اگر docker-compose-plugin را نصب نکنید، بعداً دستور docker compose up را نخواهید داشت.

سرویس داکر بعد از نصب خودش فعال می‌شود، ولی برای اطمینان:

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

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

docker run --rm hello-world

داکر ایمیج hello-world را دانلود می‌کند، در یک کانتینر اجرا می‌کند و پیام موفقیت را چاپ می‌کند. سوییچ --rm باعث می‌شود کانتینر بلافاصله پس از پایان کار حذف شود و سرورتان با یک کانتینر مردهٔ بی‌مصرف باقی نماند.

گام ۴: اجرای داکر بدون sudo

به‌صورت پیش‌فرض فقط root می‌تواند با داکر کار کند. برای اینکه کاربر عادی هم بتواند، او را به گروه docker اضافه می‌کنیم:

usermod -aG docker $USER

تغییر گروه تا زمانی که از حساب خارج و دوباره وارد نشوید اعمال نمی‌شود. برای اینکه در همین نشست فعال شود:

newgrp docker
docker ps

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

گام ۵: بالا آوردن یک سرویس واقعی با Docker Compose

اجرای کانتینر با دستور طولانی docker run برای یک تست خوب است، ولی برای سرویسی که قرار است ماه‌ها بالا بماند، پیکربندی را در یک فایل می‌نویسیم تا مستند و تکرارپذیر بماند. یک پوشه می‌سازیم:

mkdir -p /opt/webapp && cd /opt/webapp
nano compose.yaml

و این محتوا را در آن می‌گذاریم — یک وب‌سرور Nginx به‌همراه یک والیوم برای داده‌های ماندگار:

services:
  web:
    image: nginx:stable
    container_name: webapp
    restart: unless-stopped
    ports:
      - "127.0.0.1:8080:80"
    volumes:
      - web_content:/usr/share/nginx/html:ro

volumes:
  web_content:

سه تنظیم اینجا مهم‌اند:

  • restart: unless-stopped باعث می‌شود سرویس بعد از ریبوت سرور یا کرش کردن، خودکار دوباره بالا بیاید. بدون آن، سرور که ریستارت شود سرویس شما خاموش می‌ماند.
  • ports: "127.0.0.1:8080:80" پورت را فقط روی خودِ سرور منتشر می‌کند، نه روی اینترنت. در بخش بعد می‌بینیم چرا این مهم‌ترین سطر کل فایل است.
  • volumes داده را از چرخهٔ عمر کانتینر جدا می‌کند. کانتینر دورریختنی است؛ والیوم نه. هر چیزی که نباید با docker rm از بین برود، باید داخل یک والیوم باشد.

سرویس را اجرا می‌کنیم:

docker compose up -d
docker compose ps

سوییچ -d سرویس را در پس‌زمینه اجرا می‌کند. برای دیدن لاگ‌ها docker compose logs -f و برای خاموش کردن docker compose down را به کار ببرید. دقت کنید که down کانتینرها را حذف می‌کند ولی به والیوم‌ها دست نمی‌زند — مگر اینکه -v را هم اضافه کنید، که در آن صورت داده‌هایتان واقعاً پاک می‌شود.

چرا داکر فایروال UFW را دور می‌زند؟

این بخش را جدی بگیرید، چون یکی از رایج‌ترین دلایل لو رفتن پایگاه‌های دادهٔ بدون رمز روی اینترنت است.

داکر برای انتشار پورت‌ها، قواعد خودش را مستقیماً در زنجیرهٔ DOCKER در iptables می‌نویسد و این قواعد پیش از قواعد UFW بررسی می‌شوند. نتیجه این است که اگر یک کانتینر را با -p 5432:5432 اجرا کنید، آن پورت روی اینترنت باز است؛ حتی اگر UFW فعال باشد و بگوید Status: active و شما هیچ قاعده‌ای برای پورت ۵۴۳۲ اضافه نکرده باشید. ufw status هم چیزی به شما نشان نمی‌دهد، چون از دید UFW اصلاً قاعده‌ای وجود ندارد.

راه‌حل درست و ساده، همان کاری است که در compose.yaml بالا کردیم: همیشه آدرس محلی را در ابتدای نگاشت پورت بنویسید.

ports:
  - "127.0.0.1:8080:80"   # درست: فقط از روی خود سرور در دسترس است
  # - "8080:80"           # نادرست: روی کل اینترنت باز می‌شود

با این کار تنها راه رسیدن به سرویس از بیرون، عبور از یک پراکسی معکوس مثل Nginx است که شما خودتان روی پورت‌های ۸۰ و ۴۴۳ تنظیم می‌کنید و می‌توانید روی آن HTTPS و احراز هویت بگذارید. الگوی کامل این کار — Nginx به‌عنوان پراکسی معکوس به‌همراه گواهی رایگان Let's Encrypt — در مقالهٔ آموزش نصب n8n روی سرور ابری گام‌به‌گام آمده است و برای هر سرویس داکری دیگری هم عیناً قابل استفاده است.

فایروال را هم فعال می‌کنیم؛ این کار پورت‌های سرویس‌های غیرداکری (مثل خود Nginx) را کنترل می‌کند:

apt install -y ufw
ufw allow OpenSSH
ufw allow 'Nginx Full'
ufw enable

پیش از اجرای ufw enable مطمئن شوید قاعدهٔ OpenSSH را اضافه کرده‌اید، وگرنه ارتباط SSH فعلی شما قطع می‌شود. اگر این اتفاق افتاد، از کنسول تحت وب کنترل پنل ابر سپهر وارد سرور شوید و قاعده را اضافه کنید.

گام ۶: چرخش لاگ‌ها؛ کاری که همه فراموش می‌کنند

داکر به‌صورت پیش‌فرض تمام خروجی کانتینرها را در فایل‌های JSON نگه می‌دارد و هیچ سقفی برای اندازهٔ آن‌ها ندارد. یک کانتینر پرحرف می‌تواند در چند هفته چندین گیگابایت لاگ تولید کند و دیسک سرور را پر کند؛ آن‌وقت سرویس‌ها یکی‌یکی از کار می‌افتند و علتش هم در نگاه اول معلوم نیست.

این را با یک بار پیکربندی برای همیشه حل کنید:

nano /etc/docker/daemon.json
{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3"
  }
}

و داکر را ریستارت کنید:

systemctl restart docker

از این پس هر کانتینر حداکثر سه فایل لاگ ۱۰ مگابایتی نگه می‌دارد و قدیمی‌ترها خودکار حذف می‌شوند. توجه کنید که این تنظیم فقط روی کانتینرهایی اثر دارد که از این پس ساخته می‌شوند؛ کانتینرهای موجود را باید یک بار دوباره بسازید (docker compose up -d --force-recreate).

نگهداری: به‌روزرسانی، پاک‌سازی و بک‌آپ

به‌روزرسانی خود داکر از مسیر معمول سیستم انجام می‌شود، چون آن را از مخزن رسمی نصب کرده‌ایم:

apt update && apt upgrade -y

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

cd /opt/webapp
docker compose pull
docker compose up -d

پاک‌سازی فضا؛ ایمیج‌های قدیمی بعد از هر به‌روزرسانی روی دیسک باقی می‌مانند:

docker system df      # چقدر فضا اشغال شده و توسط چه چیزی
docker system prune -a

دستور prune -a هر ایمیج، شبکه و کانتینر متوقفی را که هیچ کانتینر در حال اجرایی از آن استفاده نمی‌کند حذف می‌کند. والیوم‌ها را حذف نمی‌کند — مگر اینکه --volumes را هم بدهید، که در این صورت داده‌های سرویس‌های خاموشتان هم می‌رود. این سوییچ را با احتیاط به کار ببرید.

بک‌آپ یعنی نگه‌داشتن یک نسخه از والیوم‌ها:

docker run --rm -v web_content:/data -v /root:/backup busybox \
  tar czf /backup/web_content.tar.gz -C /data .

ساده‌ترین راه اما این است که پیش از هر تغییر پرخطر، از کنترل پنل ابر سپهر یک اسنپ‌شات از کل سرور بگیرید؛ اگر چیزی خراب شد، در چند دقیقه به وضعیت قبل برمی‌گردید.

کار دستور / ابزار چه زمانی
مشاهدهٔ لاگ سرویس docker compose logs -f هنگام عیب‌یابی
فهرست کانتینرهای فعال docker ps بررسی روزانه
به‌روزرسانی سرویس docker compose pull && docker compose up -d ماهانه
آزادسازی فضای دیسک docker system prune -a پس از هر چند به‌روزرسانی
بک‌آپ کامل اسنپ‌شات کنترل پنل پیش از هر تغییر پرخطر

جمع‌بندی

نصب داکر روی اوبونتو از مخزن رسمی چند دقیقه بیشتر طول نمی‌کشد و در عوض یک سرور تمیز و تکرارپذیر به شما می‌دهد که سرویس‌ها را می‌توان روی آن بدون ترس اضافه و حذف کرد. سه تصمیمی که بیشترین تفاوت را می‌سازند: نصب از مخزن رسمی به‌جای بستهٔ قدیمی اوبونتو، انتشار پورت‌ها فقط روی 127.0.0.1 و قرار دادن یک پراکسی معکوس جلوی آن‌ها، و تنظیم سقف برای لاگ‌ها پیش از آنکه دیسک پر شود.

اگر هنوز سروری برای این کار ندارید، می‌توانید از صفحهٔ خرید سرور ابری با کمترین منابع شروع کنید و هر زمان که کانتینرهایتان سنگین‌تر شدند، منابع را ارتقا دهید.

مقالات مرتبط