What bosun add generates, the shipped reference units, and optional socket activation.
sudo bosun add <app-name> writes and enables two systemd units per app automatically — you normally never write one by hand. This doc covers what gets generated, the shipped reference copies, and optional socket activation.
Standalone mode (no argus-tty):
User=webapp-svc Group=webappsbelow is actuallyUser=<your account> Group=bosun-apps— the generated units already have the right names for your host. See standalone.md.
bosun add generateswrite_unit() in bin/add.sh writes both units directly (not from a template file):
/etc/systemd/system/puma-<app>.service
/etc/systemd/system/sidekiq-<app>.service
Both run as User=webapp-svc Group=webapps, WorkingDirectory=<app>/current, EnvironmentFile=-<app>/shared/.env, Restart=on-failure. They're enabled but not started by add — there's no release yet (current doesn't exist until the first bosun deploy).
Restart both at once with bosun restart <app-name> (added alongside this doc — admin/deployer tier, same as deploy/cleanup), or individually via the already-whitelisted sudo systemctl {start,stop,restart} <unit>.
Two files ship at /usr/lib/bosun/deploy/:
puma-app_name.service.sample — an annotated copy of what bosun add already generates. Useful as a reference, or to hand-create a unit outside the normal bosun add flow.puma-app_name.socket.sample — optional socket-activation unit (see below).Both are templates with the literal placeholder app_name — replace every occurrence with your actual app name before using either by hand.
Puma's own log redirect, and why the generated unit doesn't also redirect stdout/stderr: config/puma.rb (the app's own file) already does its own stdout_redirect to shared/log/puma.log. If the systemd unit also set StandardOutput=/StandardError= to that same path, systemd would create/open it as root before dropping privileges to User=webapp-svc, and Puma's later reopen of that now-root-owned file would fail with EACCES. Leave those unset (defaults to the journal) and let Puma own the file itself. Unit-level events (start/stop/restart, failures to launch) still show up in the journal regardless:
sudo journalctl -t puma-<app> -f
puma-app_name.socket.sample lets systemd own the Unix socket file (shared/tmp/sockets/puma.sock) and hand Puma an already-open file descriptor, instead of Puma creating/binding the socket itself at boot. Buys zero dropped connections across a Puma restart. To use it:
puma-app_name.socket.sample to /etc/systemd/system/puma-<app>.socket, replacing app_name.bind "unix://..." line in the app's config/puma.rb — with socket activation, systemd owns that path; Puma trying to bind it too defeats the point (and can fail outright).Requires=puma-<app>.socket under [Unit] in puma-<app>.service so the socket is always up before Puma starts.sudo systemctl daemon-reloadsudo systemctl enable --now puma-<app>.socket (starting just the .socket activates on first connection; start both units if you don't need on-demand activation).This is entirely optional — config/puma.rb binding its own socket directly (the default bosun add leaves in place) is simpler and fine for most setups; socket activation only matters if dropped connections during a Puma restart are a real concern for this app.