Run Bun as a daemon with systemd

systemd is an init system and service manager for Linux. It manages the startup and control of system processes and services.


To run a Bun application as a daemon with systemd, create a service file in /etc/systemd/system/.

terminal
cd /etc/systemd/system
touch my-app.service

Here is a typical service file that runs an application on system start. Use it as a template for your own service. Replace YOUR_USER with the name of the user to run the application as. To run as root, replace YOUR_USER with root and /home/YOUR_USER with /root (root's home directory). For security reasons, we don't recommend running as root.

Refer to the systemd documentation for details on each setting.

my-app.service
[Unit]
# describe the app
Description=My App
# start the app after the network management stack has started
# (this does not wait for the network to be up, see https://systemd.io/NETWORK_ONLINE)
After=network.target

[Service]
# usually you'll use 'simple'
# one of https://www.freedesktop.org/software/systemd/man/systemd.service.html#Type=
Type=simple
# which user to use when starting the app
User=YOUR_USER
# path to your application's root directory
WorkingDirectory=/home/YOUR_USER/path/to/my-app
# the command to start the app
# requires absolute paths
ExecStart=/home/YOUR_USER/.bun/bin/bun run index.ts
# restart policy
# one of {no|on-success|on-failure|on-abnormal|on-watchdog|on-abort|always}
Restart=always

[Install]
# start the app automatically
WantedBy=multi-user.target

If your application starts a webserver, non-root users cannot listen on ports 80 or 443 by default. To allow Bun to listen on these ports when run by a non-root user, use the following command. The command requires sudo permissions. This step isn't necessary when running as root.

terminal
setcap CAP_NET_BIND_SERVICE=+eip /home/YOUR_USER/.bun/bin/bun

The command attaches the capability to the bun binary itself. Replacing the binary, for example with bun upgrade, removes the capability. Re-run the command after upgrading. Alternatively, add AmbientCapabilities=CAP_NET_BIND_SERVICE to the [Service] section of the service file instead.


With the service file configured, enable the service. Once enabled, it starts automatically on reboot. Enabling the service requires sudo permissions.

terminal
systemctl enable my-app

To start the service without rebooting, start it manually.

terminal
systemctl start my-app

Check the status of your application with systemctl status. If the app started successfully, the output looks like this:

terminal
systemctl status my-app
● my-app.service - My App
     Loaded: loaded (/etc/systemd/system/my-app.service; enabled; preset: enabled)
     Active: active (running) since Thu 2023-10-12 11:34:08 UTC; 1h 8min ago
   Main PID: 309641 (bun)
      Tasks: 3 (limit: 503)
     Memory: 40.9M
        CPU: 1.093s
     CGroup: /system.slice/my-app.service
             └─309641 /home/YOUR_USER/.bun/bin/bun run index.ts

To update the service, edit the service file, then reload the daemon.

terminal
systemctl daemon-reload

For a complete guide to service unit configuration, see the systemd.service documentation. Or use this cheatsheet of common commands:

terminal
systemctl daemon-reload # tell systemd that some files got changed
systemctl enable my-app # enable the app (to allow auto-start)
systemctl disable my-app # disable the app (turns off auto-start)
systemctl start my-app # start the app if is stopped
systemctl stop my-app # stop the app
systemctl restart my-app # restart the app