SSD Nodes Learn Hosting plans →
নির্দেশিকা Matt Connorদ্বারা Matt Connor · আপডেট করা হয়েছে 2026-08-26

VPS-এ program-কে systemd service হিসেবে চালানোর নিয়ম

systemd service দিয়ে boot-এর সময় program চালু রাখুন, crash হলে restart করুন এবং journal-এ log দেখুন। unit file, timer ও নিরাপদে কম privilege ব্যবহারের নিয়ম জানুন।

systemd service কী এবং কেন এটি ব্যবহার করবেন

একটি systemd service হলো একটি ছোট text file, যা server-কে একটি program কীভাবে চালাতে হবে তা জানায়: boot-এর সময় এটি start করা, crash করলে restart করা এবং এর output system log-এ পাঠানো। এটাই এর সম্পূর্ণ কাজ। SSH session-এ হাতে start করা কোনো program আপনি logout করা বা server reboot হওয়ার সঙ্গে সঙ্গে বন্ধ হয়ে যায়। systemd service-এর মাধ্যমে চালানো program চলতে থাকে, কারণ আপনার shell-এর বদলে server নিজেই সেটির দায়িত্ব নেয়।

Ubuntu, Debian, Fedora এবং অধিকাংশ আধুনিক Linux server-এ systemd হলো init system। এটিই প্রথম start হওয়া process এবং অন্য সবকিছুর supervision করে। সবসময় এমন ছিল না, এবং একটি unit file কী করে তা জানার পরে systemd কীভাবে আগের init script-গুলোর স্থলাভিষিক্ত হয়েছিল একবার পড়ে নেওয়া উপকারী। আপনি যখন একটি service file লেখেন, তখন program-টির দায়িত্ব ওই supervisor-এর কাছে দেন। এই guide-এ সবচেয়ে ছোট কার্যকর unit, প্রতিটি unit-এ থাকা তিনটি section, এটি কীভাবে চালু করবেন ও এর log পড়বেন, timer ব্যবহার করে schedule অনুযায়ী কীভাবে চালাবেন এবং যতটা সম্ভব কম privilege-এ চালানোর জন্য কীভাবে এটি নিরাপদ করবেন—এসব দেখানো হয়েছে।

কাজ করে এমন সবচেয়ে ছোট service

একটি service file থাকে /etc/systemd/system/-এ, এর শেষে .service থাকে, এবং এতে মাত্র কয়েকটি লাইন প্রয়োজন। /usr/local/bin/myapp-এ থাকা একটি program-এর জন্য একটি file তৈরি করুন:

sudo nano /etc/systemd/system/myapp.service
[Unit]
Description=My application

[Service]
ExecStart=/usr/local/bin/myapp

[Install]
WantedBy=multi-user.target

এটি সম্পূর্ণ ও কার্যকর একটি unit। ExecStart হলো চালানোর command। WantedBy=multi-user.target-এর অর্থ হলো server স্বাভাবিক multi-user operation-এ পৌঁছালে এটি চালু করা। এ কারণেই এটি boot-এর সময় চালু হয়। বাকি সবকিছু অতিরিক্ত পরিমার্জন।

তিনটি section এবং প্রতিটির কাজ

প্রতিটি unit file square bracket-এর মধ্যে লেখা section-এ বিভক্ত। একটি service-এ তিনটি section থাকে।

[Unit] service এবং এর সম্পর্ক বর্ণনা করে। আপনি যে দুটি line সবচেয়ে বেশি ব্যবহার করবেন:

[Unit]
Description=My application
After=network-online.target
Wants=network-online.target

Description হলো systemctl status-এ দেখা human label। After=network-online.target systemd-কে network চালু না হওয়া পর্যন্ত আপনার program start না করতে বলে। যেসব program port bind করে বা outbound connection তৈরি করে, তাদের জন্য এটি গুরুত্বপূর্ণ।

[Service] program কীভাবে চলে তা নির্ধারণ করে। আপনার অধিকাংশ setting এখানে থাকবে:

[Service]
ExecStart=/usr/local/bin/myapp --config /etc/myapp/config.toml
WorkingDirectory=/opt/myapp
User=myapp
Restart=on-failure
RestartSec=5
Environment=LOG_LEVEL=info

User=myapp program-টিকে root-এর পরিবর্তে unprivileged account হিসেবে চালায়। নিরাপত্তার জন্য এটিই সবচেয়ে গুরুত্বপূর্ণ line। এখানে কোনো Type= line নেই, তাই systemd simple-এ fallback করে এবং ধরে নেয় যে ExecStart process foreground-এ চলবে। কোনো program যদি background-এ fork করে, তাহলে কীভাবে এটি start হয় তার জন্য সঠিক Type= ব্যবহার করতে হবে। তা না হলে প্রকৃত daemon ইতিমধ্যে বন্ধ হয়ে গেলেও unit active দেখাবে। Restart=on-failure এবং RestartSec=5-এর জন্য নিচে আলাদা section রয়েছে, কারণ অধিকাংশ মানুষ service লেখেন মূলত এই কারণেই।

[Install] service enable করলে কী ঘটে তা নির্ধারণ করে:

[Install]
WantedBy=multi-user.target

আপনি systemctl enable চালালে WantedBy=multi-user.target service-টিকে boot-এর সঙ্গে যুক্ত করে। কোনো [Install] section না থাকলে service হাতে start করা যায়, কিন্তু reboot-এর পরে এটি নিজে থেকে চালু হবে না।

এটি চালু করুন এবং পর্যবেক্ষণ করুন

কোনো unit file লিখে বা সম্পাদনা করার পরে systemd reload করুন, যাতে এটি পরিবর্তনটি পড়তে পারে। এরপর এক ধাপে service-টি enable ও start করুন:

sudo systemctl daemon-reload
sudo systemctl enable --now myapp.service

daemon-reload ধাপটি অনেকে ভুলে যান: systemd unit file cache করে রাখে, তাই reload না করা পর্যন্ত সম্পাদনার কোনো প্রভাব পড়ে না। enable --now service-টিকে boot-এর সময় চালু হওয়ার জন্য enable করে এবং একই সঙ্গে সঙ্গে start করে। এটি পরীক্ষা করুন:

sudo systemctl status myapp.service
* myapp.service - My application
     Loaded: loaded (/etc/systemd/system/myapp.service; enabled)
     Active: active (running) since Wed 2026-07-15 22:40:11 UTC; 3s ago
   Main PID: 4123 (myapp)

Active: active (running) এবং enabled-এর ফলাফলই প্রত্যাশিত। প্রোগ্রামের output পড়তে শুধু এই unit-এর জন্য journal-এর কাছে অনুরোধ করুন:

sudo journalctl -u myapp.service -f

-f নতুন line আসার সঙ্গে সঙ্গে তা অনুসরণ করে, tail -f-এর মতো। আপনার প্রোগ্রাম standard output বা standard error-এ যা লিখবে, তা আপনার পক্ষ থেকে কোনো logging setup ছাড়াই এখানে চলে আসবে।

ব্যর্থ হলে পুনরায় চালু করা: আপনি এখানে আসার কারণ

কোনো service-এর প্রধান সুবিধা হলো, আপনার program বন্ধ হয়ে গেলে systemd সেটি পুনরায় চালু করে। দুটি line-ই এটি করে:

[Service]
Restart=on-failure
RestartSec=5

Restart=on-failure program-টি non-zero code দিয়ে বন্ধ হলে অথবা SIGKILL বা SIGSEGV-এর মতো crash signal-এ বন্ধ হলে সেটিকে পুনরায় চালু করে। স্বাভাবিকভাবে বন্ধ হওয়া, অথবা SIGTERM, SIGINT, SIGHUP বা SIGPIPE দিয়ে থামানো হলে এটি চালু হয় না। RestartSec=5 প্রতিটি প্রচেষ্টার মধ্যে পাঁচ সেকেন্ড অপেক্ষা করে। তাই সঙ্গে সঙ্গে crash করা program tight loop-এ বারবার চালু হয় না। Process-টি বন্ধ করে এবং systemd কীভাবে সেটিকে আবার চালু করে তা monitor করে বিষয়টি নিশ্চিত করুন। SIGKILL ব্যবহার করুন। Default SIGTERM-কে স্বাভাবিক stop হিসেবে গণ্য করা হয়, তাই on-failure service-টি পুনরায় চালু করবে না:

sudo systemctl kill -s SIGKILL myapp.service
sudo systemctl status myapp.service

পাঁচ সেকেন্ডের মধ্যে status-এ নতুন Main PID দেখা যাবে এবং active (running) আবার প্রদর্শিত হবে। এটাই পুরো feature। এই কারণেই program-কে tmux বা screen-এ চালু রেখে দেওয়ার চেয়ে service ব্যবহার করা ভালো।

এটি অপ্রিভিলেজড user হিসেবে চালান এবং harden করুন

কোনো service root হিসেবে চললে program-এ exploit হলে এটি আপনার server-এ যেকোনো কাজ করতে পারে। এটিকে নিজস্ব user হিসেবে চালান এবং systemd-তে কয়েকটি directive যোগ করে এর কার্যক্রম সীমাবদ্ধ করুন। প্রথমে login এবং home ছাড়া একটি system account তৈরি করুন:

sudo useradd --system --no-create-home --shell /usr/sbin/nologin myapp

এরপর User=myapp সেট করুন এবং [Service]-এ hardening line যোগ করুন:

[Service]
User=myapp
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true

প্রতিটি line এমন একটি ক্ষমতা সরিয়ে দেয়, যেটি programটির প্রয়োজন নেই। NoNewPrivileges=true process-টিকে নতুন privilege অর্জন করা থেকে সম্পূর্ণভাবে বিরত রাখে, এমনকি setuid binary-এর মাধ্যমেও। PrivateTmp=true process-টিকে একটি private /tmp দেয়, যা অন্য কোনো process দেখতে পারে না। ProtectSystem=strict কয়েকটি path ছাড়া পুরো filesystem read-only করে; নির্দিষ্ট path-গুলো ReadWritePaths= দিয়ে উল্লেখ করা হয়। ProtectHome=true তার কাছ থেকে /home সম্পূর্ণ আড়াল করে। এটি service-কে firewall-এর পেছনে রাখার মতো একই least-privilege নীতির প্রয়োগ: serviceটির যতটুকু প্রয়োজন, শুধু ততটুকুই দিন। VPS-এ IPv6 firewall gap বন্ধ করা বিষয়ক guide পড়ে থাকলে, এটি একই ধারণার on-host অংশ। Internet-facing service-এর ক্ষেত্রে এই hardening-এর সঙ্গে SSH-এর সামনে Fail2ban এবং default-deny firewall ব্যবহার করুন।

সবকিছু হাতে লিখে কোনো directive ভুল মনে রাখার পরিবর্তে, একটি সম্পূর্ণ hardened unit তৈরি করে সেটি কপি করুন:

Toolsystemd service and timer generator

Timers: আধুনিক cron

একটি systemd timer নির্ধারিত সময়সূচি অনুযায়ী একটি service চালায়। এটি cron job-এর আধুনিক বিকল্প। একটি timer দুটি ফাইল নিয়ে গঠিত: কাজটি করে এমন একটি .service এবং কখন কাজটি চালাতে হবে তা নির্ধারণ করে এমন একটি .timer। ধরুন, আপনি প্রতিদিন ভোর 3টায় backup নিতে চান। service-টি কাজটি একবার করে এবং তারপর বন্ধ হয়ে যায়:

# /etc/systemd/system/backup.service
[Unit]
Description=Nightly backup

[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.sh

Type=oneshot systemd-কে জানায় যে প্রোগ্রামটি চলবে, কাজ শেষ করবে এবং বন্ধ হয়ে যাবে। এটি স্থায়ীভাবে চালু থাকবে না। timer সেটির সময়সূচি নির্ধারণ করে:

# /etc/systemd/system/backup.timer
[Unit]
Description=Run the nightly backup

[Timer]
OnCalendar=*-*-* 03:00:00
Persistent=true

[Install]
WantedBy=timers.target

OnCalendar=*-*-* 03:00:00 মানে প্রতিদিন ভোর 3টা। systemd-analyze calendar "*-*-* 03:00:00" দিয়ে যেকোনো calendar expression পরীক্ষা করতে পারেন। এটি expression-টি সঠিকভাবে parse হয়েছে কি না নিশ্চিত করে এবং পরবর্তী কখন কখন এটি চলবে তা দেখায়। server ভোর 3টায় বন্ধ থাকলে Persistent=true server চালু হওয়ার সঙ্গে সঙ্গে বাদ পড়া job চালায়। cron তা করতে পারে না। মনে রাখবেন, timer সক্রিয় করতে timers.target ব্যবহার করতে হয়, multi-user.target নয়। service নয়, timer সক্রিয় করুন:

sudo systemctl daemon-reload
sudo systemctl enable --now backup.timer
systemctl list-timers

list-timers পরবর্তী এবং সর্বশেষ run-সহ প্রতিটি timer দেখায়। ফলে আপনার job পরবর্তী কখন চলবে তা দ্রুত দেখা যায়। timer mode চালু করলে উপরের generator আপনার জন্য জোড়া .service এবং .timer তৈরি করে। একটি cron line-এর তুলনায় timer journal-এ প্রকৃত log, প্রতিটি service-এর মতো একই hardening directive এবং Persistent=true-এর দেওয়া বাদ পড়া run পুনরায় চালানোর সুবিধা দেয়। সাধারণ job-এর জন্য cron এখনও উপযুক্ত। তবে job গুরুত্বপূর্ণ হলে timer ব্যবহার করাই ভালো।

FAQ

systemd service এবং cron job-এর মধ্যে পার্থক্য কী?

একটি service দীর্ঘ সময় চলা program সচল রাখে: এটি boot-এর সময় start হয়, failure হলে restart হয় এবং journal-এ log লেখে। একটি cron job নির্ধারিত সময়সূচি অনুযায়ী একটি সংক্ষিপ্ত command চালায় এবং তারপর exit করে। আপনার scheduling সুবিধা দরকার, কিন্তু journal log, hardening এবং missed run-এর catch-up-ও দরকার হলে systemd timer ব্যবহার করুন। এটি একটি .timer schedule-এর সঙ্গে একটি oneshot service যুক্ত করে এবং বেশিরভাগ server task-এর ক্ষেত্রে cron-এর বিকল্প হিসেবে কাজ করে।

আমার systemd service file কোথায় রাখব?

নিজস্ব unit-গুলো /etc/systemd/system/-এ রাখুন এবং নামের শেষে .service ব্যবহার করুন। এই directory administrator-এর যোগ করা unit-এর জন্য নির্ধারিত এবং /lib/systemd/system/-এ package-এর সঙ্গে shipped unit-এর ওপর অগ্রাধিকার পায়। সেখানে file তৈরি বা সম্পাদনা করার পর sudo systemctl daemon-reload চালান, যাতে systemd পরিবর্তনটি গ্রহণ করে।

কোনো service crash করলে কীভাবে সেটিকে restart করব?

[Service] section-এ Restart=on-failure এবং RestartSec=5 যোগ করুন। এরপর sudo systemctl daemon-reload চালিয়ে service restart করুন। Program non-zero code নিয়ে exit করলে বা crash signal-এ বন্ধ হলে systemd সেটিকে আবার চালু করে। প্রতিটি চেষ্টার মধ্যে পাঁচ সেকেন্ড অপেক্ষা করে। sudo systemctl kill -s SIGKILL myapp.service দিয়ে এটি পরীক্ষা করুন। Default signal SIGTERM-কে clean stop হিসেবে গণ্য করা হয় এবং এটি on-failure চালু করে না। কয়েক সেকেন্ডের মধ্যে নতুন PID দেখা যাচ্ছে কি না, তা systemctl status-এ দেখুন।

কীভাবে systemd service-কে non-root user হিসেবে চালাব?

sudo useradd --system --no-create-home --shell /usr/sbin/nologin myapp দিয়ে একটি system account তৈরি করুন। এরপর [Service] section-এ User=myapp যোগ করুন। Process-টি যত কম access প্রয়োজন, ততটুকু access-এই চালানোর জন্য NoNewPrivileges=true, PrivateTmp=true এবং ProtectSystem=strict যোগ করুন। Unprivileged user হিসেবে চালানো service-এর নিরাপত্তা বাড়াতে সবচেয়ে গুরুত্বপূর্ণ একক পরিবর্তন।

আমার service start হতে ব্যর্থ হলো কেন?

সারসংক্ষেপের জন্য systemctl status myapp.service এবং সম্পূর্ণ output-এর জন্য journalctl -u myapp.service চালান। সবচেয়ে সাধারণ কারণ হলো ExecStart-এ ভুল path, WorkingDirectory অনুপস্থিত থাকা, User= কোনো file পড়তে না পারায় permission error, অথবা edit করার পর sudo systemctl daemon-reload না চালানো। Journal program-এর নিজস্ব error message দেখায়, যা সাধারণত সরাসরি সমস্যাটি শনাক্ত করে।