Deployment
Cast is personal infrastructure: one always-on process, on a machine you trust, bound to localhost by design.
Cast is a single Node process that runs your agents on one machine you control β a laptop, a home server, a small VPS. It binds 127.0.0.1: the dashboard, the chat UI, and the admin surface are reachable only from that machine.
So there are two things to set up: keeping Cast running across crashes and reboots, and reaching your agents while you're away from the machine.
Keep it running
pnpm start runs Cast in the foreground β fine while you're working, but it dies with the terminal. For an always-on agent you want a process supervisor: something that starts Cast on boot, restarts it if it crashes, and captures its logs. Whichever you pick, Cast still needs its container runtime (Apple Container or Docker) already running β the supervisor starts Cast, not the runtime underneath it.
Bundle to a deploy folder
You don't have to run Cast from the repo you cloned. pnpm bundle produces a self-contained directory you can put anywhere and run on its own β point it at a path with --outdir:
pnpm bundle --outdir /opt/cast # also: --name <pm2-name> --port <port>The result needs nothing but Node to run: the bundled server, the web-fetch subprocess, a resolved node_modules/, the manuals, and a ready ecosystem.config.cjs. No pnpm install, no source tree, no package manager at the destination β copy the folder to a server and start it:
cd /opt/cast
node index.js # or: pm2 start ecosystem.config.cjs~/.cast/ by default) β a separate place. So you can delete and re-bundle /opt/cast on every update without touching a single agent. They're two independent axes: where Cast runs from, and where its data lives.One thing to know: the generated ecosystem.config.cjs points the data dir at ~/.cast/ regardless of where you bundled β --outdir moves the code, not the data. To relocate data too (a dedicated volume, say), set CAST_AGENTS_DIR and CAST_CONFIG_DIR β see Runtime options.
pm2 β the recommended path
The ecosystem.config.cjs the bundle wrote is already wired with your data directories and port. From the bundle folder, start it and tell pm2 to bring Cast back on boot:
pm2 start ecosystem.config.cjs
pm2 logs cast # tail the server log
pm2 save # remember the process list
pm2 startup # generate the boot script (run the line it prints)Cast ships no other supervisor config and isn't opinionated about it. If you already run launchd, systemd, or docker with a restart policy, point it at the same bundle β the admin UI's "Restart Cast Server" button just sends the process SIGTERM and lets your supervisor bring it back.
Graceful shutdown
The first SIGTERM starts a graceful drain β Cast stops taking new work and lets open conversations finish, up to about a minute. A second SIGTERM cuts that to a couple of seconds; a third exits immediately. The thing to get right is your supervisor's stop timeout: if it follows SIGTERM with SIGKILL a second or two later (pm2's default is ~1.6s), it severs the drain and can orphan a running container. Give Cast room to finish.
Reach your agents from anywhere
To reach an agent while you're away, talk to it through a chat transport. Wire an agent up to Telegram or Slack and it answers from your phone or a web client, the same way anyone you've let in reaches it.
The transport connects out to the messaging service on Cast's behalf, so the agent is reachable from anywhere while the server stays bound to localhost. Pick one in Transports, then let yourself in on it, the same way anyone else gets in.
What to read next
- Transports β the channels your agents answer on: Telegram, Slack, and the local web client.
- Access β granting yourself and others access on each transport.
- Runtime options β every environment variable the server reads, including
CAST_PORTand the container-runtime selector. - Backups & data β what lives on disk on the machine you're keeping alive, and how to back it up.