---
title: "Workers"
description: "Long-running PM2 processes deployed alongside the web app."
---
A backend can run additional long-running processes alongside the web server. PM2 supervises all of them under one deployment.
```ts
export default shipnode
.backend()
.ssh({ host: '203.0.113.10', user: 'deploy' })
.deployTo('/var/www/api')
.pm2('api', { instances: 2 })
.port(3000)
.worker({ name: 'mailer', command: 'node dist/worker.js' })
.worker({ name: 'cron', command: 'node dist/cron.js', env: { JOB: 'cleanup' } })
.build();
```
## Targeting one process
By default `logs`, `restart`, `stop` operate on the whole deployment. Use `--process ` to target one (use the short name from your config):
```bash
npx shipnode logs --process mailer
npx shipnode restart --process cron
```
## PM2 naming
PM2 has a flat global namespace, so two deployments with a `worker` named `mailer` on the same host would collide. ShipNode prefixes worker names with the deployment namespace when registering with PM2.
A config with `.pm2('api')` + `.worker({ name: 'mailer' })` appears in `pm2 list` as `api` and `api-mailer`. You always use the short name (`mailer`) in shipnode commands.
## Worker-only deployments
Omit `.port()` and `.domain()` to deploy a worker-only app â useful for queue consumers or cron runners:
```ts
export default shipnode
.backend()
.ssh({ host: '203.0.113.10', user: 'deploy' })
.deployTo('/var/www/queue-runner')
.worker({ name: 'jobs', command: 'node dist/worker.js' })
.build();
```