SSD Nodes Learn Hosting plans →
Mga Gabay Matt ConnorNi Matt Connor · Na-update 2026-08-31

Paano gawing systemd service ang program sa VPS

Alamin kung paano gumawa ng systemd service para awtomatikong mag-start sa boot, mag-restart kapag nag-crash, mag-log sa journal, gumamit ng timer, at mag-harden.

Ano ang systemd service, at kung bakit kailangan mo nito

Ang systemd service ay isang maliit na text file na nagsasabi sa server kung paano patakbuhin ang isang program: simulan ito sa boot, i-restart kapag nag-crash, at ipadala ang output nito sa system log. Iyan ang buong gawain nito. Ang program na sinimulan mo nang mano-mano sa isang SSH session ay hihinto sa sandaling mag-logout ka o mag-reboot ang server. Ang program na nasa systemd service ay patuloy na tatakbo dahil ang server mismo ang namamahala rito, hindi ang shell mo.

Ang systemd ang init system sa Ubuntu, Debian, Fedora, at karamihan ng modern Linux server. Ito ang unang prosesong nagsisimula at ang prosesong nagso-supervise sa lahat ng iba pa. Hindi ito palaging ganito, at sulit basahin minsan ang kung paano pinalitan ng systemd ang mga init script na nauna rito kapag alam mo na kung ano ang ginagawa ng unit file. Kapag sumulat ka ng service file, ipinagkakatiwala mo ang program mo sa supervisor na iyon. Ipinapakita ng gabay na ito ang pinakamaliit na gumaganang unit, ang tatlong seksyong mayroon ang bawat unit, kung paano ito i-on at basahin ang mga log nito, kung paano ito patakbuhin ayon sa iskedyul gamit ang timer, at kung paano ito i-lock down upang gumana gamit ang pinakamaliit na privilege hangga't maaari.

Pinakamaliit na gumaganang service

Ang service file ay nasa /etc/systemd/system/, nagtatapos sa .service, at ilang linya lang ang kailangan. Gumawa ng file para sa program sa /usr/local/bin/myapp:

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

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

[Install]
WantedBy=multi-user.target

Kumpleto at gumagana na ang unit na ito. Ang ExecStart ang command na tatakbuhin. Ibig sabihin ng WantedBy=multi-user.target, simulan ito kapag umabot na ang server sa normal na multi-user operation. Dahil dito, awtomatiko itong magsisimula kapag nag-boot. Ang lahat ng iba pa ay refinement.

Ang tatlong seksyon at gamit ng bawat isa

Hinahati ang bawat unit file sa mga seksyong nasa loob ng square brackets. Tatlo ang ginagamit ng isang service.

[Unit] ang naglalarawan sa service at sa mga kaugnayan nito. Ito ang dalawang linyang pinakamadalas mong gagamitin:

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

Description ang human-readable na label na nakikita mo sa systemctl status. Sinasabi ng After=network-online.target sa systemd na huwag simulan ang iyong program hanggang maging available ang network. Mahalaga ito para sa anumang program na nagbi-bind sa isang port o gumagawa ng outbound connection.

[Service] ang nagtatakda kung paano tumatakbo ang program. Dito inilalagay ang karamihan ng iyong settings:

[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 ang nagpapatakbo sa program gamit ang unprivileged account sa halip na root. Ito ang pinakamahalagang linya para sa seguridad. Walang Type= line dito, kaya gumagamit ang systemd ng simple bilang default at ipinapalagay na nananatili sa foreground ang ExecStart process. Kung nagfa-fork sa background ang program, kailangan nito ang tamang Type= ayon sa paraan ng pagsisimula nito, kung hindi, iuulat ng unit na active ito kahit wala na ang aktuwal na daemon. May sarili nang seksyon sa ibaba ang Restart=on-failure at RestartSec=5 dahil karaniwang sila ang dahilan kung bakit gumagawa ng service ang mga administrator.

[Install] ang nagtatakda kung ano ang mangyayari kapag in-enable mo ang service:

[Install]
WantedBy=multi-user.target

WantedBy=multi-user.target ang nagli-link sa service sa boot kapag pinatakbo mo ang systemctl enable. Kung walang [Install] section, maaaring simulan ang service nang mano-mano, pero hindi ito awtomatikong magsisimula pagkatapos ng reboot.

I-on ito at i-monitor

Pagkatapos gumawa o mag-edit ng anumang unit file, i-reload ang systemd para mabasa nito ang pagbabago, pagkatapos ay i-enable at simulan ang service sa isang hakbang:

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

Ang daemon-reload ang hakbang na madalas nakalilimutan: kino-cache ng systemd ang mga unit file, kaya walang epekto ang pag-edit hangga't hindi ito nire-reload. Parehong ini-enable ng enable --now ang service para sa boot at agad itong sinisimulan. Suriin ito:

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)

Ang Active: active (running) at enabled ang inaasahang resulta. Para basahin ang output ng program, hilingin sa journal na ipakita lamang ang unit na ito:

sudo journalctl -u myapp.service -f

Sinusundan ng -f ang mga bagong linya habang dumarating ang mga ito, gaya ng tail -f. Anumang isulat ng program sa standard output o standard error ay mapupunta rito nang hindi mo kailangang mag-set up ng logging.

Restart kapag nag-fail, ang dahilan kung bakit ka narito

Ang pangunahing pakinabang ng isang service ay awtomatikong nire-restart ng systemd ang program kapag natigil ito. Dalawang linya lang ang kailangan:

[Service]
Restart=on-failure
RestartSec=5

Nire-restart ng Restart=on-failure ang program kapag nag-exit ito na may non-zero code o natigil dahil sa crash signal gaya ng SIGKILL o SIGSEGV. Hindi ito nagti-trigger kapag maayos na nag-exit ang program o pinatigil gamit ang SIGTERM, SIGINT, SIGHUP, o SIGPIPE. Naghihintay ang RestartSec=5 ng limang segundo sa pagitan ng mga pagtatangka upang hindi paulit-ulit na mag-restart nang napakabilis ang program na agad nagka-crash. Kumpirmahin ito sa pamamagitan ng pag-kill sa process at pagmamasid habang ibinabalik ito ng systemd. Gamitin ang SIGKILL: itinuturing na maayos na paghinto ang default na SIGTERM, kaya hindi ire-restart ng on-failure ang service:

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

Sa loob ng limang segundo, ipinapakita ng status ang bagong Main PID at muli ang active (running). Iyon ang buong feature, at ito ang dahilan kung bakit mas mainam ang service kaysa hayaan ang program na tumakbo sa tmux o screen.

Patakbuhin ito bilang unprivileged user at i-harden ito

Ang serbisyong tumatakbo bilang root ay maaaring gumawa ng anuman sa server kung ma-exploit ang program. Patakbuhin ito bilang sarili nitong user, at magdagdag ng ilang directive sa systemd upang malimitahan ang maaabot nito. Una, gumawa ng system account na walang login at walang home:

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

Pagkatapos, itakda ang User=myapp at idagdag ang mga hardening line sa [Service]:

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

Bawat line ay nag-aalis ng isang bagay na hindi kailangan ng program. Pinipigilan ng NoNewPrivileges=true ang process na magkaroon ng bagong privilege, kahit sa pamamagitan ng setuid binary. Binibigyan ito ng PrivateTmp=true ng pribadong /tmp na hindi makikita ng ibang process. Ginagawang read-only ng ProtectSystem=strict ang buong filesystem, maliban sa ilang path na itatalaga mo gamit ang ReadWritePaths=. Itinatago naman ng ProtectHome=true ang /home mula rito nang buo. Ito ang parehong prinsipyo ng least privilege na ginagamit kapag inilalagay ang serbisyo sa likod ng firewall: ibigay lamang ang kailangan nito. Kung nabasa mo na ang gabay tungkol sa pagsara sa IPv6 firewall gap sa isang VPS, ito ang on-host na bahagi ng parehong prinsipyo. Para sa serbisyong nakaharap sa internet, ipares ang hardening na ito sa Fail2ban sa harap ng SSH at sa firewall na default-deny.

Sa halip na mano-manong i-type ang lahat ng ito at makalimutan ang isang directive, bumuo ng kumpleto at hardened na unit at kopyahin ito:

Toolsystemd service and timer generator

Mga timer: ang modernong cron

Ang systemd timer ay nagpapatakbo ng service ayon sa iskedyul. Ito ang modernong kapalit ng cron job. Dalawang file ang timer: isang .service na nagsasagawa ng trabaho, at isang .timer na tumutukoy kung kailan ito tatakbo. Halimbawa, gusto mong magsagawa ng backup araw-araw nang 3am. Isinasagawa ng service ang task nang isang beses at pagkatapos ay nag-e-exit:

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

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

Ipinapahiwatig ng Type=oneshot sa systemd na tumatakbo ang program, natatapos, at humihinto, sa halip na manatiling resident. Isinasaad ng timer ang iskedyul nito:

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

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

[Install]
WantedBy=timers.target

Nangangahulugan ang OnCalendar=*-*-* 03:00:00 na 3am araw-araw. Subukan ang anumang calendar expression gamit ang systemd-analyze calendar "*-*-* 03:00:00". Tinitiyak nito na tama ang pag-parse sa expression at ipinapakita ang mga susunod na oras ng pagtakbo nito. Pinapatakbo ng Persistent=true ang na-miss na job sa sandaling bumalik online ang server kung naka-off ito nang 3am. Hindi ito kayang gawin ng cron. Tandaan na ine-enable ang timer gamit ang timers.target, hindi ang multi-user.target. I-enable ang timer, hindi ang service:

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

Ipinapakita ng list-timers ang lahat ng timer pati ang susunod at huling pagtakbo ng mga ito. Makikita mo agad kung kailan susunod na tatakbo ang iyong job. Awtomatikong binubuo ng generator sa itaas ang magkaparehong .service at .timer kapag in-enable mo ang timer mode. Kung ihahambing sa isang cron line, nagbibigay ang timer ng aktuwal na logs sa journal, ng parehong hardening directives na ginagamit ng anumang service, at ng catch-up para sa na-miss na pagtakbo na ibinibigay ng Persistent=true. Sapat pa rin ang cron para sa simpleng job. Mas angkop ang timer kapag mahalaga ang job.

FAQ

Ano ang pagkakaiba ng systemd service at cron job?

Pinananatiling tumatakbo ng service ang isang long-running program: nagsisimula ito sa boot, nagre-restart kapag nag-fail, at nagsusulat ng logs sa journal. Nagpapatakbo naman ang cron job ng maikling command ayon sa iskedyul at pagkatapos ay nag-e-exit. Kung kailangan mo ang scheduling at gusto mo rin ng journal logs, hardening, at catch-up para sa mga run na hindi naisagawa, gumamit ng systemd timer. Pinagtatambal nito ang isang .timer schedule at oneshot service, at kadalasang pinapalitan ang cron para sa mga server task.

Saan ko ilalagay ang systemd service file ko?

Ilagay ang sarili mong units sa /etc/systemd/system/, na may pangalang nagtatapos sa .service. Para sa mga unit na idinaragdag ng administrator ang directory na ito, at mas mataas ang priority nito kaysa sa mga unit na kasama sa packages sa /lib/systemd/system/. Pagkatapos gumawa o mag-edit ng file roon, patakbuhin ang sudo systemctl daemon-reload para mabasa ng systemd ang pagbabago.

Paano ko mapapa-restart ang service kapag nag-crash ito?

Idagdag ang Restart=on-failure at RestartSec=5 sa seksyong [Service], pagkatapos ay patakbuhin ang sudo systemctl daemon-reload at i-restart ang service. Muling inilulunsad ng systemd ang program kapag nag-exit ito na may non-zero code o namatay dahil sa crash signal, at naghihintay ng limang segundo sa pagitan ng mga pagtatangka. I-test ito gamit ang sudo systemctl kill -s SIGKILL myapp.service. Ang SIGTERM, ang default signal, ay itinuturing na malinis na pag-stop at hindi nagti-trigger ng on-failure. I-monitor ang systemctl status upang makita ang bagong PID sa loob ng ilang segundo.

Paano ko tatakbuhin ang systemd service bilang non-root user?

Gumawa ng system account gamit ang sudo useradd --system --no-create-home --shell /usr/sbin/nologin myapp, pagkatapos ay idagdag ang User=myapp sa seksyong [Service]. Idagdag ang NoNewPrivileges=true, PrivateTmp=true, at ProtectSystem=strict upang tumakbo ang proseso gamit lamang ang access na kailangan nito. Ang pagpapatakbo bilang unprivileged user ang pinakamahalagang solong pagbabagong magagawa mo para sa kaligtasan ng service.

Bakit nag-fail magsimula ang service ko?

Patakbuhin ang systemctl status myapp.service para sa buod at journalctl -u myapp.service para sa buong output. Ang pinakakaraniwang sanhi ay maling path sa ExecStart, nawawalang WorkingDirectory, permission error dahil hindi mabasa ng User= ang isang file, o nakalimutang sudo systemctl daemon-reload pagkatapos mag-edit. Ipinapakita ng journal ang sariling error message ng program, na karaniwang direktang nagsasaad ng problema.