اگر برنامهای را روی سرور لینوکسی اجرا کردهاید اما بعد از Reboot دیگر بالا نمیآید، راه استاندارد این است که آن برنامه را به یک سرویس systemd تبدیل و برای اجرای خودکار هنگام Boot فعال کنید. با این روش میتوانید مشخص کنید برنامه با چه کاربری اجرا شود، بعد از خرابی دوباره بالا بیاید، به چه سرویسهایی وابسته باشد و Logهای آن را از طریق journalctl مشاهده کنید.
پاسخ سریع: اگر سرویس از قبل Unit File دارد، معمولاً کافی است فرمان sudo systemctl enable –now SERVICE_NAME را اجرا کنید. اگر برنامه شخصی، اسکریپت Python، Node.js، Bot یا Binary اختصاصی دارید، ابتدا برای آن یک فایل .service در /etc/systemd/system/ بسازید، سپس daemon-reload، enable و start را انجام دهید.
systemd چیست و چرا برای اجرای خودکار سرویس مناسب است؟
systemd مدیر سرویس و فرایند Boot در بسیاری از توزیعهای امروزی لینوکس مانند Ubuntu، Debian، AlmaLinux و Rocky Linux است. بهجای اینکه برنامه را با یک دستور دستی در SSH اجرا کنید، میتوانید نحوه اجرای آن را در یک Unit File تعریف کنید.
systemd میتواند کارهای زیر را برای شما انجام دهد:
🔹 اجرای برنامه بهصورت خودکار بعد از روشنشدن یا Reboot سرور.
🔹 Restart خودکار برنامه در صورت Crash.
🔹 اجرای سرویس با یک User محدود بهجای root.
🔹 تعیین وابستگی به شبکه یا سرویسهای دیگر.
🔹 ثبت Log در journal سیستم.
🔹 Start، Stop، Restart و بررسی وضعیت با یک روش یکسان.
تفاوت systemctl start و systemctl enable چیست؟
این دو فرمان شبیه به هم به نظر میرسند اما کاربردشان متفاوت است.
| فرمان | کاربرد |
|---|---|
| systemctl start | سرویس را همین حالا اجرا میکند. |
| systemctl enable | سرویس را برای اجرای خودکار هنگام Boot فعال میکند. |
| systemctl enable –now | هم Auto-start را فعال میکند و هم سرویس را همین حالا اجرا میکند. |
| systemctl disable | اجرای خودکار هنگام Boot را غیرفعال میکند. |
| systemctl stop | سرویس در حال اجرا را متوقف میکند. |
حالت اول: سرویس از قبل systemd دارد
برای سرویسهایی مانند Nginx، Docker، PostgreSQL، Redis و بسیاری از برنامههایی که از Package Manager نصب میشوند، معمولاً Unit File از قبل ساخته شده است.
برای مثال وضعیت Nginx را بررسی کنید:
systemctl status nginx
اگر سرویس وجود دارد، Auto-start آن را بررسی کنید:
systemctl is-enabled nginx
اگر خروجی disabled بود:
sudo systemctl enable nginx
اگر میخواهید همان لحظه نیز اجرا شود:
sudo systemctl enable --now nginx
حالت دوم: ساخت سرویس systemd برای برنامه شخصی
فرض کنیم یک برنامه شخصی در مسیر زیر داریم:
/opt/myapp/app.sh
هدف این است که برنامه بعد از Reboot بهصورت خودکار اجرا شود و اگر بهدلیل خطا متوقف شد، systemd آن را دوباره راهاندازی کند.
مرحله ۱: مطمئن شوید برنامه دستی اجرا میشود
قبل از ساخت systemd Service، خود برنامه را دستی آزمایش کنید:
/opt/myapp/app.sh
اگر اسکریپت مستقیماً Executable نیست:
sudo chmod +x /opt/myapp/app.sh
مرحله ۲: فایل Service بسازید
فایل زیر را ایجاد کنید:
sudo nano /etc/systemd/system/myapp.service
محتوای پایه:
[Unit]
Description=My Application Service
After=network.target
[Service]
Type=simple
User=myapp
WorkingDirectory=/opt/myapp
ExecStart=/opt/myapp/app.sh
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
در این مثال باید User واقعی myapp روی سیستم وجود داشته باشد و به فایلهای برنامه دسترسی داشته باشد.
⚠️ برنامه را فقط به این دلیل که با Permission مشکل دارد با User=root اجرا نکنید. تا جای ممکن یک User محدود مخصوص همان سرویس ایجاد کنید و فقط دسترسیهای لازم را به آن بدهید.
هر بخش Unit File چه کاری انجام میدهد؟
بخش [Unit]
Description یک توضیح خوانا برای سرویس است.
After=network.target ترتیب اجرای سرویس را نسبت به Network Stack مشخص میکند؛ اما تضمین نمیکند اینترنت یا IP قابل استفاده آماده شده باشد.
بخش [Service]
Type=simple برای بسیاری از برنامههایی که در Foreground اجرا میشوند مناسب است.
User=myapp مشخص میکند برنامه با چه User لینوکسی اجرا شود.
WorkingDirectory=/opt/myapp پوشه کاری برنامه را مشخص میکند.
ExecStart دستور اصلی اجرای برنامه است.
Restart=on-failure باعث میشود اگر سرویس بهدلیل خطا از کار افتاد، systemd برای اجرای مجدد آن اقدام کند.
RestartSec=5 بین Fail شدن و Restart بعدی پنج ثانیه فاصله قرار میدهد.
بخش [Install]
این خط:
WantedBy=multi-user.target
مشخص میکند وقتی سرویس Enable میشود، در Boot عادی سیستم به multi-user.target متصل شود.
مرحله ۳: systemd را از فایل جدید مطلع کنید
بعد از ایجاد یا تغییر Unit File:
sudo systemctl daemon-reload
این فرمان باعث میشود systemd تعریف Unitهای روی دیسک را دوباره بارگذاری کند.
مرحله ۴: سرویس را قبل از Enable تست کنید
sudo systemctl start myapp.service
وضعیت:
systemctl status myapp.service --no-pager
اگر وضعیت active (running) است، مرحله بعد را انجام دهید.
مرحله ۵: اجرای خودکار بعد از Reboot را فعال کنید
sudo systemctl enable myapp.service
بررسی کنید:
systemctl is-enabled myapp.service
خروجی معمول:
enabled
یک روش کوتاهتر: enable –now
اگر Unit File درست است، میتوانید Start و Enable را همزمان انجام دهید:
sudo systemctl enable --now myapp.service
سرویس دائمی روی VPS اجرا میکنید؟
برای Bot، API، وبسرویس، برنامه Python یا Node.js که باید ۲۴ ساعته فعال باشد، استفاده از systemd همراه با یک VPS لینوکسی امکان مدیریت Start، Restart، Boot و Log سرویس را در سطح سیستمعامل فراهم میکند.
اگر برنامه واقعاً به اینترنت نیاز دارد چه کنیم؟
یکی از خطاهای رایج این است که سرویس بعد از Boot اجرا میشود، اما چون شبکه هنوز کاملاً آماده نیست، برنامه در اولین اتصال API، دیتابیس خارجی، Telegram، DNS یا سرویس Remote خطا میدهد.
این تنظیم:
After=network.target
به معنی «اینترنت کاملاً آماده است» نیست.
اگر برنامه واقعاً بدون شبکه قابل استفاده نیست، میتوانید Unit را به این شکل تنظیم کنید:
[Unit]
Description=My Network Application
Wants=network-online.target
After=network-online.target
اما network-online.target را بیدلیل برای هر سرویس اضافه نکنید؛ انتظار برای Online شدن شبکه میتواند Boot را طولانیتر کند.
Ubuntu با NetworkManager
اگر شبکه سیستم با NetworkManager مدیریت میشود و واقعاً به انتظار برای شبکه نیاز دارید، وضعیت سرویس زیر را بررسی کنید:
systemctl status NetworkManager-wait-online.service
نمونه systemd برای برنامه Python
فرض کنیم پروژه Python در این مسیر قرار دارد:
/opt/mybot/app.py
و Virtual Environment در:
/opt/mybot/venv
Unit File:
[Unit]
Description=Python Bot Service
Wants=network-online.target
After=network-online.target
[Service]
Type=simple
User=mybot
WorkingDirectory=/opt/mybot
ExecStart=/opt/mybot/venv/bin/python /opt/mybot/app.py
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
در این روش لازم نیست ابتدا source venv/bin/activate اجرا شود؛ مسیر مستقیم Python داخل Virtual Environment در ExecStart قرار گرفته است.
نمونه systemd برای Node.js
فرض کنیم Node.js در مسیر /usr/bin/node و برنامه در /opt/nodeapp/server.js قرار دارد:
[Unit]
Description=Node.js Application
After=network.target
[Service]
Type=simple
User=nodeapp
WorkingDirectory=/opt/nodeapp
ExecStart=/usr/bin/node /opt/nodeapp/server.js
Restart=on-failure
RestartSec=5
Environment=NODE_ENV=production
[Install]
WantedBy=multi-user.target
Environment Variable را کجا قرار دهیم؟
برای متغیرهای ساده میتوانید از Environment= استفاده کنید:
Environment=APP_ENV=production
Environment=PORT=8080
اگر متغیرها زیاد هستند، فایل جداگانه خواناتر است:
EnvironmentFile=/etc/myapp/myapp.env
⚠️ اگر فایل Environment شامل Password، API Key یا Token است، Permission آن را محدود کنید و اطلاعات محرمانه را داخل Unit File عمومی یا Repository قرار ندهید.
Restart=always یا Restart=on-failure؟
برای بسیاری از سرویسهای دائمی، Restart=on-failure انتخاب مناسبتری است؛ چون اگر برنامه با خطا، Signal غیرعادی یا Failure متوقف شود، systemd آن را دوباره اجرا میکند.
Restart=always تقریباً بعد از هر نوع خروج برنامه باعث Restart میشود، حتی در شرایطی که خروج عادی بوده است.
| تنظیم | رفتار |
|---|---|
| Restart=no | Restart خودکار انجام نمیشود. |
| Restart=on-failure | در Failure سرویس را دوباره اجرا میکند. |
| Restart=always | در بیشتر حالتهای خروج دوباره سرویس را اجرا میکند. |
مشاهده Log سرویس با journalctl
یکی از مزیتهای مهم systemd این است که برای بسیاری از برنامهها نیازی به ساخت Log File جداگانه ندارید.
مشاهده Log سرویس:
journalctl -u myapp.service
دنبالکردن Log بهصورت زنده:
journalctl -u myapp.service -f
Logهای مربوط به Boot فعلی:
journalctl -u myapp.service -b
قبل از Reboot بدون ریسک چه چیزهایی را بررسی کنیم؟
قبل از اینکه برای آزمایش سرور را Reboot کنید، این موارد را بررسی کنید:
systemctl is-enabled myapp.service
systemctl is-active myapp.service
systemctl status myapp.service --no-pager
همچنین Unit File را میتوانید با این ابزار بررسی کنید:
systemd-analyze verify /etc/systemd/system/myapp.service
اگر خطایی نمایش داده شد، قبل از Reboot آن را اصلاح کنید.
تست واقعی بعد از Reboot
⚠️ روی سرور Production فقط در زمانی Reboot کنید که از دسترسی SSH، تنظیمات شبکه، سرویسهای حیاتی و مسیر بازیابی اطمینان دارید. برای تست systemd در بسیاری از موارد ابتدا Start/Stop دستی کافی است.
در صورت آمادهبودن سرور:
sudo reboot
بعد از بالا آمدن سرور دوباره متصل شوید و اجرا کنید:
systemctl status myapp.service --no-pager
اگر سرویس اجرا نشده است، Log همان Boot را ببینید:
journalctl -u myapp.service -b --no-pager
خطای status=203/EXEC بعد از ساخت systemd Service
یکی از خطاهای متداول:
status=203/EXEC
معمولاً باید موارد زیر را بررسی کنید:
🔹 مسیر ExecStart اشتباه نباشد.
🔹 فایل واقعاً وجود داشته باشد.
🔹 User سرویس Permission لازم داشته باشد.
🔹 اسکریپت Executable باشد.
🔹 Interpreter صحیح در Shebang یا ExecStart مشخص شده باشد.
مسیر را بررسی کنید:
ls -l /opt/myapp/app.sh
سرویس دستی اجرا میشود ولی بعد از Reboot نه؛ علت چیست؟
این وضعیت معمولاً یکی از علتهای زیر را دارد:
🔹 سرویس Start شده ولی Enable نشده است.
🔹 برنامه قبل از آمادهشدن شبکه اجرا میشود.
🔹 مسیرهای نسبی داخل برنامه استفاده شدهاند.
🔹 Environment Variableهایی که در Shell وجود داشتند داخل systemd وجود ندارند.
🔹 User سرویس دسترسی لازم را ندارد.
🔹 برنامه به فایل یا Mount دیگری وابسته است که هنوز آماده نشده است.
اول این سه فرمان را اجرا کنید:
systemctl is-enabled myapp.service
systemctl status myapp.service --no-pager
journalctl -u myapp.service -b --no-pager
بعد از تغییر Unit File چه کنیم؟
هر بار که فایل myapp.service را تغییر میدهید، ابتدا:
sudo systemctl daemon-reload
سپس سرویس را Restart کنید:
sudo systemctl restart myapp.service
آیا rc.local هنوز روش مناسبی است؟
systemd همچنان برای سازگاری میتواند rc.local را در برخی سیستمها اجرا کند، اما مستندات systemd توصیه میکنند برای سرویسهای جدید بهجای آن Unit File واقعی systemd ساخته شود.
Unit File کنترل بیشتری روی Dependency، Restart، User، Logging و ترتیب Boot به شما میدهد و عیبیابی آن نیز سادهتر است.
دستورهای پرکاربرد systemd
| کار | فرمان |
|---|---|
| اجرای سرویس | systemctl start myapp |
| توقف سرویس | systemctl stop myapp |
| Restart | systemctl restart myapp |
| فعالسازی در Boot | systemctl enable myapp |
| غیرفعالسازی در Boot | systemctl disable myapp |
| وضعیت | systemctl status myapp |
| Log | journalctl -u myapp |
پرسشهای متداول
چطور یک سرویس را بعد از Reboot خودکار اجرا کنیم؟
اگر Unit File سرویس وجود دارد، معمولاً اجرای sudo systemctl enable SERVICE_NAME کافی است. برای Start همزمان میتوانید از enable –now استفاده کنید.
چرا systemctl start کار میکند ولی بعد از Reboot سرویس اجرا نمیشود؟
احتمالاً سرویس را Start کردهاید اما Enable نشده است. با systemctl is-enabled SERVICE_NAME وضعیت آن را بررسی کنید.
فرق network.target با network-online.target چیست؟
network.target فقط ترتیب کلی Network Stack را مشخص میکند و تضمین نمیکند اتصال قابل استفاده آماده باشد. network-online.target برای سرویسهایی است که واقعاً باید منتظر Online شدن شبکه بمانند.
چطور سرویس بعد از Crash دوباره اجرا شود؟
در بخش [Service] معمولاً میتوانید از Restart=on-failure همراه با RestartSec استفاده کنید.
آیا بعد از تغییر فایل Service باید سرور Reboot شود؟
خیر. معمولاً کافی است systemctl daemon-reload و سپس systemctl restart SERVICE_NAME اجرا شود.
Log برنامه systemd کجاست؟
در بسیاری از سرویسها خروجی Standard Output و Standard Error توسط Journal جمعآوری میشود و با journalctl -u SERVICE_NAME قابل مشاهده است.
بهتر است برنامه را با root اجرا کنیم؟
تا جای ممکن خیر. برای سرویس اختصاصی بهتر است User محدودی بسازید و فقط دسترسیهای موردنیاز برنامه را در اختیار آن قرار دهید.
منابع
🔹 مستندات systemctl در systemd
🔹 مستندات NetworkManager Wait Online
جمعبندی
برای اینکه برنامه یا سرویس بعد از Reboot سرور بهصورت خودکار اجرا شود، آن را با systemd مدیریت کنید. برای سرویسهای آماده معمولاً systemctl enable –now کافی است. برای برنامه شخصی یک Unit File با ExecStart، User مناسب، Restart=on-failure و WantedBy=multi-user.target بسازید. بعد از هر تغییر daemon-reload اجرا کنید و پیش از Reboot، Status و Log سرویس را بررسی کنید.
سرویس بعد از Reboot اجرا نمیشود؟
اگر برنامه فقط در SSH اجرا میشود اما systemd آن را بعد از Boot بالا نمیآورد، میتوانید برای بررسی Unit File، Permission، Environment، وابستگی شبکه و Logهای Boot درخواست فنی ثبت کنید.
تماس با پشتیبانی ایرانیکاسرور: 021-91302467






دیدگاهها (۰)