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.

Updated 23 Jun 20262 min read

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.yml

How 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.
  • command and args override 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: /metrics

The metrics endpoint isn't reachable externally — the platform scrapes it from the worker's own network.

Field reference (worker-specific)

YAML pathMaps toNotes
workload.commandENTRYPOINT overridelist of tokens
workload.argsCMD overridelist of tokens
workload.cpu / workload.memoryresourcessame as any container
workload.env / workload.secretsruntime configsame shape as HTTP
scaling.replicas / scaling.max_replicasautoscalingsame 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.yml

Reis matches by handle and updates only the changed fields.