
مقدمه
در بسیاری از محیطهای سرور مجازی (VPS)، ممکن است تعدادی برنامه کوچک داشته باشید که میخواهید بهصورت مداوم اجرا شوند؛ چه این برنامهها اسکریپتهای کوچک شل باشند، چه اپهای Node.js یا پکیجهای بزرگتر.
معمولاً پکیجهای خارجی همراه با یک فایل یونیت عرضه میشوند که امکان مدیریت آنها را توسط یک سیستم init مانند systemd فراهم میکند؛ یا بهصورت ایمیج داکر بستهبندی میشوند که میتوان آنها را با یک موتور کانتینر مدیریت کرد. اما وقتی نرمافزار بهخوبی بستهبندی نشده باشد، یا وقتی ترجیح میدهید با یک سیستم init سطحپایین روی سرورتان درگیر نشوید، داشتن یک جایگزین سبکوزن مفید خواهد بود.
Supervisor یک مدیر پروسه (Process Manager) است که یک رابط واحد برای مدیریت و مانیتورینگ تعدادی برنامه طولانیمدت (Long-Running) فراهم میکند. در این آموزش، Supervisor را نصب میکنید و از آن برای تعریف، راهاندازی و مدیریت یک یا چند برنامه از طریق فایلهای پیکربندی ساده و مخصوص هر برنامه استفاده میکنید. همچنین یاد میگیرید که Supervisor چگونه در سیستمهای مدرن اوبونتو و دبیان جای میگیرد (که معمولاً توسط systemd مدیریت میشود) و راهنمایی عملی برای اجرای برنامههای مدیریتشده با Supervisor در محیطهای واقعی دریافت میکنید؛ از جمله لاگینگ و چرخش لاگ، امنیت و مجوزها، بهترین روشها و عیبیابی.
نکات کلیدی
- Supervisor یک مدیر پروسه سبکوزن برای نگهداشتن پایدار برنامههای طولانیمدت است؛ بهویژه وقتی نرمافزارتان بهصورت سرویس نیتیو بستهبندی نشده است.
- روی اوبونتو و دبیان مدرن، خود Supervisor معمولاً توسط systemd مدیریت میشود؛ پس از
systemctlبرای مدیریت سرویس Supervisor و ازsupervisorctlبرای مدیریت برنامههایی که Supervisor اجرا میکند استفاده میکنید. - یک روند کاری رایج برای تغییرات هر برنامه این است که فایل
.confرا در/etc/supervisor/conf.d/ویرایش کنید، سپسsudo supervisorctl rereadوsudo supervisorctl updateرا اجرا کنید تا تغییرات اعمال شوند. - برنامههای تحت نظارت Supervisor باید در پیشزمینه اجرا شوند (حالت غیر دیمنی یا Non-Daemonizing)؛ اگر به پسزمینه fork شوند، Supervisor ممکن است وضعیتشان را اشتباه بفهمد و وارد حلقههای ریاستارت شود.
- پیکربندی هر برنامه ساده و به سبک INI است و به شما اجازه میدهد دستور، رفتار autostart/autorestart و محل نوشته شدن stdout/stderr را تعریف کنید.
- راهاندازی لاگینگ مبتنی بر فایل آسان است، اما باید مطمئن شوید دایرکتوریهای لاگ از قبل وجود دارند و کاربر برنامه اجازه نوشتن در آنها را دارد.
- رشد لاگها نیاز به برنامه دارد: Supervisor چرخش پایه را با
*_logfile_maxbytesو*_logfile_backupsپشتیبانی میکند، در حالی که چرخش پیشرفتهتر و نگهداری بلندمدت معمولاً توسط ابزارهایی مانند logrotate یا سیستم لاگینگ متمرکز انجام میشود. - برای استفاده پروداکشن، روی مبانی امنیت و قابلیت اطمینان تمرکز کنید: برنامهها را با کاربر غیر root اجرا کنید، از مسیرهای مطلق و دایرکتوری کاری صریح استفاده کنید و خطاها را با لاگهای برنامه بههمراه systemctl/journalctl (وقتی خود سرویس Supervisor مشکل دارد) عیبیابی کنید.
پیشنیازها
برای تکمیل این راهنما به این موارد نیاز دارید:
- یک سرور اوبونتو 24.04 LTS و یک کاربر غیر root با دسترسی sudo. میتوانید درباره نحوه راهاندازی کاربر با این دسترسیها بیشتر در راهنمای راهاندازی اولیه سرور با اوبونتو در پارمین کلود یاد بگیرید.
گام ۱ — نصب
با بهروزرسانی منابع پکیج و نصب Supervisor شروع کنید:
sudo apt update && sudo apt install supervisor
سرویس Supervisor بعد از نصب بهطور خودکار اجرا میشود. میتوانید وضعیتش را بررسی کنید:
sudo systemctl status supervisor
باید این خروجی را دریافت کنید:
Output
● 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 اجرا میشوند باید در حالت غیر دیمنی (گاهی «حالت پیشزمینه» هم نامیده میشود) اجرا شوند. اگر برنامهتان بعد از شروع، خودکار به شل برمیگردد، مستندات برنامه را ببینید تا گزینه نگهداشتن آن در پیشزمینه را پیدا کنید؛ وگرنه 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 و مسیر کامل برنامه شروع میشود. بهجای <your_user> نام کاربری خودتان را قرار دهید.
دو خط بعدی، رفتار خودکار اسکریپت را در شرایط خاص تعریف میکنند.
autostart=true
autorestart=true
گزینه autostart به Supervisor میگوید که برنامه را وقتی سرویس supervisord راهاندازی میشود (معمولاً هنگام بوت سیستم) شروع کند. تنظیم این گزینه روی false یعنی بعد از هر خاموشی سیستم، شروع دستی لازم است.
autorestart تعیین میکند Supervisor در صورت خروج برنامه چگونه آن را مدیریت کند:
falseبه Supervisor میگوید بعد از خروج برنامه، هرگز آن را ریاستارت نکند.trueبه Supervisor میگوید بعد از خروج برنامه، همیشه آن را ریاستارت کند.unexpectedبه Supervisor میگوید فقط وقتی برنامه با کد خروج غیرمنتظره خارج شود آن را ریاستارت کند (بهطور پیشفرض هر چیزی بهجز کدهای 0 یا 2). برای اطلاعات بیشتر درباره کدهای خروج، به مستندات برنامهتان یا مستندات وضعیت خروج لینوکس مراجعه کنید.
دو خط آخر، مکانهای دو فایل لاگ اصلی برنامه را تعریف میکنند.
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
Output
idle: available
سپس به آن میگوییم تغییرات را اعمال کند:
sudo supervisorctl update
Output
idle: added process group
هر بار که در هر فایل پیکربندی برنامهای تغییری میدهید، اجرای این دو دستور قبلی، تغییرات را اعمال میکند.
در این نقطه، برنامه ما باید در حال اجرا باشد. میتوانیم خروجیاش را با نگاه کردن به فایل لاگ خروجی بررسی کنیم:
sudo tail /var/log/idle.out.log
Output
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
Output
idle RUNNING pid 12614, uptime 1:49:37
supervisor>
supervisorctl ابتدا وضعیت و مدت فعالیت همه برنامههای پیکربندیشده را چاپ میکند و بعد پرامپت فرمانش را نشان میدهد. با وارد کردن help همه دستورات موجودش نمایش داده میشود:
help
Output
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
Output
idle: stopped
start idle
Output
idle: started
با دستور tail، میتوانید جدیدترین ورودیهای لاگهای stdout و stderr برنامهتان را ببینید:
tail idle
Output
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
Output
error!
error!
error!
error!
error!
error!
error!
با status میتوانید بعد از هر تغییری، وضعیت اجرای فعلی هر برنامه را دوباره ببینید:
status
Output
idle RUNNING pid 3745, uptime 0:00:43
در نهایت، میتوانید با Ctrl+C یا با وارد کردن quit در پرامپت، از supervisorctl خارج شوید:
quit
پیکربندی و چرخش لاگ
Supervisor میتواند جریانهای خروجی استاندارد (stdout) و خطای استاندارد (stderr) یک برنامه را در فایلهای لاگ اختصاصی بنویسد (مثلاً با تنظیم stdout_logfile و stderr_logfile در تعریف برنامه). این اغلب سادهترین راه برای ثبت لاگ اسکریپتها و سرویسهای کوچک است؛ چون میتوانید خروجی هر برنامه را در مکانهای قابل پیشبینی روی دیسک نگه دارید.
وقتی لاگینگ مبتنی بر فایل را پیکربندی میکنید، به دو نکته عملی توجه کنید. اول، دایرکتوریهایی که ارجاع میدهید باید از قبل وجود داشته باشند؛ چون Supervisor دایرکتوریهای مفقود را برایتان نمیسازد. دوم، برنامه باید اجازه نوشتن در مکانهای لاگی که مشخص میکنید را داشته باشد. مثلاً اگر لاگها را زیر /var/log/ مینویسید، ممکن است لازم باشد یک زیردایرکتوری اختصاصی بسازید و مطمئن شوید مالکش همان کاربری است که برنامه را اجرا میکند.
برای سرویسهای طولانیمدت هم مهم است که برنامهریزی کنید این لاگها چگونه بچرخند تا بدون محدودیت رشد نکنند و دیسکتان را پر نکنند.
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 را به نوشتن در یک مکان پایدار نگه دارید که ایجنت لاگینگ یا سیاست چرخشتان از قبل مانیتورش میکند.
ملاحظات امنیتی و مجوزها
Supervisor اغلب برای نگهداشتن پروسههای اپلیکیشن در حال اجرا استفاده میشود؛ یعنی بهراحتی ممکن است ناخواسته به آن پروسهها دسترسی بیش از نیاز بدهید. قبل از دیپلوی برنامههای مدیریتشده با Supervisor در پروداکشن، ارزشش را دارد که چند ملاحظه عملی امنیتی و مجوز را مرور کنید.
اول، برنامههایتان را با حداقل دسترسی ممکن اجرا کنید. اگر برنامهتان به دسترسیهای root نیاز ندارد، آن را طوری پیکربندی کنید که با کاربر غیرممتاز اجرا شود؛ با افزودن تنظیم user (و در صورت تمایل group) به تعریف برنامه. برای اپلیکیشنها، معمولاً ارزشش را دارد که یک کاربر سرویس اختصاصی بسازید (مثلاً بدون شل تعاملی) تا ناخواسته پروسههای پروداکشن را با حساب ورود شخصی اجرا نکنید.
[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
دوم، مطمئن شوید برنامهتان فقط فایلهایی را که نیاز دارد میتواند بخواند و بنویسد. در عمل، این معمولاً یعنی اطمینان از اینکه دایرکتوری اپلیکیشن، هر محیط مجازی (Virtual Environment) و هر دایرکتوری لاگ، مالکیت کاربر درست را دارند و مجوزهای مناسب دارند. اگر برنامهتان در فایلهای لاگ مینویسد (مثلاً زیر /var/log/)، مطمئن شوید دایرکتوری وجود دارد و برای کاربر برنامه قابل نوشتن است؛ وگرنه ممکن است برنامه شروع نشود یا بیصدا لاگهایش را از دست بدهد.
سوم، با فایلهای پیکربندی Supervisor مانند پیکربندی عملیاتی حساس رفتار کنید. آنها را در مکانهای دارای مالکیت root مانند /etc/supervisor/conf.d/ ذخیره کنید، مجوزها را محدود نگه دارید و هنگام ویرایش از sudo استفاده کنید. درباره اسرار هم محتاط باشید: پیکربندیهای Supervisor اغلب شامل آرگومانهای خط فرمان یا متغیرهای محیطی هستند (مثلاً URLهای دیتابیس، کلیدهای API و اعتبارنامهها)؛ پس از قابل خواندن بودن این فایلها برای غیرمدیران بپرهیزید.
در نهایت، درباره افشای رابطهای کنترل Supervisor محتاط باشید. Supervisor را میتوان با endpointهای کنترل HTTP پیکربندی کرد، اما باید از bind کردن هر رابط کنترلی به اینترنت عمومی بپرهیزید؛ چون به مهاجم اجازه میدهد پروسهها را شروع و متوقف کند یا اطلاعات عملیاتی بخواند. اگر به دلایل عملیاتی قابلیتهای کنترل ریموت را فعال میکنید، آنها را به 127.0.0.1 یا یک شبکه مدیریت خصوصی bind کنید، احراز هویت را الزامی کنید و اینکه کدام کاربران میتوانند به سوکت یا 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 و ریاستارت برای هر برنامه، با گروهبندی ساده و گزارش وضعیت |
| لاگینگ و دیدهبانی | بهطور پیشفرض با ژورنال سیستم یکپارچه است؛ journalctl برای کوئری | معمولاً stdout/stderr را در فایلهای هر برنامه مینویسد؛ شامل tail و تنظیمات چرخش پایه در supervisorctl |
| ایزولهسازی و محدودیتها | کنترلهای منابع مبتنی بر cgroups، گزینههای sandboxing و قابلیتهای هاردنینگ سطح سرویس | روی کنترل پروسه تمرکز دارد؛ ایزولهسازی و هاردنینگ معمولاً توسط سیستمعامل و مجوزهای فایل انجام میشود |
| روند کاری معمول | systemctl start|stop|restart، systemctl status، journalctl -u <unit> | supervisorctl start|stop|status، supervisorctl reread|update، supervisorctl tail |
اگر یک سرویس خوب بستهبندیشده را مدیریت میکنید، یونیت نیتیو systemd معمولاً سادهترین و استانداردترین رویکرد است. همچنین وقتی به وابستگیهای سرویس، ترتیب سختگیرانه، هاردنینگ سطح سیستمعامل یا یکپارچگی تنگاتنگ با ابزارهای توزیع نیاز دارید، معمولاً انتخاب بهتری است.
اگر چند برنامه کوچک را مدیریت میکنید و یک رابط پیکربندی و کنترل یکپارچه میخواهید، Supervisor میتواند جایگزین عملی باشد. این بهویژه درست است وقتی نیاز دارید چندین پروسه اپلیکیشن را که بهصورت سرویس بستهبندی نشدهاند نظارت کنید، یا وقتی یک ابزار واحد (supervisorctl) را برای start/stop/status و دنبال کردن لاگهای همه برنامههایتان ترجیح میدهید.
بهترین روشهای استفاده از Supervisor
وقتی با تدبیر پیکربندی شود، Supervisor میتواند مدیریت پروسه قابل اطمینان و قابل پیشبینی برای بارهای کاری اپلیکیشن فراهم کند. اما بسیاری از مشکلات پروداکشن از غفلتهای کوچک پیکربندی ناشی میشوند. بهترین روشهای زیر به شما کمک میکنند یک استقرار Supervisor امنتر، قابل نگهداریتر و مقاومتر بسازید.
برنامهها را با کاربر غیر root اجرا کنید
بهطور پیشفرض، برنامههای مدیریتشده توسط Supervisor با همان دسترسیهای سرویس supervisord اجرا میشوند که معمولاً بهعنوان کاربر root اجرا میشود. اجرای پروسههای اپلیکیشن با root بهندرت ضروری است و تأثیر بالقوه یک آسیبپذیری امنیتی یا باگ اپلیکیشن را افزایش میدهد.
در بیشتر موارد، باید برای هر اپلیکیشن یک کاربر اختصاصی با حداقل دسترسی بسازید و از آن استفاده کنید. این را میتوانید با افزودن دایرکتیو user در پیکربندی برنامهتان الزامی کنید:
[program:myapp]
command=/usr/local/bin/myapp
user=myappuser
autostart=true
autorestart=true
اجرای پروسهها با حداقل دسترسی، ریسک را بهطور چشمگیری کاهش میدهد و با روشهای استاندارد امنیتی لینوکس همراستاست.
از مسیرهای مطلق بهطور پیوسته استفاده کنید
Supervisor برنامهها را داخل یک محیط شل تعاملی کامل راهاندازی نمیکند. در نتیجه، متغیرهای محیطی مانند $PATH ممکن است آنطور که انتظار دارید رفتار نکنند. مسیرهای نسبی یا resolve شدن ضمنی دستورات میتوانند منجر به خطاهای ظریف و عیبیابیسخت شوند.
برای اجتناب از این مشکلات، همیشه از مسیرهای مطلق استفاده کنید برای:
- دستورات اجرایی
- آرگومانهای اسکریپت
- دایرکتوریهای کاری
- مکانهای فایل لاگ
مثلاً:
command=/usr/bin/python3 /opt/myapp/app.py
directory=/opt/myapp
stdout_logfile=/var/log/supervisor/myapp.out.log
استفاده از مسیرهای صریح، رفتار یکپارچه را بین ریبوتها، محیطها و روندهای خودکارسازی تضمین میکند.
مطمئن شوید برنامهها در پیشزمینه اجرا میشوند
Supervisor برای مدیریت پروسههای طولانیمدتِ پیشزمینه طراحی شده. اگر برنامهای خودش را دیمنیزه کند (به پسزمینه fork شود)، Supervisor ممکن است این را به اشتباه خروج برنامه تفسیر کند و مکرراً تلاش به ریاستارتش کند.
قبل از افزودن هر اپلیکیشنی به Supervisor، تأیید کنید که در پیشزمینه اجرا میشود. بسیاری از اپلیکیشنهای سروری فلگهایی برای غیرفعال کردن حالت دیمن ارائه میدهند. وقتی شک دارید، مستندات اپلیکیشن را ببینید و رفتار پسزمینه را صریحاً غیرفعال کنید.
بهعنوان قاعده کلی، اگر برنامهای بعد از شروع بلافاصله کنترل را به شل برمیگرداند، احتمالاً دیمنیزه میشود و باید پیکربندیاش اصلاح شود.
ریاستارتهای خودکار را باتدبیر پیکربندی کنید
تنظیم autorestart قدرتمند است اما باید با احتیاط استفاده شود. در حالی که ریاستارت خودکار پروسههای خراب، دسترسپذیری را بهبود میدهد، یک سیاست ریاستارت بیشازحد تهاجمی میتواند مشکلات زیرین را پوشش دهد یا حلقههای کرش سریعی بسازد که منابع سیستم را مصرف میکنند.
برای بیشتر بارهای کاری پروداکشن، یک پیکربندی متعادل توصیه میشود:
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 روی یک سیستم پروداکشن بدون محدودیت رشد کنند.
پیکربندیها را قبل از اعمال تغییرات اعتبارسنجی کنید
یک خطای سینتکس کوچک در فایل پیکربندی Supervisor میتواند مانع از شروع درست یک برنامه شود. برای اجتناب از قطعی غیرمنتظره، همیشه باید پیکربندیها را بهشکل کنترلشده اعتبارسنجی و ریلود کنید.
بعد از تغییر هر فایل برنامه، این را اجرا کنید:
sudo supervisorctl reread
sudo supervisorctl update
سپس وضعیت برنامه را تأیید کنید:
sudo supervisorctl status
این روند کاری به شما کمک میکند مشکلات پیکربندی را زود تشخیص دهید و مطمئن شوید تغییرات بهشکل امن اعمال میشوند.
مقدار startsecs را برای اپلیکیشنهای کندشروع تنظیم کنید
برخی اپلیکیشنها قبل از اینکه کاملاً عملیاتی شوند به زمان اضافی برای مقداردهی اولیه نیاز دارند. اگر Supervisor پروسه را خیلی سریع بررسی کند، ممکن است به اشتباه برنامه را ناموفق علامت بزند و ریاستارتهای غیرضروری انجام دهد.
اگر اپلیکیشن شما زمان راهاندازی محسوسی دارد، مقدار startsecs را افزایش دهید:
startsecs=10
این مقدار را کمی بالاتر از مدت راهاندازی معمول اپلیکیشنتان تنظیم کنید. تنظیم درست از تشخیص کاذبِ خرابی جلوگیری میکند.
از Supervisor برای بارهای کاری درست استفاده کنید
هرچند Supervisor بسیار توانمند است، برای جایگزینی سیستم init سیستم در سرویسهای اصلی سیستمعامل طراحی نشده است. توزیعهای مدرن لینوکس برای ارکستراسیون سطحپایین سرویسها، مدیریت وابستگیها و توالی بوت به systemd متکیاند.
بهطور کلی، systemd را برای این موارد ترجیح دهید:
- دیتابیسها
- سرویسهای شبکه
- دیمنهای سیستم
- زیرساختهای حیاتی بوت
Supervisor برای این موارد مناسبتر است:
- workerهای اپلیکیشن
- مصرفکنندگان صف (Queue Consumers)
- کارهای پسزمینه
- استکهای اپلیکیشن چندپروسهای
استفاده از هر ابزار برای هدف موردنظرش، معماری تمیزتر و قابل نگهداریتری نتیجه میدهد.
خود سرویس Supervisor را مانیتور کنید
در نهایت، یادتان باشد که خود Supervisor هم یک سرویس حیاتی است. اگر دیمن Supervisor متوقف شود، هیچکدام از برنامههای مدیریتشدهتان ریاستارت یا مانیتور نخواهند شد.
در محیطهای پروداکشن باید:
- مطمئن شوید سرویس 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 انتظار دارد برنامههای مدیریتشده در پیشزمینه در حال اجرا بمانند؛ پس خروجهای سریع بهعنوان خرابی تلقی میشوند.
علل رایج شامل مسیر دستور نادرست، مجوزهای اجرای مفقود، دیمنیزه شدن خود برنامه، وابستگیهای زمان اجرای مفقود یا مجوزهای فایل ناکافی است.
عیبیابی را با اجرای دستی دستور بهعنوان همان کاربرِ مشخصشده در پیکربندی Supervisor شروع کنید:
sudo -u <your_user> /full/path/to/program
اگر برنامه هنگام شروع دستی در پیشزمینه نمیماند، 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 مکرراً تلاش میکند یک سرویس شبکهای را که به پورتی bind میشود شروع کند، سرویس ممکن است به این دلیل شکست بخورد که پورت از قبل در حال استفاده است.
میتوانید بررسی کنید کدام پروسه در حال حاضر روی پورتی در حال شنود است:
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 استفاده کنید. در نهایت، ملاحظات عملی پروداکشن را مرور کردید؛ شامل پیکربندی و چرخش لاگ، امنیت و مجوزها، و بهترین روشهای رایج برای سازماندهی و بهرهبرداری از سرویسهای مدیریتشده با Supervisor.




