systemd Services
systemd is the init system on most Linux distros. It owns service lifecycle, logging, sockets, timers (cron replacement), resource limits, and dependency ordering. Writing a proper unit file beats a hand-rolled init script or screen+ssh — your service comes back after reboot, restarts on crash, and its logs land in journald automatically.
A production-shaped systemd service + timer
EXAMPLE
# 1) /etc/systemd/system/shop-api.service [Unit] Description=Shop API server After=network-online.target postgresql.service Wants=network-online.target [Service] Type=exec User=shop Group=shop WorkingDirectory=/srv/shop-api/current EnvironmentFile=/etc/shop-api.env # KEY=VALUE per line; not exposed to logs ExecStart=/usr/bin/node dist/server.js ExecReload=/bin/kill -HUP $MAINPID Restart=on-failure RestartSec=5s TimeoutStopSec=20s SuccessExitStatus=0 143 # 143 = SIGTERM # Resource limits + hardening LimitNOFILE=65535 MemoryHigh=512M MemoryMax=768M CPUQuota=200% NoNewPrivileges=true ProtectSystem=strict ProtectHome=true ReadWritePaths=/srv/shop-api/cache PrivateTmp=true PrivateDevices=true # Logs go to journald automatically StandardOutput=journal StandardError=journal [Install] WantedBy=multi-user.target # 2) Apply changes sudo systemctl daemon-reload sudo systemctl enable --now shop-api sudo systemctl status shop-api sudo journalctl -u shop-api -f -n 200 # 3) Reload config without dropping connections sudo systemctl reload shop-api # 4) Timer (cron replacement) — runs the same unit on a schedule # /etc/systemd/system/shop-backup.service # [Service] # Type=oneshot # ExecStart=/usr/local/bin/shop-backup.sh # /etc/systemd/system/shop-backup.timer # [Unit] # Description=Nightly DB backup # [Timer] # OnCalendar=*-*-* 02:30:00 # every day at 02:30 # Persistent=true # run on next boot if missed (laptop, sleep) # RandomizedDelaySec=10m # avoid herding when many hosts share a cron # [Install] # WantedBy=timers.target sudo systemctl enable --now shop-backup.timer sudo systemctl list-timers --all # 5) Useful introspection systemctl cat shop-api # show the unit file as systemd sees it systemctl edit shop-api # drop-in override (NEVER hand-edit /etc/systemd) systemctl show shop-api -p ActiveState -p SubState -p MemoryCurrent journalctl -u shop-api --since='1 hour ago' --output=json-pretty | jq . # 6) Reboot resilience — does this come up cleanly? sudo reboot # After reboot, systemctl status should show 'active (running)'.
Why it matters
NoNewPrivileges + ProtectSystem=strict + PrivateTmp + a non-root User give you a meaningful security baseline for almost no work. They prevent a compromised service from writing outside its expected paths, escalating privileges, or sharing temp files with anything else on the host — and they cost nothing to flip on.
Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.
Example
Example
sudo systemctl status nginx sudo systemctl restart nginx sudo journalctl -u nginx -fTry it Yourself »
Discussion
Loading…