paano gumawa ng systemd service sa VPS
Matutong gumawa ng systemd service para sa iyong program. Alamin ang tamang configuration para sa auto-restart, boot start, at paggamit ng journalctl logs.
Ano ang systemd service, at bakit ito kailangan
Ang systemd service ay isang maliit na text file na nagdidikta sa server kung paano patakbuhin ang isang program: i-start ito sa boot, i-restart kung mag-crash, at i-send ang output nito sa system log. Iyon lang ang tungkulin nito. Ang program na manu-manong sinimulan sa isang SSH session ay hihinto kapag nag-log out ka o nag-reboot ang server. Ang program na naka-wrap sa isang systemd service ay patuloy na tatakbo dahil ang server na ang may-ari nito sa halip na ang iyong shell.
Ang systemd ang init system sa Ubuntu, Debian, Fedora, at karamihan sa mga modernong Linux server. Ito ang unang prosesong nag-uumpisa at ang nagbabantay sa lahat ng iba pang proseso. Kapag gumawa ka ng service file, ipinapasa mo ang iyong program sa supervisor na ito. Ipinapakita ng guide na ito ang pinakasimpleng unit na gumagana, ang tatlong section na mayroon ang bawat unit, kung paano ito i-on at basahin ang logs nito, kung paano ito patakbuhin gamit ang timer, at kung paano ito i-secure para tumakbo nang may pinakamababang privilege.
Ang pinakamaliit na working service
Ang service file ay matatagpuan sa /etc/systemd/system/, may extension na .service, at nangangailangan lamang ng ilang linya. Gumawa ng isa 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.targetIsang kumpletong working unit na ito. Ang ExecStart ang command para i-run ito. Ang WantedBy=multi-user.target ay nangangahulugang i-start ang service kapag ang server ay nasa normal multi-user operation na, na siyang dahilan kung bakit ito mag-uumpisa sa boot. Ang lahat ng iba pang settings ay para sa refinement lamang.
Ang tatlong section, at ang gamit ng bawat isa
Ang bawat unit file ay nahahati sa mga section na nasa loob ng square brackets. Gumagamit ang isang service ng tatlo.
Inilalarawan ng [Unit] ang service at ang mga relasyon nito. Ang dalawang linyang madalas mong gagamitin:
[Unit]
Description=My application
After=network-online.target
Wants=network-online.targetAng Description ay ang human label na makikita sa systemctl status. Sinasabi ng After=network-online.target sa systemd na huwag munang i-start ang iyong program hanggang hindi up ang network, na mahalaga para sa anumang nagba-bind ng port o gumagawa ng outbound connection.
Ang [Service] ay kung paano patatakbuhin ang program. Dito inilalagay ang karamihan sa iyong mga 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=infoPinapatakbo ng User=myapp ang program bilang isang unprivileged account sa halip na root, na siyang pinakamahalagang linya para sa safety. Ang Restart=on-failure at RestartSec=5 ay may sariling section sa ibaba, dahil ito ang dahilan kung bakit gumagawa ang karamihan ng service.
Ang [Install] ay ang mangyayari kapag i-e-enable ang service:
[Install]
WantedBy=multi-user.targetAng WantedBy=multi-user.target ang nag-uugnay sa service sa boot kapag ni-run ang systemctl enable. Kung walang [Install] section, maaaring i-start ang service nang manual pero hindi ito kusang mag-uumpisa pagkatapos ng reboot.
I-on ito at i-monitor
Pagkatapos mag-write o mag-edit ng anumang unit file, i-reload ang systemd para mabasa ang pagbabago. Pagkatapos, i-enable at i-start ang service sa isang hakbang:
sudo systemctl daemon-reload
sudo systemctl enable --now myapp.serviceNakalilimutang hakbang ang daemon-reload: naka-cache ng systemd ang mga unit file, kaya walang mangyayari sa edit hangga't hindi nagre-reload. Ginagawa ng enable --now na i-enable ang service para sa boot at i-start ito agad. I-check 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 dapat mong makita. Para basahin ang output ng program, gamitin ang journal para sa unit na ito lamang:
sudo journalctl -u myapp.service -fAng -f ay sinusundan ang mga bagong linya habang dumarating ang mga ito, katulad ng tail -f. Anumang isulat ng iyong program sa standard output o standard error ay mapupunta rito nang hindi nangangailangan ng logging setup sa iyong panig.
Restart on failure, ang dahilan kung bakit ka narito
Ang pangunahing benepisyo ng isang service ay ang pag-restart ng systemd sa iyong program kapag ito ay nag-crash. Ginagawa ito ng dalawang linya:
[Service]
Restart=on-failure
RestartSec=5Nire-restart ng Restart=on-failure ang program kapag nag-exit ito na may non-zero code o kapag nag-crash dahil sa signal na SIGKILL o SIGSEGV. Hindi ito gagana sa clean exit, o kung itinigil gamit ang SIGTERM, SIGINT, SIGHUP, o SIGPIPE. Naghihintay ang RestartSec=5 ng limang segundo sa bawat pagsubok, para hindi magkaroon ng infinite loop ang program na mabilis mag-crash. I-verify ito sa pamamagitan ng pag-kill sa process at pag-obserba kung ibabalik ito ng systemd. Gamitin ang SIGKILL: ang default na SIGTERM ay itinuturing na clean stop, kaya hindi ire-restart ng on-failure ang service:
sudo systemctl kill -s SIGKILL myapp.service
sudo systemctl status myapp.serviceSa loob ng limang segundo, makikita sa status ang bagong Main PID at active (running) muli. Iyan ang buong feature na ito, at ito ang dahilan kung bakit mas mainam ang service kaysa sa pagpapatakbo ng program sa tmux o screen.
Patakbuhin ito bilang unprivileged user, at i-harden ito
Maaaring magawa ng isang service na tumatakbo bilang root ang kahit ano sa iyong server kung ma-exploit ang program. Patakbuhin ito gamit ang sarili nitong user, at bigyan ang systemd ng mga directive para limitahan ito. Una, gumawa ng system account na walang login at walang home directory:
sudo useradd --system --no-create-home --shell /usr/sbin/nologin myappPagkatapos ay i-set ang User=myapp at magdagdag ng hardening lines sa [Service]:
[Service]
User=myapp
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=trueAng bawat linya ay nag-aalis ng mga bagay na hindi kailangan ng program. Pinipigilan ng NoNewPrivileges=true ang process na makakuha ng bagong privileges, kahit sa pamamagitan ng setuid binary. Binibigyan ng PrivateTmp=true ang process ng isang private /tmp na hindi makikita ng ibang process. Ginagawang read-only ng ProtectSystem=strict ang buong filesystem maliban sa mga path na itatakda mo gamit ang ReadWritePaths=. Itinatago ng ProtectHome=true ang /home nang tuluyan. Ito ay katulad ng least-privilege principle sa paglalagay ng service sa likod ng firewall: ibigay lamang ang kailangan nito. Kung nabasa mo na ang guide sa pag-close ng IPv6 firewall gap sa isang VPS, ito ang on-host na bahagi ng parehong konsepto. Para sa mga service na nakaharap sa internet, isama ang hardening na ito sa Fail2ban sa harap ng SSH at isang default-deny firewall.
Sa halip na i-type ang lahat ng ito nang manual at magkamali sa directive, mag-generate ng isang kumpletong hardened unit at i-copy ito:
Timers: ang modernong cron
Ang systemd timer ay nagpapatakbo ng service base sa schedule, at ito ang modernong kapalit ng cron job. Ang timer ay binubuo ng dalawang file: isang .service na gumagawa ng trabaho, at isang .timer na nagsasabi kung kailan ito gagawin. Halimbawa, kung gusto mo ng backup tuwing 3am araw-araw. Gagawin ng service ang task nang isang beses at mag-eexit:
# /etc/systemd/system/backup.service
[Unit]
Description=Nightly backup
[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.shSinasabi ng Type=oneshot sa systemd na ang program ay tatakbo, matatapos, at tapos na, sa halip na manatiling resident sa memory. I-schedule ito ng timer:
# /etc/systemd/system/backup.timer
[Unit]
Description=Run the nightly backup
[Timer]
OnCalendar=*-*-* 03:00:00
Persistent=true
[Install]
WantedBy=timers.targetAng OnCalendar=*-*-* 03:00:00 ay nangangahulugang 3am araw-araw. I-test ang anumang calendar expression gamit ang systemd-analyze calendar "*-*-* 03:00:00", na nagpapatunay kung tama ang parsing at ipinapakita ang susunod na mga oras ng pagtakbo nito. Pinapatakbo ng Persistent=true ang mga missed job agad kapag bumalik ang server kung ito ay naka-off noong 3am, isang bagay na hindi kayang gawin ng cron. Pansinin na ang timer ay ina-enable sa pamamagitan ng timers.target, hindi multi-user.target. I-enable ang timer, hindi ang service:
sudo systemctl daemon-reload
sudo systemctl enable --now backup.timer
systemctl list-timersIpinapakita ng list-timers ang lahat ng timer kasama ang susunod at huling takbo nito, para makita mo agad kung kailan susunod na gagana ang iyong job. Ang generator sa itaas ay awtomatikong gumagawa ng pares na .service at .timer para sa iyo kapag naka-on ang timer mode. Kumpara sa cron line, ang timer ay nagbibigay ng totoong logs sa journal, ang parehong hardening directives gaya ng anumang service, at ang missed-run catch-up na ibinibigay ng Persistent=true. Ayos pa rin ang cron para sa mga simpleng job; ngunit mas mahusay na tool ang timer kapag mahalaga na ang trabaho.
FAQ
Ano ang pagkakaiba ng systemd service at cron job?
Ang service ay nagpapanatili ng isang long-running program: nagsisimula ito sa boot, nagre-restart kapag nag-fail, at naglo-log sa journal. Ang cron job naman ay nagpapatakbo ng maikling command sa isang schedule at pagkatapos ay nag-eexit. Kung kailangan mo ng scheduling pero gusto mo rin ng journal logs, hardening, at catch-up para sa mga missed runs, gamitin ang systemd timer. Ipinapares nito ang isang .timer schedule sa isang oneshot service at pinapalitan ang cron para sa karamihan ng server tasks.
Saan dapat ilagay ang aking systemd service file?
Ilagay ang iyong sariling units sa /etc/systemd/system/, na may pangalan na nagtatapos sa .service. Ang directory na ito ay para sa mga unit na idinagdag ng administrator, at mas mataas ang priority nito kaysa sa mga unit mula sa mga package sa /lib/systemd/system/. Pagkatapos gumawa o mag-edit ng file doon, i-run ang sudo systemctl daemon-reload para ma-detect ng systemd ang pagbabago.
Paano gagawing mag-restart ang service kapag nag-crash ito?
Magdagdag ng Restart=on-failure at RestartSec=5 sa [Service] section, pagkatapos ay i-run ang sudo systemctl daemon-reload at i-restart ang service. Muling patatakbuhin ng systemd ang program kapag nag-exit ito na may non-zero code o namatay dahil sa crash signal, na may limang segundong pagitan sa bawat subok. I-test ito gamit ang sudo systemctl kill -s SIGKILL myapp.service — ang SIGTERM, ang default signal, ay itinuturing na clean stop at hindi magti-trigger ng on-failure — at obserbahan ang systemctl status para makita ang bagong PID sa loob ng ilang segundo.
Paano patatakbuhin 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 [Service] section. Magdagdag ng NoNewPrivileges=true, PrivateTmp=true, at ProtectSystem=strict para ang process ay tumakbo na may pinakamababang access na kailangan nito. Ang pagtakbo bilang unprivileged user ang pinakaimportanteng pagbabago na magagawa mo para sa safety ng isang service.
Bakit hindi nag-start ang aking service?
I-run ang systemctl status myapp.service para sa summary at journalctl -u myapp.service para sa buong output. Ang mga karaniwang sanhi ay maling path sa ExecStart, kulang na WorkingDirectory, permission error dahil hindi mabasa ng User= ang isang file, o nakalimutang sudo systemctl daemon-reload pagkatapos mag-edit. Ipinapakita ng journal ang mismong error message ng program, na karaniwang direktang nagsasabi ng problema.