Skip to content

Deploy a node on Azure

Available now

This is the path for standing up a new OHM environment on Azure Container Apps — your own resource group, storage, API, and (when you want them) background-generation workers. It does not change the public openhardwaremanager.org deployment; that stack is separate.

You need the OHM source tree (the Terraform lives under deploy/terraform/azure/), an Azure subscription you can create resources in, and a published OHM container image.

What gets created

Piece Role
Resource group Isolates the environment so you can tear it down cleanly
Storage account + container Where designs, facilities, and packages live
Container Apps environment Runs the API (and optional worker)
API Container App The OHM service, with a random admin API_KEYS value
Redis + worker (optional) Celery broker and background worker for async generate-from-url
Encryption secrets (production) LLM_ENCRYPTION_SALT / LLM_ENCRYPTION_PASSWORD so admins can store LLM keys in Settings

Prerequisites

  • Azure CLI, logged in (az login) with permission to create resource groups, Container Apps, storage, and (if you enable jobs) Azure Cache for Redis
  • Terraform 1.5 or newer
  • A pullable image, for example touchthesun/openhardwaremanager:<version> — pin an explicit version; don't track latest for anything you depend on

Fastest path: one peer with jobs

The repository includes a minimal single-node example at deploy/terraform/azure/examples/single-peer/. Copy that root (or the ohm_node module usage from deploy/terraform/azure/main.tf) into a working directory, then set at least:

environment = "production"   # provisions LLM encryption secrets
enable_jobs = true           # Redis + Celery worker + JOBS_ENABLED on the API
image       = "touchthesun/openhardwaremanager:<version>"

Apply from that directory:

terraform init
terraform apply

The module outputs the API hostname (fqdn) and a sensitive admin API key. Point a reverse proxy — or the frontend image's API_UPSTREAM_URL — at that HTTPS origin.

What enable_jobs and environment do

Setting Effect
enable_jobs = true Provisions Redis and a no-ingress worker app; sets JOBS_ENABLED, JOB_BROKER_URL, and JOB_RESULT_BACKEND on the API
enable_jobs = false API only (default on the multi-peer federation lab, to control cost). Generate-from-url still works synchronously, but long runs can hit proxy timeouts
environment = "production" Boots with real LLM encryption secrets so Settings → LLM providers can store keys
environment = "test" Fine for short-lived labs; the app will refuse to persist LLM keys against development defaults

Async import behaviour is described in Import from a URL.

Multi-peer federation lab

If you need several regional peers to exercise federation (not a permanent self-host), use the ephemeral lab under deploy/terraform/azure/:

cp deploy/terraform/azure/environments/federation-ephemeral.tfvars.example \
   deploy/terraform/azure/environments/federation-ephemeral.tfvars

# Optional: enable_jobs = true / environment = "production" in the tfvars
# when you want the same job stack on every peer (costs more).

./deploy/terraform/azure/scripts/up.sh

up.sh runs a two-pass apply so peer URLs can be wired into OHM_FEDERATION_MANUAL_PEERS. Tear everything down with ./deploy/terraform/azure/scripts/down.sh when finished — destroy removes the resource group; leftover cost should be ~zero after that completes.

Federation identity for those nodes lives on ephemeral app filesystem: destroy loses it.

After the first apply

  1. Open https://<fqdn>/health and confirm the instance reports healthy storage.
  2. Authenticate with the outputted API_KEYS value (Authorization: Bearer …).
  3. If you set environment = "production", add an LLM provider under Settings → LLM providers (or keep using process env keys).
  4. If you set enable_jobs = true, run a generate-from-url import and confirm the UI shows a progress bar rather than hanging on a long request — see Import from a URL.

Day-to-day self-host expectations (storage, upgrades, access control) are in Run your own node.

What this path is not

  • It is not the CD pipeline for the public OHM instance. That continues to use a separate deploy script against an existing resource group.
  • Turning jobs on for that public stack requires the same Redis + worker wiring there; publishing a new API image alone does not enable background generation.

Operator detail (variable reference, CPU/memory pairs, idle cost policy) stays in deploy/terraform/azure/README.md in the source tree.