- پیشنیازها
- راهاندازی یک کانتینر آزمایشی
- پیدا کردن نام یا شناسه (ID) کانتینرهای در حال اجرا
- اجرای یک شِل تعاملی در داخل یک کانتینر داکر
- اجرای دستور غیرتعاملی در یک کانتینر داکر
- اجرای دستورات در یک دایرکتوری دیگر در کانتینر داکر
- خطاهای رایج و اشکالزدایی
- راهکارهای رفع مشکلات رایج هنگام استفاده از docker exec
- نکات بهینهسازی عملکرد هنگام اجرای دستورهای سنگین با docker exec
- سوالات متداول (FAQs)
- نتیجهگیری

آموزش استفاده از Docker Exec برای دسترسی و مدیریت کانتینرها
Docker یک ابزار کانتینریسازی است که به توسعهدهندگان کمک میکند کانتینرهای لینوکسی قابلحمل و سازگار ایجاد و مدیریت کنند.
هنگام توسعه یا استقرار کانتینرها، اغلب نیاز دارید که داخل یک کانتینر در حال اجرا نگاه بیندازید تا وضعیت فعلی آن را بررسی کرده یا مشکلی را دیباگ کنید. برای این منظور، Docker دستور docker exec
را ارائه میدهد تا برنامههایی را در کانتینرهای در حال اجرا اجرا کنید.
در این آموزش، با دستور docker exec
و نحوه استفاده از آن برای اجرای دستورات و دریافت یک شل تعاملی در یک کانتینر Docker آشنا خواهیم شد.
پیشنیازها
این آموزش فرض میکند که Docker قبلاً نصب شده و کاربر شما اجازه اجرای دستورات Docker را دارد. اگر نیاز دارید دستورات Docker را به عنوان کاربر ریشه (root) اجرا کنید، لطفاً به یاد داشته باشید که قبل از دستورات این آموزش sudo
اضافه کنید.
برای اطلاعات بیشتر درباره استفاده از Docker بدون دسترسی sudo
، لطفاً به بخش «اجرای دستور Docker بدون sudo» در آموزش «نحوه نصب Docker» مراجعه کنید.
راهاندازی یک کانتینر آزمایشی
برای استفاده از دستور docker exec
، نیاز به یک کانتینر در حال اجرای Docker دارید. اگر در حال حاضر کانتینری ندارید، میتوانید با استفاده از دستور زیر یک کانتینر آزمایشی راهاندازی کنید:
docker run -d --name container-name alpine watch "date >> /var/log/date.log"
این دستور یک کانتینر جدید از ایمیج رسمی Alpine ایجاد میکند. این یک ایمیج کانتینری لینوکسی محبوب است که از Alpine Linux استفاده میکند؛ توزیعی کمحجم و مینیمال از لینوکس.
ما از گزینه -d
برای جدا کردن کانتینر از ترمینال و اجرای آن در پسزمینه استفاده میکنیم. --name container-name
نام کانتینر را container-name
قرار میدهد. میتوانید هر نامی را به دلخواه وارد کنید یا این قسمت را حذف کنید تا Docker بهطور خودکار یک نام یکتا تولید کند.
در ادامه alpine
را داریم، که مشخص میکند از چه ایمیجی برای کانتینر استفاده شود.
در نهایت، watch "date >> /var/log/date.log"
دستوری است که میخواهیم در کانتینر اجرا شود. دستور watch
به طور مکرر دستور دادهشده را، بهطور پیشفرض هر دو ثانیه یکبار، اجرا میکند. در اینجا، دستوری که watch اجرا میکند این است: date >> /var/log/date.log
.
دستور date
تاریخ و زمان فعلی را چاپ میکند، مثلاً:
Fri Jul 23 14:57:05 UTC 2021
قسمت >> /var/log/date.log
خروجی دستور date
را به فایل /var/log/date.log
هدایت کرده و به انتهای آن اضافه میکند. هر دو ثانیه یک خط جدید به فایل اضافه میشود و پس از چند ثانیه فایل چیزی شبیه این خواهد شد:
Fri Jul 23 15:00:26 UTC 2021
Fri Jul 23 15:00:28 UTC 2021
Fri Jul 23 15:00:30 UTC 2021
Fri Jul 23 15:00:32 UTC 2021
Fri Jul 23 15:00:34 UTC 2021
در مرحله بعد، یاد میگیریم که چگونه نام کانتینرهای Docker را پیدا کنیم. این زمانی مفید است که قبلاً کانتینری دارید که میخواهید روی آن کار کنید اما از نام آن مطمئن نیستید.
پیدا کردن نام یا شناسه (ID) کانتینرهای در حال اجرا
اگر قبلاً یک یا چند کانتینر در حال اجرا دارید و میخواهید نام یا شناسه آنها را پیدا کنید تا از دستور docker exec
استفاده کنید، میتوانید دستور زیر را اجرا کنید:
docker ps
این دستور فهرستی از تمام کانتینرهای در حال اجرا را همراه با جزئیات زیر نمایش میدهد:
- شناسه کانتینر (CONTAINER ID)
- اییج مورد استفاده (IMAGE)
- دستوری که کانتینر با آن اجرا شده (COMMAND)
- مدت زمان اجرا (CREATED)
- مدت زمانی که در حال اجراست (STATUS)
- پورتهای نگاشت شده (PORTS)
- نام اختصاص داده شده به کانتینر (NAMES)
برای نمونه:
OutputCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
76aded7112d4 alpine "watch 'date >> /var…" 11 seconds ago Up 10 seconds container-name
در این مثال، نام کانتینر ما container-name
است که میتوانیم برای اجرای دستور docker exec
از آن استفاده کنیم.
اگر مایل باشید نام کانتینر خود را تغییر دهید، از دستور docker rename
استفاده کنید:
docker rename container-name new-name
در ادامه، چندین مثال از استفاده از دستور docker exec
برای اجرای دستورات در یک کانتینر داکر را بررسی خواهیم کرد.
اجرای یک شِل تعاملی در داخل یک کانتینر داکر
اگر نیاز دارید یک شِل تعاملی (Interactive Shell) را در داخل یک کانتینر داکر اجرا کنید—مثلاً برای بررسی سیستم فایل یا اشکالزدایی پردازشهای در حال اجرا—از دستور docker exec
همراه با دو گزینهی -i
و -t
استفاده کنید.
گزینهی -i
ورودی را برای کانتینر باز نگه میدارد و گزینهی -t
یک ترمینال مجازی (pseudo-terminal) ایجاد میکند تا شِل بتواند به آن متصل شود. این دو گزینه را میتوان بهصورت زیر ترکیب کرد:
docker exec -it container-name sh
این دستور شِل sh
را در کانتینر مشخصشده اجرا میکند و یک پرامپت سادهی شِل در اختیار شما قرار میدهد. برای خروج از کانتینر، کافی است دستور exit
را وارد کرده و ENTER را بزنید:
exit
اگر ایمیج کانتینر شما شامل یک شِل پیشرفتهتر مانند bash
باشد، میتوانید بهجای sh
از bash
استفاده کنید.
اجرای دستور غیرتعاملی در یک کانتینر داکر
اگر نیاز دارید یک دستور را در داخل یک کانتینر در حال اجرای داکر اجرا کنید، ولی نیازی به تعامل (ورودی کاربر) ندارید، میتوانید از دستور docker exec
بدون هیچ گزینهای استفاده کنید:
docker exec container-name tail /var/log/date.log
این دستور، فرمان tail /var/log/date.log
را در کانتینری با نام container-name
اجرا میکند و خروجی آن را نمایش میدهد. بهطور پیشفرض، دستور tail
ده خط آخر فایل را چاپ میکند. اگر در حال اجرای کانتینر دمو هستید که در بخش اول تنظیم کردهایم، خروجی چیزی شبیه به این خواهد بود:
Mon Jul 26 14:39:33 UTC 2021
Mon Jul 26 14:39:35 UTC 2021
Mon Jul 26 14:39:37 UTC 2021
Mon Jul 26 14:39:39 UTC 2021
Mon Jul 26 14:39:41 UTC 2021
Mon Jul 26 14:39:43 UTC 2021
Mon Jul 26 14:39:45 UTC 2021
Mon Jul 26 14:39:47 UTC 2021
Mon Jul 26 14:39:49 UTC 2021
Mon Jul 26 14:39:51 UTC 2021
این دستور در اصل همان کاری را میکند که در مرحله قبل با اجرای شِل تعاملی (docker exec -it container-name sh
) انجام دادیم و سپس در آن شِل، فرمان tail /var/log/date.log
را اجرا کردیم. اما در این حالت بدون نیاز به باز کردن شِل مجازی (pseudo-terminal)، مستقیماً خروجی دستور را در یک مرحله به ما میدهد.
اجرای دستورات در یک دایرکتوری دیگر در کانتینر داکر
برای اجرای یک دستور در یک دایرکتوری مشخص در کانتینر، میتوانید از گزینه --workdir
استفاده کنید تا دایرکتوری کاری را تعیین کنید:
docker exec --workdir /tmp container-name pwd
در این مثال، دایرکتوری /tmp
بهعنوان دایرکتوری کاری (working directory) تعیین میشود، سپس دستور pwd
اجرا میشود که دایرکتوری فعلی را چاپ میکند:
/tmp
دستور pwd
تأیید میکند که دایرکتوری کاری کنونی /tmp
است.
اجرای دستورات به عنوان کاربر متفاوت در کانتینر داکر
برای اجرای یک دستور به عنوان یک کاربر متفاوت داخل کانتینر، میتوانید از گزینه --user
استفاده کنید:
docker exec --user guest container-name whoami
این دستور، فرمان whoami
را به عنوان کاربر guest
در کانتینر اجرا میکند. دستور whoami
نام کاربری جاری را چاپ میکند:
Output
guest
این خروجی تأیید میکند که کاربر فعلی در کانتینر، guest
است.
ارسال متغیرهای محیطی (Environment Variables) به کانتینر داکر
گاهی نیاز است متغیرهای محیطی را همراه دستور به کانتینر ارسال کنید. برای این کار، گزینه -e
به شما امکان میدهد یک متغیر محیطی مشخص کنید:
docker exec -e TEST=sammy container-name env
این دستور متغیر محیطی TEST
را با مقدار sammy
تنظیم کرده و سپس دستور env
را در کانتینر اجرا میکند. دستور env
تمام متغیرهای محیطی را نمایش میدهد:
Output
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=76aded7112d4
TEST=sammy
HOME=/root
در خروجی مشاهده میشود که متغیر TEST
برابر sammy
تنظیم شده است.
برای تنظیم چند متغیر، میتوانید گزینه -e
را برای هر متغیر تکرار کنید:
docker exec -e TEST=sammy -e ENVIRONMENT=prod container-name env
ارسال فایل متغیرهای محیطی به کانتینر
اگر بخواهید فایل حاوی چند متغیر محیطی را به کانتینر ارسال کنید، از گزینه --env-file
استفاده کنید.
ابتدا فایل متنی حاوی متغیرها را بسازید. مثلاً با ویرایشگر nano:
nano .env
نام .env
رایج است چون برای مدیریت تنظیمات خارج از کنترل نسخه استفاده میشود.
داخل فایل، متغیرها را به شکل KEY=value
، هر خط یک متغیر، بنویسید:
.env
TEST=sammy
ENVIRONMENT=prod
فایل را ذخیره و ببندید (در nano، CTRL+O سپس ENTER برای ذخیره و CTRL+X برای خروج).
سپس دستور زیر را اجرا کنید تا فایل به کانتینر ارسال شود:
docker exec --env-file .env container-name env
خروجی:
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=76aded7112d4
TEST=sammy
ENVIRONMENT=prod
HOME=/root
متغیرهای داخل فایل به درستی تنظیم شدهاند.
نکته: میتوانید چند فایل را با استفاده از چند بار گزینه --env-file
مشخص کنید. اگر متغیرهای چند فایل همپوشانی داشتند، فایل آخر اولویت خواهد داشت و متغیرهای آن جایگزین قبلیها میشوند.
خطاهای رایج و رفع آنها هنگام استفاده از دستور docker exec
خطاهای رایج و اشکالزدایی
هنگام استفاده از دستور docker exec، ممکن است با چند خطا و مشکل رایج مواجه شوید. در اینجا چند خطای رایج و راهحلهای آنها آورده شده است:
خطا: “Container not found”
Error: No such container: container-name
این خطا به این معناست که کانتینری با نام مشخص شده وجود ندارد و احتمالاً نام کانتینر اشتباه تایپ شده است. برای مشاهده کانتینرهای در حال اجرا از دستور زیر استفاده کنید و نام کانتینر را دوباره بررسی کنید:
docker ps
خطا: “Permission denied”
Error response from daemon: Permission denied
این خطا معمولاً زمانی رخ میدهد که کاربری که دستور docker exec
را اجرا میکند، دسترسی کافی برای دسترسی به کانتینر ندارد. مطمئن شوید کاربر مجوزهای لازم را دارد یا دستور را با sudo
اجرا کنید.
خطا: “Container is not running”
Error response from daemon: Container <container_id> is not running
این خطا نشان میدهد کانتینر مشخص شده وجود دارد اما در حال حاضر در حال اجرا نیست (متوقف شده یا کرش کرده). برای رفع این مشکل، کانتینر را با دستور زیر دوباره اجرا کنید:
docker start container-name
سپس میتوانید با دستور docker exec
به داخل کانتینر دستور بفرستید.
خطا: “Container is paused”
Error response from daemon: Container container-name is paused, unpause the container before exec
این خطا نشان میدهد که کانتینر در حالت pause است؛ یعنی متوقف نشده اما در حال اجرا هم نیست. قبل از اجرای دستور، باید کانتینر را از حالت pause خارج کنید:
docker unpause container-name
راهکارهای رفع مشکلات رایج هنگام استفاده از docker exec
- مطمئن شوید نام کانتینر صحیح است و کانتینر در حال اجراست.
- کاربری که دستور را اجرا میکند دسترسی کافی دارد.
- کانتینر در حالت pause نیست.
- دستور و گزینهها به درستی نوشته شدهاند.
نکات بهینهسازی عملکرد هنگام اجرای دستورهای سنگین با docker exec
وقتی دستورهای سنگین داخل کانتینر اجرا میکنید، مهم است که این عملیات باعث کند شدن کانتینر نشود. چند توصیه:
- استفاده از گزینه
--detach
برای اجرای دستوری که زمان زیادی میبرد، از این گزینه استفاده کنید تا دستور در پسزمینه اجرا شود و ترمینال شما آزاد بماند:
docker exec --detach container-name command
- محدود کردن منابع مصرفی
با استفاده از گزینههای--cpu-shares
و--memory
میزان منابع CPU و رم اختصاص یافته به دستور را محدود کنید:
docker exec --cpu-shares 512 --memory 512m container-name command
- بهینهسازی دستور
دستور را بهینه کنید تا سریعتر اجرا شود، مثلاً تقسیم کار بزرگ به بخشهای کوچکتر یا استفاده از الگوریتمهای بهتر:
docker exec container-name optimized-command
- استفاده از کانتینر جداگانه برای کارهای سنگین
اگر کاری منابع زیادی مصرف میکند، آن را در یک کانتینر جداگانه اجرا کنید تا روی عملکرد کانتینر اصلی تاثیر نگذارد:
docker run --name heavy-task-container heavy-task-image
- نظارت بر عملکرد کانتینر
با دستور زیر میتوانید عملکرد کانتینر را بررسی و مشکلات احتمالی را شناسایی کنید:
docker stats container-name
- اجتناب از اجرای دستورات غیرضروری
فقط دستورات ضروری را اجرا کنید و از اجرای دستورات اضافی که ممکن است کندی ایجاد کنند، خودداری کنید:
docker exec container-name necessary-command
- استفاده از امکانات داخلی داکر برای بهینهسازی
مثلاً گزینه--oom-kill-disable
برای جلوگیری از کشته شدن کانتینر به خاطر کمبود حافظه:
docker run --oom-kill-disable container-name
با رعایت این نکات، اجرای دستورات سنگین داخل کانتینرها با docker exec
به گونهای خواهد بود که تاثیر منفی روی عملکرد کل کانتینر نگذارد.
سوالات متداول (FAQs)
دستور docker exec چیست؟
دستور docker exec
یک فرمان داکر است که به شما اجازه میدهد یک دستور را داخل یک کانتینر داکر در حال اجرا اجرا کنید. این امکان را میدهد که بدون نیاز به ساخت کانتینر جدید، فرمانی را در یک کانتینر فعال اجرا کنید. این قابلیت برای اشکالزدایی، بررسی یا تغییر وضعیت کانتینر بسیار مفید است.
مثلاً برای اجرای دستور ساده ls
داخل کانتینر در حال اجرا، از دستور زیر استفاده میشود:
docker exec <container-name> ls
این دستور محتویات دایرکتوری جاری کانتینر را نشان میدهد و خروجی آن در ترمینال شما نمایش داده میشود.
چگونه با docker exec به شل کانتینر در حال اجرا دسترسی پیدا کنم؟
برای دسترسی به شل یک کانتینر در حال اجرا با docker exec
، از گزینههای -it
استفاده میکنیم.
-i
باعث میشود ورودی به کانتینر باز بماند.-t
یک ترمینال مجازی (pseudo-TTY) به کانتینر متصل میکند.
مثال:
docker exec -it <container-name> bash
این دستور یک جلسه شل جدید داخل کانتینر باز میکند و شما میتوانید همانند ورود مستقیم به سیستم با کانتینر تعامل کنید.
آیا میتوانم دستورات را به عنوان کاربر خاصی در کانتینر اجرا کنم؟
بله، با استفاده از گزینه --user
میتوانید دستور را با کاربر مشخصی داخل کانتینر اجرا کنید. این گزینه نام یا شناسه کاربر را مشخص میکند.
مثال اجرای دستور به عنوان کاربر root:
docker exec --user root <container-name> command
این دستور فرمان مشخص شده را داخل کانتینر با دسترسی root اجرا میکند.
چگونه چندین دستور را داخل کانتینر با docker exec اجرا کنم؟
برای اجرای چند دستور به صورت پشت سر هم، میتوانید دستورات را با ;
از هم جدا کنید و آنها را داخل گزینه -c
قرار دهید.
مثال:
docker exec <container-name> -c "command1; command2; command3"
این دستور به ترتیب command1
، سپس command2
و در نهایت command3
را داخل کانتینر اجرا میکند.
اگر docker exec کار نکرد، چه کنم؟
اگر دستور docker exec
به درستی اجرا نشد، این موارد را بررسی کنید:
- وضعیت کانتینر: با
docker ps
بررسی کنید که کانتینر در حال اجرا باشد. اگر نه، باdocker start
آن را راهاندازی کنید. - نام کانتینر: مطمئن شوید نام یا شناسه کانتینر درست وارد شده است.
- درستی دستور: اطمینان یابید دستور به درستی و با قالب درست نوشته شده باشد.
- پیکربندی کانتینر: ممکن است دستور نیاز به دسترسی یا مجوز خاصی داشته باشد؛ تنظیمات کانتینر را بررسی کنید.
- نسخه داکر: مطمئن شوید نسخه داکر نصب شده با دستوری که میخواهید اجرا کنید سازگار است (با
docker --version
بررسی کنید).
اگر هیچکدام از این موارد مشکل را حل نکرد، مستندات داکر را مطالعه کنید یا از یک متخصص داکر کمک بگیرید.
نتیجهگیری
در این آموزش، یاد گرفتید که چگونه از دستور docker exec
برای اجرای دستورات در یک کانتینر در حال اجرا استفاده کنید. همچنین نحوه اجرای دستورات ساده و نحوه ورود به یک شل تعاملی درون کانتینر را دیدید.
این ابزار ابزاری حیاتی برای دیباگ و مدیریت کانتینرهاست، بهویژه زمانی که در حال توسعه برنامههای تحت Docker یا عیبیابی آنها هستید.
منبع: DigitalOcean