Deploy an HTTP container with YAML

An HTTP container is a long-running service that accepts incoming requests on a port and gets a hostname, TLS, autoscaling, rate limiting, IP allow/deny, and basic auth out of the box. Pick this type when you're deploying an API, a web app, or anything else that fronts traffic.

Updated 23 Jun 20263 min read

An HTTP container is a long-running service that accepts incoming requests on a port and gets a hostname, TLS, autoscaling, rate limiting, IP allow/deny, and basic auth out of the box. Pick this type when you're deploying an API, a web app, or anything else that fronts traffic.

This guide walks through the full YAML shape for an HTTP container. For the same deployment driven from the shell, see Deploy an HTTP container with flags.

Minimal example

kind: container
project: my-project
handle: web-api
name: Web API
image: ghcr.io/myorg/api:v1.0.0
type: http
regions:
  - falkenstein-1
 
workload:
  cpu: "500"
  memory: "512"
  port: "8080"
  healthcheck: /healthz

Apply it:

reis apply -f web-api.yml

That's the entire path from "empty file" to "production HTTP container."

Anatomy of the YAML

The top-level keys identify the container and route it; the workload group covers runtime sizing and the HTTP-specific port and health check.

kind: container
project: my-project                # the project handle this container lives under
handle: web-api                    # immutable identifier — Reis looks this up to update later
name: Web API                      # display name in the console
image: ghcr.io/myorg/api:v1.0.0    # image reference with tag
type: http                         # immutable after create
registry: ghcr                     # registry handle if the image is private
regions:
  - falkenstein-1
  - virginia-1                     # multi-region by listing more regions
 
workload:
  cpu: "500"                       # min CPU in millicores
  memory: "512"                    # min memory in MB
  port: "8080"                     # the port your app listens on
  healthcheck: /healthz            # HTTP path that returns 200 when healthy
  env:                             # environment variables as plain key/value
    NODE_ENV: production
    LOG_LEVEL: info
  secrets:                         # ENV_VAR_NAME → secret-handle
    DB_PASSWORD: db-password
    API_KEY: api-key

Autoscaling

Set max_replicas to enable autoscaling. The minimum is replicas; autoscaling kicks in between the two based on CPU and memory targets.

scaling:
  replicas: "2"
  max_replicas: "8"
  autoscalingtargetcpu: "70"       # percent of requested CPU
  autoscalingtargetmemory: "80"    # percent of requested memory

If you don't include max_replicas, the container runs at exactly replicas instances.

Custom hostnames

By default, an HTTP container gets a Bahriya-issued hostname. Add your own:

networking:
  domains:
    - hostname: app.example.com
      wwwredirect: true            # serves www.app.example.com → app.example.com

The platform issues a TLS certificate via Let's Encrypt automatically once you point the DNS record.

Observability

Expose Prometheus metrics so the platform scrapes them:

observability:
  prometheus_port: "9090"
  prometheus_path: /metrics

Security

Rate limiting and IP allow/deny lists sit under security:

security:
  rate_limiting:
    ratelimitingenabled: true
    ratelimitingrequestsperminute: 60
  basic_auth:
    - username: ops
      password: <bcrypt-or-plaintext>

Field reference

YAML pathMaps toNotes
workload.portcontainer portrequired for HTTP
workload.healthcheckhealth check pathrequired for HTTP, default /healthz
workload.cpumin CPU (millicores)default 350
workload.memorymin memory (MB)default 150
workload.envenvironment variableskey/value map
workload.secretsinjected secretsENV_NAME → secret-handle
scaling.replicasmin instancesdefault 1
scaling.max_replicasmax instancesenables autoscaling
networking.domainscustom hostnamesTLS issued automatically
observability.prometheus_portmetrics portenables scraping
observability.prometheus_pathmetrics pathdefault /metrics

For the complete list of every group and field, see the YAML mode reference.

Updating an HTTP container

Re-apply the same file with any changes:

reis apply -f web-api.yml

Reis looks up the container by handle, updates only the fields whose values changed, and leaves everything else alone.