مجله ایرانیکاسرورآموزش سرور، هاست، وردپرس و شبکه
آموزشی

اجرای خودکار سرویس‌ها بعد از Reboot با systemd؛ آموزش کامل

اگر برنامه‌ای را روی سرور لینوکسی اجرا کرده‌اید اما بعد از Reboot دیگر بالا نمی‌آید، راه استاندارد این است که آن برنامه را به یک سرویس systemd تبدیل و برای اجرای خودکار هنگام Boot…

اجرای خودکار سرویس‌ها بعد از Reboot با systemd؛ آموزش کامل
خلاصه سریع این آموزش

اگر برنامه‌ای را روی سرور لینوکسی اجرا کرده‌اید اما بعد از Reboot دیگر بالا نمی‌آید، راه استاندارد این است که آن برنامه را به یک سرویس systemd تبدیل و برای…

۱۰ دقیقه مطالعه ۰ دیدگاه ۱۲ مهر ۱۴۰۵ آخرین به‌روزرسانی

اگر برنامه‌ای را روی سرور لینوکسی اجرا کرده‌اید اما بعد از 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

🔹 مستندات systemd.service

🔹 مستندات systemd Unit

🔹 مستندات 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

اشتراک‌گذاری مقاله
گفت‌وگو درباره آموزش

دیدگاه‌ها (۰)

هنوز دیدگاهی ثبت نشده است.

دیدگاه یا سؤال خود را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *