Deploy a worker with YAML
A worker container is a long-running background process with no public network exposure. Use it for queue consumers, schedulers that live inside the application, stream processors, and anything else that runs continuously but isn't reachable from outside the project.
A worker container is a long-running background process with no public network exposure. Use it for queue consumers, schedulers that live inside the application, stream processors, and anything else that runs continuously but isn't reachable from outside the project.
This guide walks through the worker YAML shape. For the flag-mode equivalent, see Deploy a worker with flags.
Minimal example
kind: container
project: my-project
handle: queue-worker
name: Queue Worker
image: ghcr.io/myorg/app:v1.0.0
type: worker
regions:
- falkenstein-1
workload:
cpu: "200"
memory: "256"
command: [/usr/bin/php]
args: [artisan, queue:work, --tries=3]Apply it:
reis apply -f queue-worker.ymlHow workers differ from HTTP containers
Same kind: container, same commands, but:
- No port, no health check — workers aren't reachable on a public address, so neither field applies.
commandandargsoverride the image's ENTRYPOINT and CMD. Use these to point the same image at different runners (queue worker vs scheduler vs stream consumer).- Hostnames, custom domains, basic auth, rate limiting — none of these apply.
- Autoscaling still works — based on CPU/memory.
Anatomy
kind: container
project: my-project
handle: queue-worker
name: Queue Worker
image: ghcr.io/myorg/app:v1.0.0
type: worker
registry: ghcr
regions:
- falkenstein-1
workload:
cpu: "200"
memory: "256"
env:
QUEUE_CONNECTION: redis
LOG_LEVEL: info
secrets:
DB_PASSWORD: db-password
REDIS_URL: redis-url
command:
- /usr/bin/php
args:
- artisan
- queue:work
- --tries=3
- --max-time=3600
scaling:
replicas: "2"
max_replicas: "6"Command vs args
command overrides the image's ENTRYPOINT; args overrides CMD. One token per list entry — Reis doesn't word-split for you, and that's deliberate: a token like --max-time=3600 stays a single argument instead of being split on =.
If you omit both, the image's own ENTRYPOINT/CMD run as built.
Observability
Workers can still expose Prometheus metrics:
observability:
prometheus_port: "9090"
prometheus_path: /metricsThe metrics endpoint isn't reachable externally — the platform scrapes it from the worker's own network.
Field reference (worker-specific)
| YAML path | Maps to | Notes |
|---|---|---|
workload.command | ENTRYPOINT override | list of tokens |
workload.args | CMD override | list of tokens |
workload.cpu / workload.memory | resources | same as any container |
workload.env / workload.secrets | runtime config | same shape as HTTP |
scaling.replicas / scaling.max_replicas | autoscaling | same as HTTP |
Worker containers ignore workload.port, workload.healthcheck, and every field under networking and security.
Updating a worker
Re-apply the same file with any changes:
reis apply -f queue-worker.ymlReis matches by handle and updates only the changed fields.
Related
- Deploy a worker with flags — flag-mode equivalent
- Deploy an HTTP container with YAML — same
kind: container, different type - Deploy a cron job with YAML — for scheduled runs instead of continuous