
مقدمه
در بسیاری از محیطهای VPS، ممکن است تعدادی برنامه کوچک داشته باشید که میخواهید بهصورت دائمی اجرا شوند؛ چه این برنامهها اسکریپتهای کوچک شل باشند، چه اپهای Node.js یا پکیجهای بزرگتر.
معمولاً، پکیجهای خارجی با یک فایل یونیت عرضه میشوند که مدیریتشان توسط یک سیستم init مانند systemd را ممکن میکند؛ یا بهصورت ایمیجهای Docker بستهبندی میشوند که میتوان آنها را با یک موتور کانتینری مدیریت کرد. با این حال، وقتی نرمافزار بهخوبی بستهبندی نشده باشد یا وقتی ترجیح میدهید با سیستم init سطح پایین روی سرورتان تعامل نداشته باشید، داشتن یک جایگزین سبکوزن مفید است.
Supervisor یک مدیر پروسه است که یک رابط واحد برای مدیریت و مانیتورینگ تعدادی برنامه طولانیمدت فراهم میکند. در این آموزش، Supervisor را نصب کرده و از آن برای تعریف، شروع و مدیریت یک یا چند برنامه از طریق فایلهای پیکربندی ساده و مخصوص هر برنامه استفاده میکنید. همچنین یاد میگیرید که Supervisor چه جایگاهی در سیستمهای مدرن اوبونتو و دبیان دارد (که معمولاً توسط systemd مدیریت میشود) و راهنمایی عملی برای بهرهبرداری از برنامههای مدیریتشده با Supervisor در محیطهای واقعی — شامل لاگگیری و چرخش (Rotation) لاگ، امنیت و دسترسیها، بهترین شیوهها و عیبیابی — دریافت میکنید.
نکات کلیدی
- Supervisor یک مدیر پروسه سبکوزن برای نگهداشتن برنامههای طولانیمدت در حال اجرای قابلاتکا است؛ بهخصوص وقتی نرمافزار شما بهصورت سرویس بومی بستهبندی نشده است.
- روی اوبونتو و دبیان مدرن، خود Supervisor معمولاً توسط systemd مدیریت میشود؛ پس از systemctl برای مدیریت سرویس Supervisor و از supervisorctl برای مدیریت برنامههایی که Supervisor اجرا میکند، استفاده میکنید.
- یک گردش کار رایج برای تغییراتِ هر برنامه این است که فایل .conf زیر /etc/supervisor/conf.d/ را ویرایش کرده؛ سپس
sudo supervisorctl rereadوsudo supervisorctl updateرا برای اعمال بهروزرسانیها اجرا کنید. - برنامههای مدیریتشده توسط Supervisor باید در Foreground (حالت غیر Daemone) اجرا شوند؛ اگر خودشان به پسزمینه Fork کنند، ممکن است Supervisor وضعیتشان را اشتباه تشخیص داده و وارد حلقههای ریاستارت شود.
- پیکربندیِ به تفکیک برنامه سرراست و به سبک INI است و به شما اجازه میدهد دستور، رفتار autostart/autorestart و محل نوشتهشدن stdout/stderr را تعریف کنید.
- لاگگیری مبتنی بر فایل راهاندازی آسانی دارد؛ اما باید مطمئن شوید دایرکتوریهای لاگ از قبل وجود دارند و کاربر برنامه اجازه نوشتن در آنها را دارد.
- رشد لاگها به یک برنامه نیاز دارد: Supervisor از چرخش پایه از طریق
*_logfile_maxbytesو*_logfile_backupsپشتیبانی میکند؛ درحالیکه چرخش پیشرفتهتر و نگهداری لاگ معمولاً توسط ابزارهایی مانند logrotate یا سیستم لاگگیری متمرکز هندل میشود. - برای استفاده در production، روی اصول پایه امنیت و قابلیتاطمینان تمرکز کنید: برنامهها را با کاربر غیر root اجرا کنید، از مسیرهای مطلق و دایرکتوری کاری صریح استفاده کنید و خطاها را با لاگهای برنامه بههمراه systemctl/journalctl — وقتی خود سرویس Supervisor مشکل دارد — عیبیابی کنید.
پیشنیازها
برای تکمیل این راهنما به موارد زیر نیاز دارید:
- یک سرور اوبونتو و یک کاربر غیر root با دسترسی sudo. میتوانید درباره راهاندازی کاربری با این دسترسیها در راهنمای «راهاندازی اولیه سرور با اوبونتو» بیشتر یاد بگیرید.
مرحله ۱ — نصب
با بهروزرسانی منابع پکیج و نصب Supervisor شروع کنید:
sudo apt update && sudo apt install supervisor
سرویس Supervisor بعد از نصب بهطور خودکار اجرا میشود. میتوانید وضعیتش را بررسی کنید:
sudo systemctl status supervisor
باید خروجی زیر را دریافت کنید:
خروجی:
● supervisor.service - Supervisor process control system for UNIX
Loaded: loaded (/usr/lib/systemd/system/supervisor.service; enabled; preset: enabled)
Active: active (running) since Wed 2026-02-25 06:46:51 UTC; 2h 50min ago
Docs: http://supervisord.org
Main PID: 3027 (supervisord)
Tasks: 3 (limit: 4656)
Memory: 20.4M (peak: 21.2M)
CPU: 1min 18.224s
حالا که Supervisor نصب شده، میتوانیم به افزودن اولین برنامههای خود بپردازیم.
مدیریت Supervisor با systemd
روی سیستمهای مدرن اوبونتو و دبیان، دیمن Supervisor (supervisord) توسط systemd راهاندازی و نظارت میشود. در عمل، این یعنی دو لایه مدیریت وجود دارد و مهم است که از ابزار درست برای هر کار استفاده کنید.
- از systemctl برای مدیریت خودِ سرویس Supervisor استفاده میکنید (مثلاً برای شروع، توقف، ریاستارت یا فعالسازی هنگام بوت).
- از supervisorctl برای مدیریت برنامههایی که Supervisor اجرا میکند استفاده میکنید (مثلاً برای خواندن مجدد فایلهای پیکربندی، اعمال بهروزرسانیها، شروع و توقف یک برنامه یا مشاهده وضعیت).
قاعده کلی این است: اگر در حال عیبیابیِ اینکه آیا اصلاً Supervisor در حال اجراست هستید، از systemctl استفاده کنید. اگر در حال اعمال تغییر روی تعریف منفردی از یک برنامه زیر /etc/supervisor/conf.d/ هستید یا میخواهید یک برنامه تحتِ نظارت مشخص را کنترل کنید، از supervisorctl استفاده کنید.
مثلاً، میتوانید با این دستور مطمئن شوید Supervisor هنگام بوت راهاندازی میشود:
sudo systemctl enable supervisor
میتوانید بعد از اعمال تغییرات روی پیکربندی اصلی Supervisor (مثلاً /etc/supervisor/supervisord.conf)، آن را ریاستارت کنید:
sudo systemctl restart supervisor
اگر لازم باشد خودِ سرویس Supervisor را عیبیابی کنید، میتوانید لاگهایش را با journalctl بررسی کنید:
sudo journalctl -u supervisor --no-pager -n 50
در مقابل، اگر فقط در حال تغییر یک پیکربندیِ مربوط به یک برنامه زیر /etc/supervisor/conf.d/ هستید، معمولاً از sudo supervisorctl reread و sudo supervisorctl update برای بارگذاری آن تغییرات استفاده میکنید. این معمولاً به ریاستارت کل سرویس Supervisor ترجیح داده میشود؛ چون ریاستارت Supervisor میتواند همه برنامههایی که در حال حاضر مدیریت میکند را مختل کند.
مرحله ۲ — افزودن یک برنامه
یک بهترین شیوه در کار با Supervisor این است که برای هر برنامهای که قرار است هندل کند، یک فایل پیکربندی بنویسید.
توجه: برنامههایی که زیر Supervisor اجرا میشوند باید در حالت غیر Daemone (که گاهی «حالت Foreground» هم نامیده میشود) اجرا شوند. اگر برنامهتان بعد از شروع، شما را خودکار به شل برمیگرداند، مستندات برنامه را برای یافتن گزینه نگهداشتن آن در Foreground ببینید؛ در غیر این صورت Supervisor قادر نخواهد بود وضعیتش را بهطور قابلاتکا تشخیص دهد.
برای نمایش کارکرد Supervisor، یک اسکریپت شل میسازیم که کاری جز تولید خروجی قابل پیشبینی — یک بار در هر ثانیه — انجام نمیدهد؛ اما تا توقف دستی، بهطور پیوسته اجرا میشود. با nano یا ویرایشگر متن دلخواه خود، فایلی به نام idle.sh در دایرکتوری خانه خود باز کنید:
nano ~/idle.sh
محتوای زیر را اضافه کنید:
~/idle.sh
#!/bin/bash
while true
do
# ارسال تاریخ فعلی به stdout
echo "$(date)"
# ارسال 'error!' به stderr
echo 'error!' >&2
sleep 1
done
فایل را ذخیره کرده و ببندید. اگر از nano استفاده میکنید، Ctrl+X را فشار داده و سپس هنگام درخواست، Y و Enter را بزنید.
سپس، اسکریپت خود را قابل اجرا کنید:
chmod +x ~/idle.sh
فایلهای پیکربندیِ به تفکیک برنامه برای برنامههای Supervisor در دایرکتوری /etc/supervisor/conf.d قرار دارند. مرسوم است که هر برنامه در یک فایل جداگانه باشد و نام هر فایل پیکربندی با .conf تمام شود. برای این اسکریپت، فایل پیکربندی را بهعنوان /etc/supervisor/conf.d/idle.conf میسازیم:
sudo nano /etc/supervisor/conf.d/idle.conf
این محتوا را اضافه کنید:
/etc/supervisor/conf.d/idle.conf
[program:idle]
command=/home/<your_user>/idle.sh
autostart=true
autorestart=true
stderr_logfile=/var/log/idle.err.log
stdout_logfile=/var/log/idle.out.log
این را خط به خط بررسی میکنیم:
command=/home/<your_user>/idle.sh
پیکربندی با تعریف برنامهای با نام idle و مسیر کامل آن شروع میشود. مقدار را با نام کاربری خود جایگزین کنید.
دو خط بعدی، رفتار خودکار اسکریپت را تحت شرایط مشخصی تعریف میکنند.
autostart=true
autorestart=true
گزینه autostart به Supervisor میگوید برنامه را هنگام شروع سرویس supervisord (معمولاً در طول بوت سیستم) راهاندازی کند. تنظیم آن روی false یعنی پس از هر خاموشی سیستم، شروع دستی لازم خواهد بود.
مقدار autorestart تعیین میکند Supervisor در صورت خروج برنامه، چطور باید آن را مدیریت کند:
- مقدار false به Supervisor میگوید هرگز بعد از خروج، برنامه را ریاستارت نکند.
- مقدار true به Supervisor میگوید همیشه بعد از خروج، برنامه را ریاستارت کند.
- مقدار unexpected به Supervisor میگوید فقط در صورتی برنامه را ریاستارت کند که با کد خروجِ غیرمنتظره خارج شود (بهصورت پیشفرض، هر چیزی غیر از کدهای ۰ یا ۲). برای اطلاعات بیشتر درباره کدهای خروج، به مستندات برنامهتان یا مستندات وضعیت خروج لینوکس مراجعه کنید.
دو خط پایانی، مکانهای دو فایل لاگ اصلی برنامه را تعریف میکنند.
stderr_logfile=/var/log/idle.err.log
stdout_logfile=/var/log/idle.out.log
همانطور که نام گزینهها پیشنهاد میکند، stdout و stderr به ترتیب به مکانهای stdout_logfile و stderr_logfile هدایت میشوند. دایرکتوریهای مشخصشده باید از قبل وجود داشته باشند؛ چون Supervisor تلاشی برای ساخت دایرکتوریهای غایب نمیکند.
پیکربندیای که اینجا ساختیم، یک قالب مینیمال برای یک برنامه Supervisor است. مستندات Supervisor گزینههای اختیاری بسیار بیشتری را فهرست میکند که برای تنظیم نحوه اجرای برنامهها در دسترساند.
وقتی فایل پیکربندیمان ساخته و ذخیره شد، میتوانیم از طریق دستور supervisorctl، Supervisor را از برنامه جدید خود مطلع کنیم. ابتدا به Supervisor میگوییم با این دستور بهدنبال هرگونه پیکربندی برنامه جدید یا تغییرکرده در دایرکتوری /etc/supervisor/conf.d بگردد:
sudo supervisorctl reread
خروجی:
idle: available
و سپس با این دستور به آن میگوییم تغییرات را اعمال کند:
sudo supervisorctl update
خروجی:
idle: added process group
هر بار که تغییری در هر فایل پیکربندی برنامه اعمال میکنید، اجرای دو دستور قبلی، آن تغییرات را اعمال میکند.
در این نقطه، برنامه ما باید در حال اجرا باشد. میتوانیم خروجیاش را با نگاه کردن به فایل لاگ خروجی بررسی کنیم:
sudo tail /var/log/idle.out.log
خروجی:
Wed Feb 25 06:59:00 UTC 2026
Wed Feb 25 06:59:01 UTC 2026
Wed Feb 25 06:59:02 UTC 2026
Wed Feb 25 06:59:03 UTC 2026
Wed Feb 25 06:59:04 UTC 2026
Wed Feb 25 06:59:05 UTC 2026
Wed Feb 25 06:59:06 UTC 2026
Wed Feb 25 06:59:07 UTC 2026
Wed Feb 25 06:59:08 UTC 2026
Wed Feb 25 06:59:09 UTC 2026
در ادامه، چند روش دیگر استفاده از Supervisor را پوشش میدهیم.
مرحله ۳ — مدیریت برنامهها
فراتر از اجرای برنامهها، میخواهید آنها را متوقف، ریاستارت یا وضعیتشان را بررسی کنید. برنامه supervisorctl که در مرحله ۲ استفاده کردیم، یک حالت تعاملی هم دارد که میتوانید برای کنترل برنامههایتان از آن استفاده کنید.
برای ورود به حالت تعاملی، supervisorctl را بدون آرگومان اجرا کنید:
sudo supervisorctl
خروجی:
idle RUNNING pid 12614, uptime 1:49:37
supervisor>
برنامه supervisorctl ابتدا وضعیت و مدت فعالیت (Uptime) همه برنامههای پیکربندیشده را چاپ کرده و سپس خط فرمان خود را نمایش میدهد. با وارد کردن help، همه دستورات در دسترسش آشکار میشوند:
help
خروجی:
default commands (type help <topic>):
=====================================
add exit open reload restart start tail
avail fg pid remove shutdown status update
clear maintail quit reread signal stop version
میتوانید برنامهای را با دستورات مربوطه و بههمراه نام برنامه شروع یا متوقف کنید:
stop idle
خروجی:
idle: stopped
start idle
خروجی:
idle: started
با دستور tail میتوانید آخرین ورودیهای لاگهای stdout و stderr برنامهتان را ببینید:
tail idle
خروجی:
Wed Feb 25 07:01:56 UTC 2026
Wed Feb 25 07:01:57 UTC 2026
Wed Feb 25 07:01:58 UTC 2026
Wed Feb 25 07:02:04 UTC 2026
Wed Feb 25 07:02:05 UTC 2026
Wed Feb 25 07:02:06 UTC 2026
Wed Feb 25 07:02:07 UTC 2026
Wed Feb 25 07:02:08 UTC 2026
Wed Feb 25 07:02:09 UTC 2026
Wed Feb 25 07:02:10 UTC 2026
Wed Feb 25 07:02:11 UTC 2026
tail idle stderr
خروجی:
error!
error!
error!
error!
error!
error!
error!
با status میتوانید بعد از اعمال هرگونه تغییر، وضعیت اجرای فعلی هر برنامه را دوباره ببینید:
status
خروجی:
idle RUNNING pid 3745, uptime 0:00:43
در نهایت، میتوانید با Ctrl+C یا با وارد کردن quit در خط فرمان، از supervisorctl خارج شوید:
quit
پیکربندی لاگ و چرخش آن
Supervisor میتواند جریانهای خروجی استاندارد (stdout) و خطای استاندارد (stderr) یک برنامه را در فایلهای لاگ اختصاصی بنویسد (مثلاً با تنظیم stdout_logfile و stderr_logfile در تعریف برنامه). این اغلب سادهترین راه ثبت لاگ برای اسکریپتها و سرویسهای کوچک است؛ چون میتوانید خروجی هر برنامه را در مکانهای قابل پیشبینی روی دیسک نگه دارید.
وقتی لاگگیری مبتنی بر فایل را پیکربندی میکنید، دو نکته عملی را در ذهن داشته باشید. اول اینکه دایرکتوریهایی که ارجاع میدهید باید از قبل وجود داشته باشند؛ چون Supervisor دایرکتوریهای غایب را برای شما نمیسازد. دوم اینکه برنامه باید اجازه نوشتن در مکانهای لاگی که مشخص میکنید را داشته باشد. مثلاً، اگر لاگها را زیر /var/log/ مینویسید، ممکن است لازم باشد یک زیردایرکتوری اختصاصی بسازید و مطمئن شوید مالکش همان کاربری است که برنامه را اجرا میکند.
برای سرویسهای طولانیمدت، مهم است که برنامهریزی کنید این لاگها چگونه چرخش (Rotate) شوند تا بدون سقف رشد نکنند و دیسک شما را پر نکنند.
Supervisor تنظیمات چرخش ساده لاگ را مستقیماً در هر تعریف برنامه پشتیبانی میکند. مثلاً، میتوانید گزینههایی مثل موارد زیر را برای کنترل اندازه لاگ و تعداد فایلهای چرخشیافته نگهداشتهشده اضافه کنید:
[program:idle]
command=/home/<your_user>/idle.sh
autostart=true
autorestart=true
stderr_logfile=/var/log/idle.err.log
stdout_logfile=/var/log/idle.out.log
stderr_logfile_maxbytes=10MB
stderr_logfile_backups=5
stdout_logfile_maxbytes=10MB
stdout_logfile_backups=5
در این مثال، Supervisor هر لاگ را وقتی از *_logfile_maxbytes بزرگتر شود چرخش میکند و تا *_logfile_backups فایل لاگ قدیمیتر نگه میدارد. این تنظیمات، محافظت پایهای در برابر رشد بیسقف لاگ — بدون نیاز به هیچ ابزار اضافی — فراهم میکنند.
اگر مدیریت پیشرفتهتری از لاگ لازم دارید (مثلاً فشردهسازی، چرخش مبتنی بر تاریخ یا سیاستهای متمرکز روی سرویسهای متعدد)، شاید راهحل سطح سیستمی مثل logrotate یا ارسال لاگها به یک سیستم لاگگیری متمرکز را ترجیح بدهید. در آن صورت، همچنان مفید است که Supervisor به مکانی پایدار بنویسد که Agent لاگگیری یا سیاست چرخش شما از قبل مانیتورش میکند.
ملاحظات امنیتی و دسترسی
از Supervisor اغلب برای نگهداشتن پروسههای اپلیکیشن در حال اجرا استفاده میشود؛ یعنی بهراحتی ممکن است به این پروسهها دسترسیای بیش از نیازشان بدهید. قبل از استقرار برنامههای مدیریتشده با Supervisor در production، ارزشش را دارد چند ملاحظه عملی امنیتی و دسترسی را مرور کنید.
اول، برنامههایتان را با کمترین دسترسیِ ممکن اجرا کنید. اگر برنامهتان به دسترسیهای root نیاز ندارد، آن را طوری پیکربندی کنید که با کاربر بدون دسترسی اجرا شود؛ با افزودن تنظیم user (و بهصورت اختیاری group) به تعریف برنامه. برای اپلیکیشنها، ساخت یک کاربر سرویس اختصاصی (مثلاً بدون شل تعاملی) اغلب ارزشمند است تا پروسههای production را بهطور تصادفی با حساب ورود شخصی خودتان اجرا نکنید.
[program:your_app]
command=/path/to/your/app
user=<your_user>
علاوه بر user و group، میتوانید ریسک را با تنظیم یک دایرکتوری کاری صریح و محدودکردن دسترسیهای پیشفرض فایل بیشتر کاهش دهید. این کار از غافلگیریهایی مثل نوشتن فایلها توسط برنامهها در دایرکتوریهای متعلق به root یا ساخت لاگهایی که توسط کاربران ناخواسته قابل خواندناند جلوگیری میکند:
[program:your_app]
command=/path/to/your/app
directory=/path/to/your/app
user=<your_user>
group=<your_group>
umask=027
دوم، مطمئن شوید برنامهتان فقط میتواند فایلهایی را که لازم دارد بخواند و بنویسد. در عمل، این معمولاً یعنی اطمینان از اینکه دایرکتوری اپلیکیشن، هر محیط مجازی و هر دایرکتوری لاگ، متعلق به کاربر درست بوده و دسترسیهای مناسبی دارند. اگر برنامهتان در فایلهای لاگ مینویسد (مثلاً زیر /var/log/)، مطمئن شوید دایرکتوری وجود دارد و توسط کاربر برنامه قابل نوشتن است؛ در غیر این صورت، ممکن است برنامه راهاندازی نشود یا بیصدا لاگهایش را از دست بدهد.
سوم، با فایلهای پیکربندی Supervisor مثل پیکربندی عملیاتیِ حساس رفتار کنید. آنها را در مکانهای متعلق به root مثل /etc/supervisor/conf.d/ ذخیره کنید، دسترسیها را محدود نگه دارید و هنگام ویرایش از sudo استفاده کنید. درباره اطلاعات محرمانه هم احتیاط کنید: پیکربندیهای Supervisor اغلب شامل آرگومانهای خط فرمان یا متغیرهای محیطی (مثلاً URLهای پایگاه داده، کلیدهای API و اطلاعات احراز هویت) هستند؛ پس از قابلخواندنشدن این فایلها برای غیرمدیران اجتناب کنید.
در نهایت، درباره در معرض نمایش گذاشتن اینترفیسهای کنترل Supervisor محتاط باشید. Supervisor را میتوان با Endpointهای کنترل HTTP پیکربندی کرد؛ اما نباید هیچ اینترفیس کنترلی را به اینترنت عمومی متصل (Bind) کنید؛ چون میتواند به مهاجمی اجازه شروع و توقف پروسهها یا خواندن اطلاعات عملیاتی بدهد. اگر به دلایل عملیاتی قابلیتهای کنترل از راه دور را فعال میکنید، آنها را به 127.0.0.1 یا یک شبکه مدیریت خصوصی متصل کرده، احراز هویت را الزامی کنید و مشخص کنید کدام کاربران میتوانند به سوکت یا Endpoint کنترل دسترسی داشته باشند. بهعنوان قاعده کلی، با دسترسی supervisorctl مثل دسترسی مدیریتی رفتار کنید.
Supervisor در برابر systemd
هم Supervisor و هم systemd میتوانند سرویسها را در حال اجرا نگه دارند، پروسهها را پس از شکست ریاستارت کنند و برنامهها را هنگام بوت راهاندازی کنند. با این حال، این دو مسئلههای متفاوتی را حل کرده و گردش کارهای عملیاتی متفاوتی را تشویق میکنند.
بهطور کلی، systemd مدیر سرویس پیشفرض و انتخاب اول برای توزیعهای مدرن لینوکس است. این سیستم بهطور عمیق با سیستمعامل یکپارچه شده و برای مدیریت سازگار سرویسهای سیستمی — با مفاهیم خوشتعریفِ وابستگی، ترتیب، محدودیتهای منبع و لاگهای ساختاریافته — طراحی شده است.
Supervisor یک سیستم کنترل پروسه است که روی راهاندازی و مانیتورینگ یک یا چند برنامه طولانیمدت از یک پیکربندی ساده و به سبک INI تمرکز دارد. این ابزار اغلب وقتی مفید است که یک رابط سبک و سازگار برای مدیریت چندین پروسه کوچک اپلیکیشنی میخواهید (بهخصوص اسکریپتها و اپهایی که فایل یونیت systemd ندارند) یا وقتی میخواهید همان گردش کار مدیریت برنامه را در پروژههای مختلف داشته باشید.
همچنین در نظر داشته باشید که روی اوبونتو و دبیان، خود Supervisor معمولاً توسط systemd راهاندازی میشود. به بیان دیگر، اغلب از systemctl برای مدیریت سرویس Supervisor و از supervisorctl برای مدیریت برنامههایی که Supervisor اجرا میکند استفاده خواهید کرد.
مقایسه زیر میتواند به تصمیمگیری درباره اینکه کدام ابزار را استفاده کنید کمک کند:
| موضوع | systemd | Supervisor |
|---|---|---|
| نقش اصلی | سیستم init سیستمعامل و مدیر سرویس | سیستم کنترل پروسه برای برنامههای طولانیمدت |
| بهترین کاربرد | سرویسهای سطح سیستمعامل و نرمافزارهای بستهبندیشده با فایل یونیت | پروسههای اپلیکیشن، اسکریپتها و پشتههای چندپروسهای کوچک |
| مدل پیکربندی | فایلهای یونیت با معناشناسی صریح وابستگی و ترتیب | بخشهای برنامه به سبک INI زیر /etc/supervisor/ (معمولاً /etc/supervisor/conf.d/) |
| رفتار شروع و ریاستارت | سیاستهای ریاستارت غنی، ترتیب و مدیریت وابستگی (مثلاً بعد از بالا آمدن شبکه) | رفتار خودکارِ Autostart و ریاستارتِ قابلاتکا برای هر برنامه؛ همراه با گروهبندی ساده و گزارش وضعیت |
| لاگگیری و دیدپذیری | بهصورت پیشفرض با Journal سیستم یکپارچه است؛ همراه journalctl برای کوئری | معمولاً stdout/stderr را در فایلهایی به تفکیک برنامه مینویسد؛ شامل tail در supervisorctl و تنظیمات پایه چرخش لاگ |
| ایزولاسیون و محدودیتها | از کنترلهای منبع مبتنی بر cgroups، گزینههای Sandbox و قابلیتهای Hardening در سطح سرویس پشتیبانی میکند | روی کنترل پروسه تمرکز دارد؛ ایزولاسیون و Hardening معمولاً توسط سیستمعامل و دسترسیهای فایل هندل میشوند |
| گردش کار معمول | systemctl start|stop|restart، systemctl status، journalctl -u <unit> | supervisorctl start|stop|status، supervisorctl reread|update، supervisorctl tail |
اگر در حال مدیریت یک سرویس منفردِ بهخوبی بستهبندیشده هستید، یک یونیت بومی systemd معمولاً سادهترین و استانداردترین رویکرد است. این رویکرد معمولاً انتخاب بهتری هم هست وقتی به وابستگیهای سرویس، ترتیب سختگیرانه، Hardening در سطح سیستمعامل یا یکپارچگی نزدیک با ابزارهای توزیع نیاز دارید.
اگر چند برنامه کوچک را مدیریت میکنید و یک پیکربندی و اینترفیس کنترل یکپارچه میخواهید، Supervisor میتواند جایگزینی عملی باشد. این بهخصوص زمانی صادق است که نیاز دارید چندین پروسه اپلیکیشنیِ که بهصورت سرویس بستهبندی نشدهاند را نظارت کنید؛ یا وقتی یک ابزار واحد (supervisorctl) را برای استارت/استاپ/وضعیت و دنبالکردن لاگ — بهصورت سازگار روی همه برنامههایتان — ترجیح میدهید.
بهترین شیوههای استفاده از Supervisor
وقتی با تدبر پیکربندی شود، Supervisor میتواند مدیریت پروسهای قابلاتکا و قابل پیشبینی برای بارهای کاری اپلیکیشنی فراهم کند. با این حال، بسیاری از مشکلات production از غفلتهای کوچک پیکربندی ناشی میشوند. بهترین شیوههای زیر به شما کمک میکنند یک استقرار امنتر، قابلنگهداریتر و مقاومتر از Supervisor بسازید.
اجرای برنامهها بهعنوان کاربر غیر root
بهصورت پیشفرض، برنامههای مدیریتشده توسط Supervisor با همان دسترسیهای سرویس supervisord اجرا میشوند؛ که معمولاً با کاربر root اجرا میشود. اجرای پروسههای اپلیکیشن با root بهندرت لازم بوده و تأثیر بالقوه یک آسیبپذیری امنیتی یا باگ اپلیکیشن را افزایش میدهد.
در بیشتر موارد، باید برای هر اپلیکیشن یک کاربر اختصاصی با کمترین دسترسی بسازید و از آن استفاده کنید. میتوانید این را با افزودن Directive مربوط به user در پیکربندی برنامهتان الزامی کنید:
[program:myapp]
command=/usr/local/bin/myapp
user=myappuser
autostart=true
autorestart=true
اجرای پروسهها با حداقل دسترسی، ریسک را بهطور چشمگیری کاهش داده و با شیوههای استاندارد امنیتی لینوکس همراستاست.
استفاده از مسیرهای مطلق بهصورت پیوسته
Supervisor برنامهها را داخل یک محیط شل تعاملی کامل اجرا نمیکند. در نتیجه، متغیرهای محیطی مانند $PATH ممکن است آنطور که انتظار دارید رفتار نکنند. مسیرهای نسبی یا Resolve خودکارِ دستورات میتوانند منجر به شکستهای ظریف و دشوارِ دیباگ شوند.
برای اجتناب از این مشکلات، همیشه از مسیرهای مطلق برای این موارد استفاده کنید:
- دستورات اجرایی (Executable)
- آرگومانهای اسکریپت
- دایرکتوریهای کاری
- مکانهای فایل لاگ
مثلاً:
command=/usr/bin/python3 /opt/myapp/app.py
directory=/opt/myapp
stdout_logfile=/var/log/supervisor/myapp.out.log
استفاده از مسیرهای صریح، رفتار سازگار در سراسر ریبوتها، محیطها و گردش کارهای اتوماسیون را تضمین میکند.
اطمینان از اجرای برنامهها در Foreground
Supervisor برای مدیریت پروسههای طولانیمدتِ Foreground طراحی شده است. اگر برنامهای خودش را Daemone کند (به پسزمینه Fork شود)، ممکن است Supervisor این را به اشتباه خروج برنامه تفسیر کرده و بارها سعی کند آن را ریاستارت کند.
قبل از افزودن هر اپلیکیشنی به Supervisor، تأیید کنید که در Foreground اجرا میشود. بسیاری از اپلیکیشنهای سرور، فلگهایی برای غیرفعالکردن حالت Daemone دارند. در صورت تردید، مستندات اپلیکیشن را ببینید و رفتار پسزمینهرفتن را صریحاً غیرفعال کنید.
قاعده کلی این است: اگر برنامهای بعد از شروع، بلافاصله کنترل را به شل برمیگرداند، بهاحتمال زیاد در حال Daemone شدن است و باید بازپیکربندی شود.
پیکربندی هوشمندانه ریاستارتهای خودکار
تنظیم autorestart قدرتمند است اما باید با احتیاط استفاده شود. درحالیکه ریاستارت خودکارِ پروسههای شکستخورده، دسترسپذیری را بهبود میدهد، یک سیاست ریاستارتِ بیشازحد تهاجمی میتواند مشکلات زیربنایی را پوشانده یا حلقههای کرش سریعی بسازد که منابع سیستم را مصرف میکنند.
برای بیشتر بارهای کاری production، یک پیکربندی متعادل توصیه میشود:
autorestart=unexpected
startsecs=5
startretries=3
این رویکرد به Supervisor میگوید برنامه را فقط وقتی بهطور غیرمنتظره خارج شود ریاستارت کند؛ قبل از موفقشمردنِ شروع، کمی صبر کند و از تلاشهای بینهایت ریاستارت اجتناب کند. مقدار autorestart=true را برای پروسههای Worker ساده و شناختهشدهای که انتظار اجرای پیوسته از آنها میرود نگه دارید.
منظم نگهداشتن فایلهای پیکربندی
با رشد تعداد برنامههای مدیریتشده، حفظ فایلهای پیکربندیِ شفاف و سازگار اهمیت فزایندهای پیدا میکند. پیکربندیهای نامنظم، عیبیابی را دشوارتر کرده و ریسک اشتباهات عملیاتی را افزایش میدهند.
باید این شیوهها را بپذیرید:
- یک تعریف برنامه در هر فایل ذخیره کنید
- از نامگذاری توصیفی فایلها استفاده کنید
- از قراردادهای نامگذاری سازگار پیروی کنید
- سرویسهای مرتبط را بهطور منطقی گروهبندی کنید
مثلاً:
/etc/supervisor/conf.d/
├── web-api.conf
├── worker-default.conf
├── worker-priority.conf
└── scheduler.conf
یک ساختار پیکربندی تمیز، در طول دیباگ و نگهداری آینده وقت شما را ذخیره میکند.
مدیریت فعال رشد لاگها
رشد کنترلنشده لاگ، یکی از رایجترین مشکلات عملیاتی در استقرارهای Supervisor است. چون Supervisor هم stdout و هم stderr را ثبت میکند، فایلهای لاگ — بهخصوص برای اپلیکیشنهای پرخروجی — میتوانند سریع رشد کنند.
در حداقل، باید چرخش داخلی لاگ Supervisor را فعال کنید:
stdout_logfile_maxbytes=50MB
stdout_logfile_backups=5
stderr_logfile_maxbytes=50MB
stderr_logfile_backups=5
این پیکربندی، اندازه هر لاگ را محدود کرده و تعداد ثابتی از فایلهای چرخشیافته را نگه میدارد. در محیطهای بزرگتر، ممکن است یکپارچهسازی با ابزار logrotate سیستمی یا یک پلتفرم لاگگیری متمرکز را هم در نظر بگیرید.
هرگز نباید اجازه دهید لاگهای مدیریتشده توسط Supervisor روی یک سیستم production بدون سقف رشد کنند.
اعتبارسنجی پیکربندیها قبل از اعمال تغییرات
یک خطای سینتکس کوچک در فایل پیکربندی Supervisor میتواند مانع شروع درست یک برنامه شود. برای اجتناب از Downtime غیرمنتظره، همیشه پیکربندیها را بهصورت کنترلشده اعتبارسنجی و بارگذاری مجدد کنید.
بعد از تغییر هر فایل برنامه، اجرا کنید:
sudo supervisorctl reread
sudo supervisorctl update
سپس وضعیت برنامه را تأیید کنید:
sudo supervisorctl status
این گردش کار به شما کمک میکند مشکلات پیکربندی را زود تشخیص داده و مطمئن شوید تغییرات بهطور ایمن اعمال میشوند.
تنظیم startsecs برای اپلیکیشنهای کندشونده
برخی اپلیکیشنها قبل از کاملاً عملیاتی شدن، به زمان اضافی برای راهاندازی اولیه نیاز دارند. اگر Supervisor پروسه را خیلی سریع بررسی کند، ممکن است برنامه را به اشتباه شکستخورده علامتگذاری کرده و ریاستارتهای غیرضروری انجام دهد.
اگر اپلیکیشن شما زمان شروع قابلتوجهی دارد، مقدار startsecs را افزایش دهید:
startsecs=10
این مقدار را کمی بالاتر از مدت شروعِ معمول اپلیکیشنتان تنظیم کنید. تنظیم درست از تشخیصهای کاذبِ شکست جلوگیری میکند.
استفاده از Supervisor برای بارهای کاری مناسب
اگرچه Supervisor بسیار توانمند است، برای جایگزینی سیستم init در سرویسهای اصلی سیستمعامل طراحی نشده است. توزیعهای مدرن لینوکس برای ارکستراسیون سرویسهای سطح پایین، مدیریت وابستگیها و ترتیب بوت به systemd متکیاند.
بهطور کلی، systemd را برای این موارد ترجیح بدهید:
- پایگاههای داده
- سرویسهای شبکه
- دیمنهای سیستم
- زیرساختهای حیاتی برای بوت
و Supervisor برای این موارد مناسبتر است:
- Workerهای اپلیکیشن
- مصرفکنندههای صف (Queue Consumer)
- کارهای پسزمینه
- پشتههای چندپروسهای اپلیکیشن
استفاده از هر ابزار برای هدفِ درستش، به معماری تمیزتر و قابلنگهداریتر منجر میشود.
مانیتور کردن خودِ سرویس Supervisor
در نهایت، به یاد داشته باشید که خود Supervisor هم یک سرویس حیاتی است. اگر دیمن Supervisor از اجرا بایستد، هیچکدام از برنامههای مدیریتشده شما ریاستارت یا مانیتور نخواهند شد.
در محیطهای production باید:
- مطمئن شوید سرویس Supervisor هنگام بوت فعال است
- آن را در سیستمهای مانیتورینگ و هشدار خود بگنجانید
- وضعیت پروسهها را بهصورت دورهای بازبینی کنید
- رویدادهای ریاستارت مکرر را بررسی کنید
یک مدیر پروسه فقط وقتی مؤثر است که خودش سالم و بهطور پیوسته در حال اجرا باقی بماند.
خطاهای رایج و عیبیابی
حتی وقتی Supervisor بهدرستی نصب شده باشد، ممکن است گاهی هنگام شروع یا مدیریت برنامهها با مشکلاتی روبرو شوید. بیشتر مشکلات از اشتباههای کوچک پیکربندی، عدم تطابق دسترسیها یا تفاوتهای محیطی بین شل شما و Supervisor ناشی میشوند. راهنمایی زیر، رایجترین سناریوهای شکست را پوشش داده و نحوه تشخیص روشمند آنها را توضیح میدهد.
در حال اجرا نبودن سرویس Supervisor
اگر دستور supervisorctl خطای اتصال گزارش کند یا هیچ برنامهای فهرست نکند، ممکن است خودِ دیمن Supervisor در حال اجرا نباشد.
ابتدا باید وضعیت سرویس را تأیید کنید:
sudo systemctl status supervisor
اگر سرویس غیرفعال است، آن را شروع کنید:
sudo systemctl start supervisor
اگر Supervisor شروع نشود یا فوراً خارج شود، لاگهای سرویس را برای شناسایی خطاهای پیکربندی یا شکستهای راهاندازی بررسی کنید:
sudo journalctl -u supervisor --no-pager -n 50
در بسیاری از موارد، خطاهای سینتکس در /etc/supervisor/supervisord.conf یا مسیرهای Include نامعتبر، مانع شروع موفق سرویس میشوند.
نمایش برنامه بهصورت FATAL یا BACKOFF
اگر Supervisor برنامهای را با وضعیت FATAL یا BACKOFF علامتگذاری کند، معمولاً یعنی پروسه بعد از راهاندازی خیلی سریع خارج میشود. Supervisor انتظار دارد برنامههای مدیریتشده در Foreground در حال اجرا بمانند؛ پس خروجهای سریع مثل شکست رفتار میشوند.
علتهای رایج شامل مسیر دستور نادرست، نبودن دسترسیهای اجرا، Daemone شدن خود برنامه، نبودن وابستگیهای اجرایی (Runtime) یا ناکافیبودن دسترسیهای فایل است.
عیبیابی را با اجرای دستیِ دستور — بهعنوان همان کاربری که در پیکربندی Supervisor تعیین شده — شروع کنید:
sudo -u <your_user> /full/path/to/program
اگر برنامه هنگام شروع دستی در Foreground باقی نماند، Supervisor قادر به مدیریت قابلاتکای آن نخواهد بود.
همچنین باید لاگهای برنامه را با این دستور بررسی کنید:
sudo supervisorctl tail <program_name>
خروجی لاگ اغلب دلیل دقیق شکست را آشکار میکند.
ناتوانی Supervisor در نوشتن فایلهای لاگ
اگر برنامهای فوراً شکست بخورد یا خروجی لاگی تولید نکند، مسئله اغلب به دسترسیهای فایل لاگ یا دایرکتوریهای غایب مربوط است.
به یاد داشته باشید که Supervisor دایرکتوریهای والد را خودکار نمیسازد. دایرکتوری مشخصشده در stdout_logfile و stderr_logfile باید از قبل وجود داشته باشد و کاربرِ پیکربندیشده برنامه، دسترسی نوشتن داشته باشد.
مثلاً، اگر قصد ذخیره لاگها زیر /var/log/ را دارید، باید دایرکتوری را ساخته و مالکیتش را بهدرستی تخصیص دهید:
sudo mkdir -p /var/log/supervisor
sudo chown <your_user>:<your_user> /var/log/supervisor
پس از اصلاح دسترسیها، پیکربندی برنامه را بارگذاری مجدد کرده و دوباره سعی کنید پروسه را شروع کنید.
اعمالنشدن تغییرات پیکربندی
اگر فایلی زیر /etc/supervisor/conf.d/ را تغییر میدهید اما هیچ تغییری در رفتار برنامه نمیبینید، بهاحتمال زیاد Supervisor پیکربندی بهروز شده را بارگذاری مجدد نکرده است.
بعد از ویرایش هر فایل پیکربندیِ مربوط به یک برنامه، همیشه این دستورات را اجرا کنید:
sudo supervisorctl reread
sudo supervisorctl update
دستور reread به Supervisor دستور میدهد فایلهای پیکربندی جدید یا تغییرکرده را تشخیص دهد و دستور update آن تغییرات را اعمال میکند.
در بیشتر موارد، وقتی فقط پیکربندیهایِ مربوط به برنامهها تغییر کردهاند، نیازی به ریاستارت کل سرویس Supervisor ندارید.
اجرا شدن برنامه بهصورت دستی اما شکست زیر Supervisor
اگر برنامهتان از خط فرمان با موفقیت اجرا میشود اما هنگام مدیریت توسط Supervisor شکست میخورد، مسئله معمولاً از تفاوتهای محیطی ناشی میشود.
برنامههایی که توسط Supervisor شروع میشوند، محیط شل تعاملی شما را به ارث نمیبرند. در نتیجه، شکستها معمولاً به دلیل نبودن متغیرهای محیطی، دایرکتوری کاری نادرست، تفاوتهای PATH یا عدم تطابق دسترسیها رخ میدهند.
بسیاری از این مشکلات را میتوانید با تعریف صریح دایرکتوری کاری در پیکربندی برنامه حل کنید:
directory=/path/to/your/app
اگر اپلیکیشن شما به متغیرهای محیطی وابسته است، آنها را مستقیماً در پیکربندی تعریف کنید:
environment=ENV_VAR="value",OTHER_VAR="value"
صریحبودن درباره زمینه اجرا، به تضمین رفتار سازگار بین اجراهای دستی و اجرای مدیریتشده توسط Supervisor کمک میکند.
اشغال بودن از قبلِ سوکت یا پورت
اگر Supervisor بارها سعی کند یک سرویس شبکهای را که به پورتی متصل میشود شروع کند، ممکن است سرویس به دلیل اشغال بودن از قبلِ پورت در حال شکست باشد.
میتوانید با این دستور بررسی کنید کدام پروسه در حال حاضر روی پورتی گوش میدهد:
sudo ss -tulpn | grep <port>
اگر اینستنس دیگری از اپلیکیشن از قبل خارج از Supervisor در حال اجراست، قبل از اجازهدادن به Supervisor برای مدیریت سرویس آن را متوقف کنید. اجرای اینستنسهای تکراری از یک سرویس اغلب به حلقههای گیجکننده ریاستارت منجر میشود.
ریاستارتهای سریعِ مکرر
اگر برنامهای بارها و در فاصلههای کوتاه کرش کرده و ریاستارت شود، ممکن است Supervisor پس از اتمام تلاشهای Retry در نهایت آن را FATAL علامتگذاری کند. اگرچه میتوانید رفتار ریاستارت را بخشندهتر کنید، ریاستارتهای مکرر معمولاً به یک مشکل زیربنایی اپلیکیشن اشاره دارند که باید بررسی شود.
برای بارهای کاری که واقعاً به زمان شروع بیشتری نیاز دارند، میتوانید این تنظیمات راチبین کنید:
startsecs=5
startretries=3
autorestart=unexpected
با این حال، از پوشاندن شکستهای واقعی اپلیکیشن با افزایش ساده سقفهای Retry — بدون درک علت ریشهای — اجتناب کنید.
ناتوانی supervisorctl در اتصال به سوکت
اگر با خطایی مشابه این روبرو شدید:
unix:///var/run/supervisor.sock no such file
ممکن است دیمن Supervisor در حال اجرا نباشد یا سوکت کنترل دسترسیهای نادرستی داشته باشد.
ابتدا تأیید کنید که سرویس Supervisor فعال است:
sudo systemctl status supervisor
اگر سرویس در حال اجراست، بررسی کنید مسیر سوکتِ پیکربندیشده در /etc/supervisor/supervisord.conf با چیزی که supervisorctl انتظار دارد مطابقت داشته باشد. همچنین مطمئن شوید کاربرِ اجراکننده supervisorctl اجازه دسترسی به سوکت را دارد.
سوالات متداول
۱. Supervisor روی اوبونتو چه کاربردی دارد؟
Supervisor یک سیستم کنترل پروسه است که روی اوبونتو برای مدیریت و مانیتورینگ اپلیکیشنهای طولانیمدت و سرویسهای پسزمینه استفاده میشود. این ابزار به شما اجازه میدهد برنامهها را بهطور خودکار شروع کنید، در صورت کرش ریاستارتشان کنید و چندین پروسه را از یک رابط واحد مدیریت کنید. کاربرد رایج آن برای Workerهای اپلیکیشن، مصرفکنندههای صف و سرویسهای سفارشیای است که بهصورت یونیت بومی systemd بستهبندی نشدهاند.
۲. چطور Supervisor را روی اوبونتو شروع کنم؟
روی اوبونتو، Supervisor بهعنوان یک سرویس systemd اجرا میشود. میتوانید با اجرای این دستور آن را شروع کنید:
sudo systemctl start supervisor
برای اطمینان از شروع خودکار Supervisor هنگام بوت، سرویس را فعال کنید:
sudo systemctl enable --now supervisor
میتوانید با sudo systemctl status supervisor تأیید کنید که در حال اجراست.
۳. فایلهای پیکربندی Supervisor کجا قرار دارند؟
روی سیستمهای اوبونتو و دبیان، فایل پیکربندی اصلی Supervisor در این مسیر قرار دارد:
/etc/supervisor/supervisord.conf
فایلهای پیکربندیِ مربوط به هر برنامه معمولاً در این مسیر ذخیره میشوند:
/etc/supervisor/conf.d/
بهعنوان بهترین شیوه شناخته میشود که برای هر برنامه مدیریتشده، یک فایل .conf در این دایرکتوری بسازید.
۴. چطور در Supervisor یک پروسه را ریاستارت کنم؟
میتوانید یک برنامه مدیریتشده را با دستور supervisorctl ریاستارت کنید. برای ریاستارت یک پروسه خاص، اجرا کنید:
sudo supervisorctl restart <program_name>
مثلاً:
sudo supervisorctl restart idle
این دستور، برنامه را متوقف و سپس شروع میکند؛ بدون نیاز به ریاستارت کامل سرویس Supervisor.
۵. آیا Supervisor برنامهها را بهطور خودکار شروع میکند؟
بله؛ Supervisor میتواند برنامهها را در صورت تنظیم گزینه autostart=true در پیکربندی برنامه، بهطور خودکار شروع کند. وقتی این گزینه فعال باشد، برنامه هر بار که دیمن Supervisor شروع شود اجرا خواهد شد؛ که اگر سرویس Supervisor فعال باشد، معمولاً هنگام بوت سیستم رخ میدهد. اگر autostart روی false باشد، باید برنامه را با supervisorctl start بهصورت دستی شروع کنید.
جمعبندی
در این آموزش یاد گرفتید که چطور Supervisor را نصب و مدیریت کنید تا برنامههای طولانیمدت را بهطور قابلاتکا در حال اجرا نگه دارید. یک فایل پیکربندیِ مخصوص برنامه ساختید، تغییرات را با supervisorctl اعمال کردید و از قابلیتهای وضعیت و دنبالکردن لاگ Supervisor برای تأیید اجرای درست برنامهتان استفاده کردید.
همچنین یاد گرفتید که Supervisor در سیستمهای مدرن اوبونتو — که معمولاً توسط systemd راهاندازی و نظارت میشود — چه جایگاهی دارد و در عملیات روزمره، چه زمانی از systemctl و چه زمانی از supervisorctl استفاده کنید. در نهایت، ملاحظات عملی production را مرور کردید؛ شامل پیکربندی لاگ و چرخش آن، امنیت و دسترسیها و بهترین شیوههای رایج برای سازماندهی و بهرهبرداری از سرویسهای مدیریتشده با Supervisor.




