نصب Docker روی اوبونتو و دستورات پایه

برای نصب Docker روی اوبونتو بهتر است از مخزن رسمی خود Docker استفاده کنید، نه بسته docker.io توزیع. مراحل آن این است: کلید GPG و مخزن Docker را اضافه کنید، بسته‌های docker-ce و docker-compose-plugin را نصب کنید و با اجرای یک کانتینر آزمایشی مطمئن شوید همه‌چیز کار می‌کند. بعد از نصب، مهم‌ترین نکته امنیتی این است که اضافه کردن کاربر به گروه docker عملاً به او دسترسی root می‌دهد.

دستورها برای Ubuntu 22.04 و 24.04 نوشته شده‌اند. اگر هنوز با کانتینر آشنا نیستید و می‌خواهید بدانید برای سرویس شما کانتینر درست‌تر است یا ماشین مجازی، تفاوت داکر و ماشین مجازی را ببینید.

پیش از نصب

  • سرور باید به اینترنت وصل باشد تا بسته‌ها و ایمیج‌ها دانلود شوند.
  • نسخه‌های قدیمی را حذف کنید تا تداخل نداشته باشند. اگر سرور تازه است، این دستور فقط پیام می‌دهد که بسته‌ای نصب نبوده:
sudo apt remove docker.io docker-doc docker-compose podman-docker containerd runc

نصب Docker روی اوبونتو، مرحله اول: مخزن رسمی

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

بعد مخزن را به منابع apt اضافه کنید:

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" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update

مرحله دوم: نصب بسته‌ها

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

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

sudo systemctl status docker
sudo docker run hello-world

اگر پیام Hello from Docker را دیدید، نصب درست است. دستورهای systemctl را بیشتر در دستورات systemctl و journalctl توضیح داده‌ایم.

استفاده بدون sudo و هشدار امنیتی

برای اینکه هر بار sudo ننویسید، کاربر را به گروه docker اضافه می‌کنند:

sudo usermod -aG docker $USER

بعد از خروج و ورود دوباره، دستور docker بدون sudo کار می‌کند. ولی کسی که عضو این گروه است، می‌تواند با کانتینر فایل‌سیستم میزبان را mount کند و در عمل root سرور است. این دسترسی را فقط به کاربران مورد اعتماد بدهید.

دستورهای پایه Docker

کاردستور
دانلود ایمیجdocker pull nginx
اجرای کانتینر در پس‌زمینهdocker run -d --name web -p 8080:80 nginx
فهرست کانتینرهای فعالdocker ps
فهرست همه کانتینرهاdocker ps -a
دیدن لاگdocker logs -f web
ورود به کانتینرdocker exec -it web sh
توقف و حذفdocker stop web و docker rm web
فهرست ایمیج‌هاdocker images

در دستور run، گزینه -p 8080:80 پورت ۸۰ کانتینر را روی پورت ۸۰۸۰ سرور منتشر می‌کند. بعد از اجرا، آدرس سرور با پورت ۸۰۸۰ صفحه Nginx را نشان می‌دهد.

نگهداری داده با Volume

داده داخل کانتینر با حذف آن از بین می‌رود. برای داده‌ای که باید بماند، مثل فایل‌های دیتابیس، یک Volume یا پوشه میزبان را mount کنید:

docker run -d --name db -v dbdata:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=CHANGE_ME mysql:8

Volume مستقل از کانتینر نگه‌داری می‌شود و بکاپ‌گیری از آن باید در طرح بکاپ سرور لحاظ شود. روش بکاپ دیتابیس‌ها در بکاپ گرفتن از دیتابیس MySQL آمده است.

اجرای چند سرویس با Docker Compose

Compose با یک فایل YAML چند کانتینر را با هم تعریف می‌کند. فایل compose.yaml زیر یک Nginx را روی پورت ۸۰۸۰ بالا می‌آورد:

services:
  web:
    image: nginx:stable
    ports:
      - "8080:80"
    restart: unless-stopped

با docker compose up -d اجرا و با docker compose down متوقف می‌شود. گزینه restart: unless-stopped باعث می‌شود بعد از ری‌استارت سرور، کانتینر دوباره بالا بیاید.

مشکل Docker و فایروال UFW

پورتی که Docker منتشر می‌کند، قوانین UFW را دور می‌زند، چون Docker مستقیم قانون iptables می‌نویسد. یعنی با اینکه UFW پورت ۸۰۸۰ را نبسته، کانتینر از اینترنت در دسترس است. اگر فقط باید از خود سرور در دسترس باشد، پورت را روی آدرس محلی منتشر کنید:

docker run -d -p 127.0.0.1:8080:80 nginx

حالا فقط پروسه‌های روی همان سرور، مثلاً یک Nginx پشت‌خط، به آن می‌رسند. روش وصل کردن آن به دامنه در Reverse Proxy چیست آمده است. پایه‌های ایمن‌سازی سرور هم در چک لیست امنیت سرور لینوکس است.

پاک‌سازی منابع

ایمیج‌ها و Volumeهای بی‌استفاده با گذر زمان فضای زیادی می‌گیرند. فضای مصرف‌شده را ببینید و موارد بی‌استفاده را پاک کنید:

docker system df
docker system prune

دستور prune کانتینرهای متوقف، شبکه‌ها و ایمیج‌های بدون برچسب را پاک می‌کند. Volumeها را فقط با گزینه جداگانه --volumes پاک می‌کند؛ این گزینه را فقط وقتی بزنید که مطمئنید داده مهمی در آن‌ها نیست.

خطاهای رایج

نشانهعلت و راه حل
permission denied while trying to connect to the Docker daemon socketکاربر در گروه docker نیست یا بعد از اضافه شدن خارج و داخل نشده است
port is already allocatedپورت میزبان را سرویس دیگری گرفته؛ پورت دیگری انتخاب کنید
no space left on deviceدیسک پر است؛ docker system df را ببینید و موارد بی‌استفاده را پاک کنید
کانتینر بلافاصله متوقف می‌شودdocker logs را بخوانید؛ معمولاً متغیر محیطی لازم تنظیم نشده است
دانلود ایمیج شکست می‌خورددسترسی شبکه به رجیستری یا DNS سرور را بررسی کنید

سوالات متداول

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

docker.io بسته‌ای است که خود Ubuntu از Docker می‌سازد و معمولاً نسخه‌اش عقب‌تر است. docker-ce از مخزن رسمی خود Docker می‌آید و به‌روزرسانی سریع‌تری دارد. هر دو کار می‌کنند، ولی مستندات Docker نصب از مخزن رسمی را پیشنهاد می‌کنند.

بعد از نصب Docker روی اوبونتو، Compose را جدا نصب کنم؟

نه. نسخه جدید Compose به‌صورت افزونه docker-compose-plugin نصب می‌شود و با دستور docker compose (با فاصله) اجرا می‌شود، نه docker-compose قدیمی.

برای دیتابیس‌های سنگین از Docker استفاده کنم؟

ممکن است، ولی باید Volume روی دیسک مناسب باشد و بکاپ و پایش را جدی بگیرید. بسیاری از تیم‌ها دیتابیس اصلی را روی سرور یا ماشین مجازی جدا نگه می‌دارند و فقط برنامه را کانتینری می‌کنند.

ایمیج چه فرقی با کانتینر دارد؟

ایمیج قالب فقط‌خواندنی است و کانتینر نمونه در حال اجرای آن. از یک ایمیج می‌توان چند کانتینر ساخت.

منابع