Server

Do this once, on the Linux box that will host your queues. It is the same shape as a Sitehoster server (Caddy out front for TLS, a localhost-only Node service behind it), but instead of serving pages it accepts posted tasks, hands them to workers, and keeps each one as a file on disk.

1

Get a box with systemd

Any Linux box with systemd (Debian or Ubuntu); a small VPS is plenty. You need root and outbound network. The installer pulls in Node v20+ and Caddy for you if they are not already present.

2

Run the bootstrap

Pipe it straight to root. It fetches the release bundle, verifies its checksum, and runs the bundle's installer.

curl -fsSL https://taskhoster.org/install.sh | sudo bash
Fetch, verify and install the server in one step.
The installer writes the master token to /etc/taskhoster/token and prints it once. Copy it now, the local package needs it.
3

Or install from the bundle by hand

If you would rather not pipe to bash, download the tarball and its checksum, verify, unpack, and run the installer inside the bundle; the bootstrap does exactly this.

# download the server bundle and its checksum
curl -fLO https://taskhoster.org/downloads/taskhoster.tar.gz
curl -fLO https://taskhoster.org/downloads/taskhoster.tar.gz.sha256

# verify it matches, then unpack
sha256sum -c taskhoster.tar.gz.sha256
tar -xzf taskhoster.tar.gz

# run the installer inside the bundle
sudo ./taskhoster/deploy/install.sh
The manual verify-then-install path the bootstrap automates.
Read the token back any time with sudo cat /etc/taskhoster/token.
4

What the installer sets up

One long-running service, plus Caddy fronting it for TLS:

PieceRole
taskhoster-apiThe API service, bound to 127.0.0.1:8790. It stores queue definitions, keeps every item as a file, serves the producer, worker and management surfaces, and records each task's lifecycle to a durable log for Task Logs. A periodic sweep re-queues lapsed leases, times out old items, and clears retained ones.
CaddyTerminates TLS for every queue domain (on-demand certificates, gated so it only issues for domains that actually have queue definitions), routes each request to taskhoster-api by Host header, and transparently upgrades the WebSocket endpoints.

Data lives under a few directories, all owned by the service user. The Server internals page maps every one of them:

PathHolds
/srv/taskhosterQueue and user definitions: one JSON file per queue in each host's taskhoster-queues/ folder and one per user in its taskhoster-users/ folder, as pushed up by the local package.
/srv/taskhoster-itemsEvery item, one file per item under a state directory (pending / processing / done).
/srv/taskhoster-logsCaddy's access log, and the durable task-event log (and any archived payloads) that Task Logs reads.
/etc/taskhoster/tokenThe master token. The local package authenticates with it; nothing else does.
5

Point a queue domain at the box

A queue host is just a domain (task.example.com) with an A/AAAA record pointing at the server's IP. When a request for that domain arrives, Caddy asks the API whether the domain has any queues before issuing a certificate, so only domains you have actually defined get one. Add the folder for the domain on your machine, define a queue in it, and sync; the first HTTPS request provisions the certificate.

A queue domain must resolve to this box and have at least one queue definition before Caddy will serve it over HTTPS. Sync the definition first, then hit the domain.

Managing the server

The service is a standard systemd unit:

systemctl status taskhoster-api
sudo systemctl restart taskhoster-api
journalctl -u taskhoster-api -f
Check, restart and follow the API service.

Upgrade by re-running the bootstrap (it keeps your token and data). Remove it with deploy/uninstall.sh (add --purge to delete the data too). How it all fits together is on the Server internals page.

Next steps