Skip to content

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.

/etc/systemd/system/actor-ts.service
[Unit]
Description=actor-ts application
After=network-online.target
Wants=network-online.target
[Service]
Type=exec
User=actor-ts
Group=actor-ts
WorkingDirectory=/opt/actor-ts
Environment="NODE_ENV=production"
EnvironmentFile=/etc/env
ExecStart=/usr/bin/bun /opt/dist/main.js
Restart=on-failure
RestartSec=10s
TimeoutStopSec=60s
KillSignal=SIGTERM
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
Terminal window
sudo systemctl daemon-reload
sudo systemctl enable actor-ts
sudo systemctl start actor-ts
sudo systemctl status actor-ts
sudo journalctl -u actor-ts -f
DirectivePurpose
Restart=on-failureAuto-restart on non-zero exit. Combined with RestartSec=10s for backoff.
TimeoutStopSec=60sHow long systemd waits after SIGTERM before SIGKILL. Sized to match coordinated-shutdown phase budget.
KillSignal=SIGTERMThe graceful-shutdown signal. Triggers
the framework’s coordinated-shutdown hooks.
User/GroupRun as non-root. Always.
StandardOutput=journalLogs flow to journald — collected centrally.
# /etc/env on each host:
ACTOR_TS_HOSTNAME=10.0.0.5 # this host's IP
ACTOR_TS_PORT=2552
ACTOR_TS_SEEDS=10.0.0.5:2552,10.0.0.6:2552,10.0.0.7:2552

Three 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.).

Terminal window
# 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).

ecosystem.config.json
{
"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"
}
]
}
Terminal window
pm2 start ecosystem.config.json --env production
pm2 startup # generate systemd config so PM2 starts on boot
pm2 save # persist current state
OptionPurpose
exec_mode: "fork"One process per actor-ts node. Don’t use cluster-mode (PM2’s cluster-mode confuses cluster semantics).
instances: 1One instance. Multiple actor-ts in cluster-mode would each try to be the same node, breaking things.
kill_timeout: 60000SIGTERM → SIGKILL window. Match coordinated-shutdown.
max_memory_restartAuto-restart if memory exceeds. Combined with metrics to alert before kill.
ScenarioChoice
≤ 5 VMs, stable, manual operationssystemd / PM2
Dynamic scaling, ≥ 10 VMsKubernetes
Bare-metal with hardware affinitysystemd
Multi-cloud / on-prem hybridKubernetes (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.