> ## Documentation Index
> Fetch the complete documentation index at: https://ekso.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Render

> Deploy Ekso to Render — managed Postgres, web service, background worker, plus your own S3-compatible bucket for attachments. Cloud-platform install path.

Render is the cloud-platform install path: managed Postgres, web service for the API, background worker, and your own S3-compatible bucket for uploaded attachments. One Blueprint provisions everything; redeploys pull the latest images automatically.

<Note>
  Running on your own machine instead? Use [Docker - full stack](/guide/install/quickstart) for the bundled Postgres path or [Docker - bring your own database](/guide/install/byod) if you already have a Postgres / SQL Server you want Ekso to share. The Render path is a separate target — same code, different operational shape.
</Note>

## Why this differs from the Docker bundles

The Docker bundles mount a shared host folder for uploaded attachments — the `app` and `worker` containers both read and write the same directory. Render's persistent disks are bound to a single service, so that pattern doesn't work there.

This install path uses Ekso's S3 storage backend instead: attachments live in your bucket, the `app` and `worker` services read and write it independently, and durability is delegated to your bucket provider's versioning and lifecycle rules. The trade-off is one extra moving part (the bucket) for the cloud-platform shape that Render's pricing model is built around.

## Prerequisites

* **A Render account** with billing set up. The smallest viable shape is one Starter web service + one Starter worker + Basic-1gb Postgres — roughly **\$37–43/month** at current pricing (table below).
* **A GitHub account** to push `render.yaml` to a repo Render can read.
* **An S3-compatible bucket** with an access key. Cloudflare R2 is the recommended default — zero egress fees, S3-compatible, and what `render.yaml` defaults to. AWS S3, Backblaze B2, and MinIO all work too. See [bucket setup](#bucket-setup) below.
* **A free Ekso license.** Fetch one at [ekso.app/get-started](https://ekso.app/get-started). Free tier is 3 users, no credit card.

## Install

Two ways to start. Both produce the same Render Blueprint and end at the same place — pick whichever fits your situation.

| Path                        | When to pick it                                                                                                                                                                                            |
| --------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **[Automatic](#automatic)** | One-click via Render's Deploy button. Fastest path; Render reads the Blueprint from Ekso's public repo. Best for evaluation and quick spin-ups.                                                            |
| **[Manual](#manual)**       | Download the Blueprint and push it to your own GitHub repo. You own the YAML — Ekso's future updates don't reach your install unless you re-download. Best for production deploys you'll manage long-term. |

### Automatic

[![Deploy to Render](https://render.com/images/deploy-to-render-button.svg)](https://render.com/deploy?repo=https://github.com/EksoApp/Deploy-to-Render)

1. Click the button above. Render takes you to its Blueprint preview screen, with the source set to [`EksoApp/Deploy-to-Render`](https://github.com/EksoApp/Deploy-to-Render) (the public canonical mirror of `render.yaml`).
2. Sign in to Render if you aren't already, then approve.
3. Continue with the [shared steps](#after-render-connects) below.

<Note>
  **Heads-up:** when you use the automatic path, your install tracks Ekso's public Blueprint. If we update `render.yaml` (e.g. to bump a Postgres tier or pin a new image version), Render will sync the change on your next redeploy. That's usually a feature (security patches, plan-name fixes — like the `starter` → `basic-1gb` rename Render did in late 2025), but if you'd rather pin, use the [manual](#manual) path instead.
</Note>

### Manual

1. **Download** [`ekso-render.zip`](https://ekso.app/download/ekso-render.zip). It contains:

   | File          | Purpose                                                 |
   | ------------- | ------------------------------------------------------- |
   | `render.yaml` | The Blueprint: Postgres + web + worker + env-var config |
   | `README.md`   | Bundle-local quick reference (frozen at download time)  |

2. **Push `render.yaml` to a GitHub repo you own:**

   ```bash theme={null}
   curl -L https://ekso.app/download/ekso-render.zip -o ekso-render.zip
   unzip ekso-render.zip -d ekso-render && cd ekso-render
   git init && git add render.yaml README.md
   git commit -m "Ekso on Render"
   git remote add origin git@github.com:YOU/ekso-render.git
   git push -u origin main
   ```

3. **In Render:** **New +** → **Blueprint** → connect the repo from step 2.

4. Continue with the [shared steps](#after-render-connects) below.

### After Render connects

Both paths converge here.

1. **No prompts to fill.** The Blueprint declares no `sync: false` env vars — `Secrets__JwtKey` and `Secrets__EncryptionKey` auto-mint at first deploy via `generateValue: true`, and `Database__TransactConnection` / `Database__MartConnection` are wired from the Postgres resource via `fromDatabase`. Click **Apply Blueprint** and Render goes straight to provisioning.

2. **Wait \~2 minutes.** Render provisions the database first (web + worker depend on it), then builds and starts both services in parallel. The Blueprint progress page shows resources moving from queued (⏳) to deployed (✓):

   <Frame>
     <img src="https://mintcdn.com/eksoinc/_CPbzAO3w9Gww3za/images/install/render/deploy-progress.png?fit=max&auto=format&n=_CPbzAO3w9Gww3za&q=85&s=8fd4dcb2e88bdfe051975baf347fa803" alt="Render Blueprint deploy progress: env group complete, database provisioning, web and worker queued" width="1048" height="398" data-path="images/install/render/deploy-progress.png" />
   </Frame>

3. **Open `https://<your-api>.onrender.com/startup`** to land in the [first-run wizard](/guide/install/first-run).

4. **Configure storage and email post-install.** Once you're logged in as admin:

   * **Settings → System → Storage** — pick **S3-compatible**, paste your bucket details. See [Configure storage and email](/guide/manage/storage-and-email) for provider-specific recipes (R2 is the recommended default — zero egress, S3-compatible).
   * **Settings → Mail → Outbound** — pick **Resend** (paste API key) or **SMTP** (host + credentials + from-address). Required before any email-dependent flow (password reset, two-factor login, new-user invitations) will succeed.

   Both sets of credentials are encrypted at rest in the database using `Secrets__EncryptionKey`, so they never appear in the Render dashboard environment panel.

The JWT signing key and encryption key are both auto-generated by Render at first deploy and preserved across redeploys. You don't need to set or rotate them manually — treat the Render dashboard environment panel like a password file once the deploy is live.

## What's running

Three Render resources come up:

| Resource      | Type                                                     | Role                                                |
| ------------- | -------------------------------------------------------- | --------------------------------------------------- |
| `ekso-api`    | Web Service (Docker image `eksoapp/app:latest`)          | REST API + UI behind Render's HTTPS edge            |
| `ekso-worker` | Background Worker (Docker image `eksoapp/worker:latest`) | Background jobs — email, ticketing, vector indexing |
| `ekso-db`     | Managed Postgres 18 with pgvector                        | OLTP + reporting database                           |

Plus your bucket (external to Render) for uploaded attachments. The bucket lives in your cloud provider's account, not Render's — destroying the Render workspace doesn't touch it, and the access key in Render's dashboard is the only thing that lets the API talk to it.

For the full data layout, backup story, and restore procedures across both `Local` and `S3` storage backends, see [Data management](/guide/manage/data-management#s3-storage).

## Bucket setup

Configure the bucket post-install via **Settings → System → Storage** in the running app. Provider-specific recipes (Cloudflare R2 — recommended default, AWS S3, Backblaze B2, MinIO) and the wrong-page warning for R2 token creation are in [Configure storage and email](/guide/manage/storage-and-email).

### Recommended bucket settings (any provider)

* **Versioning enabled** — recovers a deleted or overwritten object. Equivalent to the Docker bundles' 14-day storage snapshots, but at object granularity.
* **Lifecycle rule** auto-expiring non-current versions after 30 or 90 days so versioned data doesn't accumulate forever.

See [Data management → Attachment durability](/guide/manage/data-management#attachment-durability) for restore patterns.

## Cost shape

Approximate, at the time of writing — check [Render pricing](https://render.com/pricing) for canonical numbers:

| Resource                          | Plan             | Approx / month |
| --------------------------------- | ---------------- | -------------- |
| Postgres                          | Basic-1gb        | \$23.50        |
| Web service (`ekso-api`)          | Starter          | \$7            |
| Background worker (`ekso-worker`) | Starter          | \$7            |
| Cloudflare R2 storage             | First 10 GB free | \$0–5          |
| Cloudflare R2 egress              | Free, all tiers  | \$0            |
| **Total**                         |                  | **\~\$37–43**  |

AWS S3 adds an egress component (data leaving the bucket); B2 sits between R2 and AWS. Render's bandwidth from the web service is included in the Starter plan up to 100 GB/month.

## Backups

Render Postgres takes **daily automatic backups with point-in-time recovery** on every paid plan — there's nothing to wire up. Restore from the Render dashboard: Database → Recovery → pick a timestamp.

Attachment durability is your bucket provider's job. Configure versioning plus a lifecycle rule (above), and you're covered for the same kinds of mistakes the Docker bundle's `backup` sidecar covers — accidental deletes, overwrites, ransomware. See [Data management → S3 storage](/guide/manage/data-management#s3-storage).

## Pointing it at a real domain

Render assigns each service a `<service>.onrender.com` hostname with HTTPS terminated at the edge — fine for evaluation. For production, add a custom domain in the Render dashboard: Service → Settings → Custom Domain. Render auto-provisions a Let's Encrypt certificate.

Use that domain as the **public URL** during the [first-run wizard](/guide/install/first-run).

## Updating

Render redeploys when you push to your `render.yaml` repo, or you can trigger a manual redeploy from the dashboard to pull the latest `eksoapp/app:latest` and `eksoapp/worker:latest` images.

To pin a specific version, change the `image.url` in `render.yaml` from `docker.io/eksoapp/app:latest` to `docker.io/eksoapp/app:1.X` and push. Same for `eksoapp/worker`.

Release cadence and version pinning: [Upgrading](/guide/manage/upgrading).

## Tearing it down

In the Render dashboard, deleting the Blueprint deletes all three resources (web, worker, database). Your bucket is in your own cloud account — Render can't touch it; delete it yourself if you don't need the data.

<Warning>
  Deleting the database is permanent. Take a Render manual backup (Database → Recovery → **Take backup**) and download it before deletion if there's any chance you'll want the data back.
</Warning>

## See also

* [Configure storage and email](/guide/manage/storage-and-email) — admin-UI walkthrough for the S3 bucket + Resend/SMTP setup that lands post-install
* [Configuration reference](/guide/install/configuration) — `ekso.json` (Secrets + Database) and the env-var override mechanisms Render uses
* [Data management → S3 storage](/guide/manage/data-management#s3-storage) — backup and restore patterns when attachments live in a bucket
* [First-run wizard](/guide/install/first-run) — what to expect at `/startup` on first boot
* [Upgrading](/guide/manage/upgrading) — release cadence, version pinning, rollback
