Interactive tool
A systemd service for your program
Answer a few questions and get a unit file that runs your program as its own user, restarts it on failure and sandboxes it, plus the commands to check it with systemd-analyze before you enable it.
Runs in your browser · nothing is sent anywhere
api.service
[Unit] Description=Example API server Wants=network-online.target After=network-online.target [Service] Type=exec User=api WorkingDirectory=/opt/api ExecStart=/opt/api/bin/server --port 8080 Restart=on-failure RestartSec=5 NoNewPrivileges=yes ProtectSystem=strict ProtectHome=yes PrivateTmp=yes ReadWritePaths=/var/lib/api [Install] WantedBy=multi-user.target
The link holds every field of the form above. Remove passwords and tokens before you send it.
Install, check and start it
sudo install -m 644 api.service /etc/systemd/system/ sudo systemd-analyze verify /etc/systemd/system/api.service sudo systemctl daemon-reload sudo systemctl enable --now api systemctl status api journalctl -u api -f systemd-analyze security api
What a unit file is
A unit file tells systemd, the service manager on most Linux servers, how to run a program as a service: the command, which user it runs as, and what to do when it stops. systemd then starts it at boot, restarts it if it crashes and collects its output in the journal.
Using it
Give the full path to your program and a user to run it as. Read the warnings: each is a mistake that would stop the service or make it less safe. Then install the file in /etc/systemd/system, the directory for units created by the administrator, check it with systemd-analyze verify and enable it.
If the service will not start, journalctl -u with its name shows why. With sandboxing on, the usual cause is a directory it needs to write to that is not in the writable paths.
What this checks
- Builds a service unit from your answers, using directives checked against the systemd manual, and warns about relative paths, running as root, secrets in the environment and sandboxing that will block your program.
What it cannot know
- Run your program or know what it needs: which paths it writes, whether it signals readiness, or what sandboxing it tolerates.
- Check that the user, paths and files exist on your server.
Check it for real
sudo systemd-analyze verify /etc/systemd/system/<name>.service systemd-analyze security <name>
verify loads the unit and prints any errors; security scores the sandboxing from 0 to 10, where lower is tighter. Neither tests the program itself, so watch journalctl -u <name> after starting it. systemd-analyze(1)
Why these defaults
Type=exec. With simple, systemd reports the start as successful as soon as it has forked, even if the program then cannot be executed. With exec it waits until the program has actually started, so a wrong path fails the start. The systemd manual recommends exec for long-running services.
Sandboxing. ProtectSystem=strict makes the whole filesystem read-only for the service except the paths you allow, ProtectHome hides home directories, PrivateTmp gives it its own /tmp, and NoNewPrivileges stops it gaining privileges through setuid programs. systemd-analyze security scores the result from 0 to 10, lower meaning tighter.
Secrets. The systemd manual says environment variables are not suitable for passing secrets: they are visible to unprivileged clients and inherited by child processes. Use LoadCredential= for passwords and keys; the program reads them from files under $CREDENTIALS_DIRECTORY.
Questions people ask about this
Where do I put a systemd service file?
In /etc/systemd/system, which the systemd manual lists as the place for units created by the administrator. Run systemctl daemon-reload after adding or changing a file there, then systemctl enable --now with its name to start it now and at every boot.
Should I use Type=simple or Type=exec?
exec, for most long-running programs. With simple, systemd treats the service as started the moment it forks, so a wrong path still looks like a successful start. With exec it waits until the program has been executed. The systemd manual recommends exec for long-running services.
How do I give a systemd service a password safely?
Not through Environment= or an EnvironmentFile: the systemd manual says environment variables are not suitable for passing secrets. Store the secret in a file only root can read, add LoadCredential=name:/path/to/file to the unit, and have the program read it from $CREDENTIALS_DIRECTORY/name.
Did this get you to an answer?
No text box on purpose — please do not paste production logs anywhere
Something wrong or out of date? Report it
Tools that go with this
- Cron Expression BuilderDescribe when a job should run and get the expression, read back through the same engine that explains one.
- docker run to Compose ConverterA docker run command as a Compose service, with every flag it could not convert listed.
- Container Exit Code ExplainerWhat 137, 143 and 139 mean, and the rule behind them.