Process manager deployment
For deployments without container orchestration — bare-metal, VMs, smaller setups — process managers like systemd (Linux) or PM2 (Node-focused) supervise actor-ts processes.
systemd
Section titled “systemd”[Unit]Description=actor-ts applicationAfter=network-online.targetWants=network-online.target
[Service]Type=execUser=actor-tsGroup=actor-tsWorkingDirectory=/opt/actor-tsEnvironment="NODE_ENV=production"EnvironmentFile=/etc/envExecStart=/usr/bin/bun /opt/dist/main.jsRestart=on-failureRestartSec=10sTimeoutStopSec=60sKillSignal=SIGTERMStandardOutput=journalStandardError=journal
[Install]WantedBy=multi-user.targetsudo systemctl daemon-reloadsudo systemctl enable actor-tssudo systemctl start actor-ts
sudo systemctl status actor-tssudo journalctl -u actor-ts -fKey directives
Section titled “Key directives”| Directive | Purpose |
|---|---|
Restart=on-failure | Auto-restart on non-zero exit. Combined with RestartSec=10s for backoff. |
TimeoutStopSec=60s | How long systemd waits after SIGTERM before SIGKILL. Sized to match coordinated-shutdown phase budget. |
KillSignal=SIGTERM | The graceful-shutdown signal. Triggers |
| the framework’s coordinated-shutdown hooks. | |
User/Group | Run as non-root. Always. |
StandardOutput=journal | Logs flow to journald — collected centrally. |
Cluster across systemd hosts
Section titled “Cluster across systemd hosts”# /etc/env on each host:ACTOR_TS_HOSTNAME=10.0.0.5 # this host's IPACTOR_TS_PORT=2552ACTOR_TS_SEEDS=10.0.0.5:2552,10.0.0.6:2552,10.0.0.7:2552Three hosts; each knows the full seed list. Add another host later by appending to the seed list and rolling out.
For dynamic-size deployments (autoscaling VMs), use the DNS seed provider backed by your DNS-SD provider (Consul, Eureka, etc.).
Rolling restart on systemd
Section titled “Rolling restart on systemd”# Stop one node at a time, wait for cluster to converge, then next:ssh host-1 'sudo systemctl restart actor-ts'# Wait for re-up:ssh host-2 'curl http://localhost:8558/ready'# Then:ssh host-2 'sudo systemctl restart actor-ts'# ...Manual but straightforward. Tooling like Ansible or Salt automates the orchestration.
PM2 is Node-focused; works well for actor-ts on Node (Bun has native support but doesn’t natively integrate with PM2’s binary).
{ "apps": [ { "name": "actor-ts", "script": "dist/main.js", "exec_mode": "fork", "instances": 1, "max_memory_restart": "2G", "kill_timeout": 60000, "env_production": { "NODE_ENV": "production", "ACTOR_TS_PORT": "2552" }, "error_file": "/var/log/error.log", "out_file": "/var/log/out.log" } ]}pm2 start ecosystem.config.json --env productionpm2 startup # generate systemd config so PM2 starts on bootpm2 save # persist current stateKey options
Section titled “Key options”| Option | Purpose |
|---|---|
exec_mode: "fork" | One process per actor-ts node. Don’t use cluster-mode (PM2’s cluster-mode confuses cluster semantics). |
instances: 1 | One instance. Multiple actor-ts in cluster-mode would each try to be the same node, breaking things. |
kill_timeout: 60000 | SIGTERM → SIGKILL window. Match coordinated-shutdown. |
max_memory_restart | Auto-restart if memory exceeds. Combined with metrics to alert before kill. |
Avoiding common pitfalls
Section titled “Avoiding common pitfalls”When to use process managers vs K8s
Section titled “When to use process managers vs K8s”| Scenario | Choice |
|---|---|
| ≤ 5 VMs, stable, manual operations | systemd / PM2 |
| Dynamic scaling, ≥ 10 VMs | Kubernetes |
| Bare-metal with hardware affinity | systemd |
| Multi-cloud / on-prem hybrid | Kubernetes (or HashiCorp Nomad) |
Process managers are lower abstraction — fewer features but fewer dependencies. For a single-machine prod or a small VM fleet, the K8s overhead isn’t worth it.
Where to next
Section titled “Where to next”- Kubernetes deployment — the K8s alternative.
- Docker Compose — for local multi-node setups.
- Coordinated shutdown —
what your
TimeoutStopSec/kill_timeoutneeds to allow for. - Operations overview — production checklist.