توی این درس یاد میگیری داکر (Docker) دقیقاً چه مشکلی را حل میکند، کانتینر (container) یعنی چه و چه فرقی با یک برنامهی معمولی دارد، سه مفهوم اصلی image و container و registry چه نقشی دارند، و داکر در عمق (با namespace، cgroup و لایهها) چطور کار میکند. در آخر هم با شش مثال واقعی دستبهکار میشوی، از docker --version تا بالا آوردن یک وبسرور.
مشکل: «روی سیستم من که کار میکرد!»
Section titled “مشکل: «روی سیستم من که کار میکرد!»”فرض کن یک برنامهی وب نوشتهای. روی لپتاپ خودت عالی کار میکند. آن را برای همکارت میفرستی و او میگوید: «ارور میدهد.»
چرا؟ چون برنامهی تو فقط کد نیست. به یک مجموعه چیز دیگر هم وابسته است:
- نسخهی مشخصی از زبان برنامهنویسی (مثلاً Node.js 22 یا Python 3.12)
- چند کتابخانه با نسخههای مشخص
- یک دیتابیس با تنظیمات خاص
- متغیرهای محیطی، پورتها، فایلهای تنظیمات
- و حتی خود سیستمعامل (ویندوز، مک یا لینوکس؟ کدام نسخه؟)
روی لپتاپ تو همهی اینها «اتفاقاً» درستاند. روی لپتاپ همکارت، یا روی سروری که قرار است برنامه آنجا اجرا شود، یکیشان فرق دارد. نتیجه همان جملهی معروف است: «works on my machine».
راهحل: همهچیز را با هم بستهبندی کن
Section titled “راهحل: همهچیز را با هم بستهبندی کن”تشبیه سادهاش کانتینر باری است.
قبل از اختراع کانتینر، کشتیها هر کالا را جداگانه بار میکردند: کیسه، جعبه، بشکه، هر کدام با شکل و اندازهی خودش. بارگیری کند بود و هر بندر روش خودش را داشت. بعد کسی فکر کرد: همهچیز را داخل یک جعبهی استاندارد بگذاریم. حالا هر چه داخلش باشد، کشتی و جرثقیل و کامیون فقط با یک چیز کار دارند: جعبهی هماندازه.
داکر همین کار را برای نرمافزار میکند. برنامهات را با تمام چیزهایی که لازم دارد (زبان برنامهنویسی، کتابخانهها، تنظیمات) داخل یک «جعبه» میگذارد. این جعبه را کانتینر میگویند. هر جا که داکر باشد، آن جعبه همانطور که هست اجرا میشود: لپتاپ تو، لپتاپ همکارت، یا یک سرور در آن سر دنیا.
داکر از چه تکههایی ساخته شده؟
Section titled “داکر از چه تکههایی ساخته شده؟”وقتی میگویی «داکر»، در واقع چند برنامه با هم کار میکنند. این نمودار تصویر کلی را نشان میدهد؛ در بخش «پشت پرده» به هر تکه برمیگردیم.
| تکه | وظیفه |
|---|---|
docker CLI |
برنامهای که تو در ترمینال با آن حرف میزنی. فقط دستور تو را به daemon میفرستد |
dockerd (daemon) |
مغز داکر. image ها، کانتینرها، شبکهها و volume ها را مدیریت میکند و در پسزمینه همیشه روشن است |
| Registry | انبار image ها (مثل Docker Hub). image را از آنجا میگیری (pull) یا آنجا میگذاری (push) |
containerd |
مدیریت چرخهی عمر کانتینر: ساخت، شروع، توقف |
runc |
ابزار سطح پایینی که کانتینر را واقعاً میسازد و اجرا میکند |
| هستهی لینوکس | ویژگیهایی مثل namespace و cgroup که جداسازی را ممکن میکنند |
سه مفهوم اصلی
Section titled “سه مفهوم اصلی”این سه کلمه را همین حالا خوب یاد بگیر. تا آخر دوره هر روز میشنویشان.
| مفهوم | یعنی چه؟ | تشبیه |
|---|---|---|
| Image (ایمیج) | یک قالب فقطخواندنی که همهی چیزهای لازم برنامه در آن است | دستور پخت و مواد اولیهی بستهبندیشده |
| Container (کانتینر) | یک نمونهی در حال اجرا از یک image | غذایی که از روی آن دستور پخته شده و الان سر میز است |
| Registry (رجیستری) | انباری که image ها آنجا ذخیره و به اشتراک گذاشته میشوند | یک فروشگاه یا کتابخانهی آنلاین. معروفترینش Docker Hub است |
از روی یک image میتوانی هر چند کانتینر که بخواهی بسازی، همانطور که از یک دستور پخت میشود چندین بار غذا پخت. هر کانتینر مستقل از بقیه است.
مثالهای عملی
Section titled “مثالهای عملی”از ساده شروع میکنیم و کمکم به چیزهای واقعی میرسیم. همهی خروجیها از اجرای واقعی روی یک سیستم با Docker Desktop گرفته شدهاند؛ شناسهها، تاریخها و نسخهها روی سیستم تو فرق میکنند.
مثال ۱: داکر نصب است؟ کدام نسخه؟
Section titled “مثال ۱: داکر نصب است؟ کدام نسخه؟”docker --versionDocker version 29.8.1, build 4a63305این فقط نسخهی برنامهی docker (همان CLI) را میگوید. برای دیدن هر دو طرف، یعنی CLI و daemon:
docker version --format 'Client: {{.Client.Version}} ({{.Client.Os}}/{{.Client.Arch}}){{"\n"}}Server: {{.Server.Version}} ({{.Server.Os}}/{{.Server.Arch}})'Client: 29.8.1 (darwin/arm64)Server: 29.8.1 (linux/arm64)به یک نکتهی جالب دقت کن: Client روی darwin (macOS) است ولی Server روی linux. یعنی daemon روی یک لینوکس اجرا میشود حتی وقتی سیستم تو مک است. چرا؟ در بخش «پشت پرده» توضیح میدهم. اگر docker version خطا داد که به daemon وصل نمیشود، یعنی داکر روشن نیست (در Docker Desktop برنامه را باز کن).
مثال ۲: اولین کانتینر، hello-world
Section titled “مثال ۲: اولین کانتینر، hello-world”docker run hello-worldUnable to find image 'hello-world:latest' locallylatest: Pulling from library/hello-world58dee6a49ef1: Pull completeDigest: sha256:5e23090353324d887c48ad5e5c56d294eab81588df9605b07d1afe895f9cc8f8Status: Downloaded newer image for hello-world:latest
Hello from Docker!This message shows that your installation appears to be working correctly.خطبهخط بخوانیم:
Unable to find image ... locally: داکر اول روی سیستم خودت دنبال image گشت و پیدا نکرد.Pulling from library/hello-world: پس آن را از registry (Docker Hub) pull کرد، یعنی دانلود کرد.Hello from Docker!: از آن image یک کانتینر ساخت، اجرایش کرد، و برنامهی داخلش این پیام را چاپ کرد. بعد از چاپ، کار برنامه تمام شد و کانتینر خودش بسته شد.
در یک دستور، هر سه مفهوم را دیدی: registry (Docker Hub)، image (hello-world) و container (چیزی که اجرا شد).
در خروجی docker run hello-world، عبارت «Pulling from library/hello-world» یعنی چه؟
داکر اول دنبال image روی سیستم میگردد؛ پیدا نکرد، پس آن را از Docker Hub pull کرد.
مثال ۳: image و container کجا ماندند؟
Section titled “مثال ۳: image و container کجا ماندند؟”docker images hello-worldIMAGE ID DISK USAGE CONTENT SIZE EXTRAhello-world:latest 5e2309035332 22.6kB 10.3kB Uimage هنوز روی سیستم هست؛ دفعهی بعد دیگر دانلود نمیشود. و کانتینری که اجرا شد؟
docker ps -a --filter ancestor=hello-world --format 'table {{.ID}}\t{{.Image}}\t{{.Status}}'CONTAINER ID IMAGE STATUSb4a3840b9a96 hello-world Exited (0) Less than a second agoکانتینر هم هنوز هست، ولی با وضعیت Exited (0): کارش تمام شده (کد خروج 0 یعنی بدون خطا). docker ps فقط کانتینرهای در حال اجرا را نشان میدهد؛ -a (all) همه را، حتی متوقفشدهها.
مثال ۴: یک لینوکس دیگر داخل سیستم تو
Section titled “مثال ۴: یک لینوکس دیگر داخل سیستم تو”docker run --rm ubuntu:24.04 cat /etc/os-releasePRETTY_NAME="Ubuntu 24.04.5 LTS"NAME="Ubuntu"VERSION_ID="24.04"این دستور یک کانتینر از image با اسم ubuntu و تگ (tag، یعنی نسخه) 24.04 ساخت، داخلش cat /etc/os-release را اجرا کرد و کانتینر را بست. --rm یعنی «بعد از تمام شدن، کانتینر را خودکار پاک کن» تا کانتینرهای متوقفشده انباشته نشوند.
سیستمعامل داخل کانتینر Ubuntu است، حتی اگر سیستم تو مک یا ویندوز باشد. روی همان سیستم من، دستور uname -s بیرون از کانتینر Darwin (macOS) میگوید. این یعنی کانتینر یک «محیط جدا» است که چیزهای خودش را دارد.
مثال ۵: یک وبسرور واقعی
Section titled “مثال ۵: یک وبسرور واقعی”حالا چیزی بسازیم که واقعاً کار کند: وبسرور nginx.
docker run -d -p 8099:80 --name lx-web nginxStatus: Downloaded newer image for nginx:latest527352eda9a71f578450e190b15d4eb89a1be863cecf8e389ea3f147a622b826سه گزینهی جدید:
-d(detached): کانتینر را در پسزمینه اجرا کن و ترمینال را آزاد بگذار.-p 8099:80: پورت8099سیستم خودت را به پورت80داخل کانتینر وصل کن (به ترتیبپورت-سیستم:پورت-کانتینر).--name lx-web: اسمی که خودمان به کانتینر میدهیم، تا بعداً راحت صدایش کنیم.
خروجی، شناسهی بلند کانتینر است. ببینیم زنده است:
docker ps --filter name=lx-web --format 'table {{.ID}}\t{{.Image}}\t{{.Status}}\t{{.Ports}}\t{{.Names}}'CONTAINER ID IMAGE STATUS PORTS NAMES527352eda9a7 nginx Up Less than a second 0.0.0.0:8099->80/tcp, [::]:8099->80/tcp lx-webو واقعاً جواب میدهد؟
curl -s localhost:8099 | head -5<!DOCTYPE html><html><head><title>Welcome to nginx!</title><style>مرورگرت را هم باز کن و برو به http://localhost:8099؛ صفحهی «Welcome to nginx!» را میبینی. یک وبسرور کامل را بدون نصب هیچ چیز روی سیستمت بالا آوردی.
مثال ۶: بازرسی و تمیزکاری
Section titled “مثال ۶: بازرسی و تمیزکاری”لاگهای کانتینر (آخرین خطها):
docker logs lx-web2026/10/01 13:51:09 [notice] 1#1: start worker process 36192.168.65.1 - - [01/Oct/2026:13:51:11 +0000] "GET / HTTP/1.1" 200 896 "-" "curl/8.7.1" "-"درخواستی که با curl زدیم همینجا ثبت شده. و پروسههای داخل کانتینر:
docker top lx-webUID PID PPID C STIME TTY TIME CMDroot 1806 1783 0 13:51 ? 00:00:00 nginx: master process nginx -g daemon off;statd 1849 1806 0 13:51 ? 00:00:00 nginx: worker processیک نکتهی کلیدی: کانتینر چیزی جز یک پروسه (یا چند پروسه) روی سیستم نیست. حالا ببندیمش و پاکش کنیم:
docker stop lx-webdocker rm lx-weblx-weblx-webstop کانتینر را متوقف میکند و rm آن را حذف میکند. (image nginx سر جایش میماند؛ برای حذف آن docker rmi nginx است.)
پشت پرده: داکر در عمق چطور کار میکند؟
Section titled “پشت پرده: داکر در عمق چطور کار میکند؟”تا اینجا داکر را مثل یک جعبهی سیاه دیدیم. حالا بازش کنیم. سه ایده هست که همهچیز را توضیح میدهند.
۱) کانتینر یک پروسهی جداشده است (namespace)
Section titled “۱) کانتینر یک پروسهی جداشده است (namespace)”کانتینر ماشین مجازی نیست. هیچ سیستمعامل جداگانهای در آن بوت نمیشود. کانتینر فقط یک پروسهی معمولی لینوکس است که هسته (kernel) با ویژگیای به اسم namespace برایش «توهم یک سیستم جدا» میسازد: پروسه فقط پروسههای خودش را میبیند، اسم کامپیوتر (hostname) مخصوص خودش را دارد، شبکه و فایلسیستم خودش را دارد.
ببین:
docker run --rm ubuntu:24.04 sh -c 'echo "PID inside: $$"; echo "hostname: $(hostname)"; echo "processes:"; ls /proc | grep -E "^[0-9]+$"'PID inside: 1hostname: c0946a1c7a82processes:178داخل کانتینر پروسهی اصلی شمارهی ۱ دارد (مثل اولین پروسهی یک سیستم تازهبوتشده)، و hostname کانتینر همان شناسهی کوتاهش است. فقط سه پروسه میبیند: خود sh (شمارهی ۱) و دو دستور ls و grep که همین الان اجرا کردیم. کل پروسههای سیستم را نمیبیند. دیوار namespace همین است. (در docker top مثال قبل، همان پروسهی nginx از بیرون با شمارهی 1806 دیده میشد؛ یک پروسه، دو شماره.)
۲) منابع را محدود میکنیم (cgroup)
Section titled “۲) منابع را محدود میکنیم (cgroup)”ویژگی دوم هسته cgroup (control group) است که مشخص میکند یک پروسه چقدر CPU و حافظه میتواند بگیرد:
docker run --rm --memory 100m ubuntu:24.04 cat /sys/fs/cgroup/memory.maxdocker run --rm ubuntu:24.04 cat /sys/fs/cgroup/memory.max104857600maxبا --memory 100m عدد 104857600 بایت (یعنی دقیقاً ۱۰۰ مگابایت: ۱۰۰ × ۱۰۲۴ × ۱۰۲۴) بهعنوان سقف حافظه ثبت شد. بدون آن، max است، یعنی بدون سقف. اگر پروسهی داخل کانتینر بیشتر از ۱۰۰ مگابایت بخواهد، هسته آن را میبندد.
۳) فایلها لایهلایهاند (union filesystem)
Section titled “۳) فایلها لایهلایهاند (union filesystem)”image یک فایل بزرگ و یکپارچه نیست؛ پشتهای از لایههای فقطخواندنی است. هر لایه تغییراتی را روی لایهی زیریناش اضافه میکند:
docker image inspect nginx --format 'layers: {{len .RootFS.Layers}}'docker history nginx --format 'table {{.CreatedBy}}\t{{.Size}}' | head -6layers: 7CREATED BY SIZECMD ["nginx" "-g" "daemon off;"] 0BSTOPSIGNAL SIGQUIT 0BEXPOSE map[80/tcp:{}] 0BENTRYPOINT ["/docker-entrypoint.sh"] 0BCOPY 30-tune-worker-processes.sh /docker-ent… 16.4kBimage nginx هفت لایه دارد، و docker history نشان میدهد هر کدام با چه دستوری ساخته شدهاند (از جدید به قدیم). وقتی از image کانتینر میسازی، داکر یک لایهی نازک قابلنوشتن روی همهی اینها میگذارد:
هر تغییری که داخل کانتینر بدهی (فایل بسازی، چیزی را پاک کنی) در همین لایهی بالایی ثبت میشود. با docker diff میتوانی ببینی:
docker run --name lx-a ubuntu:24.04 sh -c 'echo hi > /tmp/x && cat /tmp/x'docker diff lx-adocker run --rm ubuntu:24.04 cat /tmp/xhiC /tmpA /tmp/xcat: /tmp/x: No such file or directoryحرف A (Added) یعنی فایل جدید اضافه شد و C (Changed) یعنی پوشه تغییر کرد. ولی کانتینر دیگری که از همان image ساخته شد، فایل /tmp/x را ندارد، چون آن فایل فقط در لایهی قابلنوشتن کانتینر lx-a است. و اگر lx-a را حذف کنی (docker rm lx-a)، آن لایه و آن فایل هم برای همیشه میروند. این دقیقاً دلیل وجود volume است که در درسهای بعد یاد میگیری.
چرا کانتینر دیگری که از همان image ساخته شد، فایل /tmp/x را ندارد؟
هر کانتینر لایهی قابلنوشتن مخصوص خودش را دارد؛ لایههای image فقطخواندنی و مشترکاند.
داکر روی مک و ویندوز چطور کار میکند؟
Section titled “داکر روی مک و ویندوز چطور کار میکند؟”namespace و cgroup ویژگیهای هستهی لینوکس هستند. مک و ویندوز این هسته را ندارند. پس Docker Desktop در پسزمینه یک ماشین مجازی سبک لینوکسی اجرا میکند و daemon داخل آن است. وقتی در ترمینال مک دستور docker میزنی، CLI با آن VM حرف میزند. همین است که در مثال ۱ دیدیم Client روی darwin و Server روی linux بود. روی ویندوز هم همینطور است و VM روی WSL 2 اجرا میشود (همان چیزی که در درس اول بخش لینوکس نصب کردی). برای همین نصب داکر روی ویندوز به WSL 2 نیاز دارد.
برای دیدن همین موضوع روی سیستم خودت:
docker info --format 'Server: {{.ServerVersion}}OS: {{.OperatingSystem}}Kernel: {{.KernelVersion}}Runtime: {{.DefaultRuntime}}'Server: 29.8.1OS: Docker DesktopKernel: 7.0.14-linuxkitRuntime: runcKernel: ...-linuxkit یعنی هستهی لینوکسِ داخل آن VM، و Runtime: runc همان ابزاری است که در نمودار معماری دیدی.
جدولهای مرجع
Section titled “جدولهای مرجع”image در برابر container
Section titled “image در برابر container”| Image | Container | |
|---|---|---|
| ماهیت | قالب ثابت و فقطخواندنی | نمونهی زنده (یا متوقفشده) |
| تغییر میکند؟ | نه | بله (لایهی قابلنوشتن) |
| تعداد | یک نسخه | هر چند تا از یک image |
| فهرست کردن | docker images |
docker ps و docker ps -a |
| حذف | docker rmi |
docker rm |
| تشبیه | دستور پخت | غذای پختهشده |
گزینههای پرکاربرد docker run
Section titled “گزینههای پرکاربرد docker run”| گزینه | معنی |
|---|---|
-d |
اجرا در پسزمینه (detached) |
-p میزبان:کانتینر |
وصل کردن پورت سیستم به پورت کانتینر |
--name اسم |
دادن اسم به کانتینر |
--rm |
حذف خودکار کانتینر بعد از تمام شدن |
--memory 100m |
سقف حافظه (cgroup) |
-it |
حالت تعاملی با ترمینال (در درسهای بعد) |
-e ، -v |
متغیر محیطی و volume (در درسهای بعد) |
وضعیتهای کانتینر
Section titled “وضعیتهای کانتینر”| وضعیت | یعنی |
|---|---|
Up ... |
در حال اجرا |
Exited (0) |
تمام شد، بدون خطا |
Exited (1) یا عدد دیگر |
با خطا بسته شد |
Created |
ساخته شده ولی هنوز شروع نشده |
اشتباهات رایج
Section titled “اشتباهات رایج”۱) «پورت اشغال است»
Section titled “۱) «پورت اشغال است»”اگر یک کانتینر روی پورت 8099 سیستم داری و یکی دیگر را هم روی همان پورت بالا بیاوری:
docker run -d -p 8099:80 --name lx-web2 nginxdocker: Error response from daemon: failed to set up container networking: driver failed programming external connectivity on endpoint lx-web2 (049243535be9...): Bind for 0.0.0.0:8099 failed: port is already allocatedport is already allocated یعنی «پورت ۸۰۹۹ سیستم را قبلاً کسی گرفته». راهحل: یا یک پورت دیگر بده (-p 8100:80)، یا با docker ps ببین کدام کانتینر آن پورت را گرفته و آن را stop کن. یادت هست در درس پروسهها و پورتها هم خطای مشابه (Address already in use) را دیدی؟ همان مفهوم است.
۲) «اسم تکراری است»
Section titled “۲) «اسم تکراری است»”docker run -d --name lx-web nginxdocker: Error response from daemon: Conflict. The container name "/lx-web" is already in use by container "6f9fc794369f...". You have to remove (or rename) that container to be able to reuse that name.اسم هر کانتینر باید یکتا باشد، حتی اگر متوقفشده باشد. راهحل: docker rm lx-web و دوباره بساز. یا اسم دیگری بده.
۳) «image را نمیتوانی پاک کنی»
Section titled “۳) «image را نمیتوانی پاک کنی»”docker rmi nginxError response from daemon: conflict: unable to delete nginx:latest (must be forced) - container 527352eda9a7 is using its referenced image abe47724e466تا وقتی کانتینری (حتی متوقفشده) از آن image ساخته شده، نمیشود image را پاک کرد. راهحل: اول کانتینر را docker rm کن، بعد docker rmi. (استفاده از -f ممکن است ولی بهتر است وقتی دلیلش را میدانی.)
۴) «کانتینرم ساخته شد ولی در docker ps نیست!»
Section titled “۴) «کانتینرم ساخته شد ولی در docker ps نیست!»”docker run -d --name lx-up ubuntu:24.04docker ps --filter name=lx-up --format 'table {{.ID}}\t{{.Image}}\t{{.Status}}'docker ps -a --filter name=lx-up --format 'table {{.ID}}\t{{.Image}}\t{{.Command}}\t{{.Status}}'CONTAINER ID IMAGE STATUSCONTAINER ID IMAGE COMMAND STATUSa6824b661bfc ubuntu:24.04 "/bin/bash" Exited (0) 1 second agoدستور اول فقط سرستونها را چاپ کرد (هیچ کانتینر در حال اجرایی نیست) و دستور دوم کانتینر متوقفشده را نشان داد.
یادت هست گفتیم کانتینر یک پروسه است؟ وقتی پروسهی اصلی تمام شود، کانتینر هم تمام میشود. در image اوبونتو (Ubuntu) پروسهی اصلی bash است و چون هیچ ترمینالی به آن وصل نیست، همان لحظه خارج میشود. کانتینر خراب نشد؛ فقط کارش تمام شد. برای نگه داشتن، باید پروسهای بدهی که ادامه بدهد (مثل وبسرور nginx که داخلش nginx -g daemon off; همیشه میماند). تمیزکاری: docker rm lx-up.
با یک دستور از یک کانتینر ubuntu بخواه که جملهی Hello from a container را چاپ کند، و کانتینر بعد از کار خودکار پاک شود.
دیدن جواب
docker run --rm ubuntu:24.04 echo "Hello from a container"Hello from a container--rm کانتینر را بعد از تمام شدن پاک میکند. اگر docker ps -a بزنی اثری از آن نیست.
یک وبسرور nginx با اسم lx-ex روی پورت 8100 سیستمات بالا بیاور. با curl ثابت کن جواب 200 میدهد. بعد آن را متوقف و حذف کن و ثابت کن دیگر وجود ندارد.
دیدن جواب
docker run -d -p 8100:80 --name lx-ex nginxcurl -s -o /dev/null -w "%{http_code}\n" localhost:8100docker stop lx-exdocker rm lx-exdocker ps -a --filter name=lx-ex -q | wc -l01e94a9deb37...200lx-exlx-ex0دستور آخر شناسهی کانتینرهایی با آن اسم را میشمارد و 0 یعنی هیچ. (اگر curl را فوراً بعد از run زدی و خطا گرفتی، دو ثانیه صبر کن تا nginx بالا بیاید.)
دو کانتینر از یک image بساز: کانتینر lx-a فایلی به اسم /tmp/note.txt با محتوای hello بسازد، و کانتینر lx-b فقط محتوای /tmp را فهرست کند. بدون ورود به کانتینر ثابت کن فایل فقط در lx-a وجود دارد. بعد توضیح بده چرا، و هر دو را پاک کن.
دیدن جواب
docker run --name lx-a ubuntu:24.04 sh -c 'echo hello > /tmp/note.txt'docker run --name lx-b ubuntu:24.04 sh -c 'ls /tmp'docker diff lx-adocker diff lx-bdocker rm lx-a lx-bC /tmpA /tmp/note.txtدستور ls /tmp در lx-b هیچ چیزی چاپ نکرد و docker diff lx-b هم خالی است. فقط lx-a تغییر دارد (A /tmp/note.txt).
چرا؟ هر دو از یک image ساخته شدهاند و لایههای image فقطخواندنی و مشترکاند. فایل جدید در لایهی قابلنوشتن مخصوص lx-a نوشته شد، و lx-b لایهی قابلنوشتن خودش را دارد که خالی است. کانتینرها از هم جدا هستند.
آزمونک
Section titled “آزمونک”کانتینر دقیقاً چیست؟
کانتینر سیستمعامل جدا ندارد؛ پروسهای است که با namespace و cgroup از بقیه جدا شده است.
فرق image و container چیست؟
مثل دستور پخت (image) و غذای پختهشده (container). از یک image میشود چند container ساخت.
در دستور «docker run -d -p 8099:80 nginx»، عدد 8099 مربوط به کجاست؟
ترتیب «پورت-میزبان:پورت-کانتینر» است. 8099 سیستم تو است و 80 داخل کانتینر.
چرا کانتینر «docker run -d ubuntu:24.04» در docker ps دیده نمیشود؟
کانتینر تا وقتی زنده است که پروسهی اصلیاش زنده باشد. با docker ps -a کانتینر متوقفشده را میبینی.
اگر داخل یک کانتینر فایل بسازی و آن کانتینر را حذف کنی، چه میشود؟
دادهها در لایهی قابلنوشتن همان کانتینر هستند. برای ماندگاری باید از volume استفاده کرد (درسهای بعد).
جمعبندی
Section titled “جمعبندی”- داکر مشکل «روی سیستم من کار میکرد» را با بستهبندی برنامه همراه همهی وابستگیهایش حل میکند.
- Image قالب فقطخواندنی است، container نمونهی در حال اجرای آن، و registry انبار image ها (مثل Docker Hub).
- از بیرون:
dockerCLI باdockerdحرف میزند. از درون:containerdوruncبا کمک namespace (جداسازی)، cgroup (محدودیت منابع) و لایههای فایل کانتینر را میسازند. - کانتینر یک پروسه است. وقتی پروسهی اصلی تمام شود، کانتینر هم تمام میشود.
- هر کانتینر یک لایهی قابلنوشتن موقت دارد؛ با حذف کانتینر، آن دادهها هم میروند.
- داکر روی مک و ویندوز داخل یک VM لینوکسی اجرا میشود (روی ویندوز، با WSL 2).
| دستور | کاری که میکند |
|---|---|
docker --version | نسخهی docker CLI |
docker version | نسخهی CLI و daemon (Client و Server) |
docker info | اطلاعات کلی daemon (هسته، runtime، ...) |
docker run IMAGE | ساخت و اجرای کانتینر (و pull اگر image نباشد) |
docker run -d -p 8099:80 --name NAME IMAGE | اجرا در پسزمینه، با پورت و اسم |
docker run --rm IMAGE CMD | اجرای یک دستور و پاک شدن خودکار کانتینر |
docker run --memory 100m IMAGE | سقف حافظه برای کانتینر |
docker ps | کانتینرهای در حال اجرا |
docker ps -a | همهی کانتینرها (حتی متوقفشده) |
docker images | image های روی سیستم |
docker logs NAME | لاگ کانتینر |
docker top NAME | پروسههای داخل کانتینر |
docker diff NAME | تغییرات لایهی قابلنوشتن (A، C، D) |
docker history IMAGE | لایههای image و دستور ساخت هر کدام |
docker image inspect IMAGE | جزئیات کامل image (مثلاً تعداد لایهها) |
docker stop NAME | توقف کانتینر |
docker rm NAME | حذف کانتینر |
docker rmi IMAGE | حذف image |
در درس بعد کانتینر را کنار ماشین مجازی میگذاریم و دقیق مقایسهشان میکنیم.