Serviceman generates and enables startup files on Linux, Mac, and Windows.

To update or switch versions, run webi serviceman@stable (or @v0.8, beta, etc).

Cheat Sheet

A lightweight, cross-platform wrapper to more easily
use your native init system to control system service daemons
and user launch agents. \

Works for web servers, backup scripts, network and system tools, etc, in all languages.

  • Launchd (macOS)
  • Systemd (Linux)
  • OpenRC (Alpine, Docker)
  • Windows: Startup Registry

Works for any program, written in any language.

Table of Contents

  • Files
  • User Agents & System Daemons
    • Bash, Node, Go, etc
  • Service Management
  • Dry Run
  • Unit File Examples
    • systemd, launchd, openrc


These are the files / directories that are created and/or modified with this install:


This will also generate init system unit files according to your OS:

(use the --dryrun option to learn what serviceman does without making any changes)

  • launchctl (macOS)
  • systemctl (Linux)
  • openrc (Alpine, Docker)
  • The Registry (Windows)
    HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Run <AGENT>

Example: Bash

sudo env PATH="$PATH" \
    serviceman add --system --path="$PATH" -- \
    bash ./ /mnt/data

Example: Node.js

Development Server

pushd ./my-node-app/

sudo env PATH="$PATH" \
    serviceman add --system --path="$PATH" \
    --cap-net-bind -- \
    npx nodemon ./server.js

Production Server

pushd ./my-node-app/

sudo env PATH="$PATH" \
    serviceman add --system --path="$PATH" \
    --cap-net-bind -- \
    npm start

Example: Golang

pushd ./my-go-package/

sudo env PATH="$PATH" \
    serviceman add --system --path="$PATH" \
    -- \
    go run -mod=vendor cmd/my-service/*.go --port 3000
pushd ./my-go-package/
go build -mod=vendor cmd/my-service

sudo env PATH="$PATH" \
    serviceman add --system --path="$PATH" \
    --cap-net-bind -- \
    ./my-service --port 80

How to see all services

serviceman list --system
serviceman list --user
serviceman-managed services:


How to restart a service

You can either add the service again (which will update any changed options), or you can stop and then start any service by its name:

sudo env PATH="$PATH" serviceman stop example-service
sudo env PATH="$PATH" serviceman start example-service

See the (sub)command help

The main help, showing all subcommands:

serviceman --help

Sub-command specific help:

serviceman add --help

Use --dryrun to see the generated launcher config:

sudo env PATH="$PATH" \
    serviceman add --system --path="$PATH" \
    --dryrun -- \
    bash ./ /mnt/data

What a typical systemd .service file looks like

systemd is the init system on cloud-init enabled server distros, and most desktop distros.

Description=example-service systemd-networkd-wait-online.service



ExecStart=/srv/example-service/bin/example-command start
ExecReload=/bin/kill -USR1 $MAINPID

# Allow the program to bind on privileged ports, such as 80 and 443


What a typical init.d service script looks like

openrc is the init system on Alpine and other Docker and container-friendly Linuxes.



name="Example System Daemon"
description="A Service for Logging 'Hello, World', a lot!"
description_checkconfig="Check configuration"
description_reload="Reload configuration without downtime"

# example:
# exampled run --port 1337 --envfile /path/to/env
# exampled check-config --port 1337 --envfile /path/to/env
# exampled reload --port 1337 --envfile /path/to/env

# for setting Config
: ${exampled_opts:="--envfile /root/.config/exampled/env"}

command_args="run --port 1337 $exampled_opts"

depend() {
    need net localmount
    after firewall

checkconfig() {
    ebegin "Checking configuration for $name"
    su ${command_user%:*} -s /bin/sh -c "$command check-config $exampled_opts"
    eend $?

reload() {
    ebegin "Reloading $name"
    su ${command_user%:*} -s /bin/sh -c "$command reload $exampled_opts"
    eend $?

stop_pre() {
    if [ "$RC_CMD" = restart ]; then
        checkconfig || return $?

What a typical launchd .plist file looks like

<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated for serviceman. Edit as you wish, but leave this line. -->
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "">
<plist version="1.0">





Report an Issue Submit Installer Star on GitHub