How to use it
- Enter the service name (the file name without .service), a description and the command with its full path.
- Set the working directory and, for a system service, the user to run as. Leaving the user empty runs the service as root.
- Pick the type and restart policy, add environment variables one per line, and choose the options.
- Save the unit file to the path shown, then run the commands: daemon-reload, enable –now, then status and journalctl to check it.
How it works
The unit has three sections:
- [Unit]: Description and ordering. A system service gets After=network.target, or After= and Wants=network-online.target when it needs the network. A user service gets no network ordering, because a user manager cannot wait for system units.
- [Service]: Type, User and Group, WorkingDirectory, one Environment=“KEY=value” per variable (with \ and “ escaped), EnvironmentFile, ExecStart, Restart and RestartSec, and with hardening NoNewPrivileges=true and PrivateTmp=true.
- [Install]: WantedBy=multi-user.target for a system service or default.target for a user service, which is what enable hooks into.
Worked example
The default form (name myapp, Node.js server, user myapp, restart on failure after 5 s, two variables, network-online, hardening) gives:
[Unit]
Description=My app
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=myapp
WorkingDirectory=/opt/myapp
Environment="NODE_ENV=production"
Environment="PORT=3000"
ExecStart=/usr/bin/node /opt/myapp/server.js
Restart=on-failure
RestartSec=5
NoNewPrivileges=true
PrivateTmp=true
[Install]
WantedBy=multi-user.target
Saved as /etc/systemd/system/myapp.service, it is started with sudo systemctl daemon-reload and sudo systemctl enable --now myapp.service.
Tips
- systemd expands % specifiers in ExecStart and Environment: write %% for a literal percent sign.
- ExecStart is not run by a shell, so pipes, && and redirects do not work; wrap them as /bin/sh -c ‘…’ or in a script.
- Keep secrets out of the unit file: put them in an EnvironmentFile readable only by root.
- After every change to the file, run daemon-reload and restart the service.