Deployment
Two ways to run a scaffolded project in production — pick Docker for a container platform, PM2 for a plain VM you manage directly.
Docker
docker compose up --build
Builds the HTTP adapter into a container and starts it alongside Redis.
For production, push the image to any container platform with
REDIS_URL and your model/tool API keys set as environment variables.
PM2
For a bare VM without a container platform, run the HTTP adapter under PM2 instead — it handles restart-on-crash, log capture, and boot persistence:
npm install -g pm2
pm2 start "npx loopengine serve" --name loopengine
pm2 save
pm2 startup # wires PM2 into this machine's own boot sequence
loopengine serve (not dev) is the right command here — it's the
same server with no tsx --watch file-watching, which would otherwise
fight with PM2's own restart supervision. serve also loads .env
automatically, equivalent to --env-file-if-exists=.env, so
ANTHROPIC_API_KEY and friends just need to be in the project's .env
file.
For a checked-in config instead of a one-off command, an
ecosystem.config.cjs in the project root:
module.exports = {
apps: [
{
name: 'loopengine',
script: 'npx',
args: 'loopengine serve',
env: { NODE_ENV: 'production' },
},
],
}
pm2 start ecosystem.config.cjs
pm2 logs loopengine
Set REDIS_URL in .env too once you're running more than one PM2
instance (e.g. PM2's own cluster mode) against the same sessions — see
Basic Configuration for the full environment
variable list.