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

# Get Started on Azure (Closed Beta)

> Deploy Velt full self-hosting into your own Azure subscription. Hand the install guide to an AI coding agent, answer the inputs up front, and complete the human steps.

You don't run this deployment by hand. An AI coding agent follows the [Install guide](https://velt.dev/docs/self-hosting/full/azure/install.md) and stops to ask you whenever a step needs a person.

Budget 60 to 90 minutes of wall clock time, plus the human steps. Most of that is waiting on the AKS and PostgreSQL apply, pod startup, and the first Application Gateway sync.

> [!NOTE]
>
> Full self-hosting on Azure is in **closed beta**. Contact us before your first install. New to full self-hosting? Read the [Overview](https://velt.dev/docs/self-hosting/full/overview.md) first.

## What runs in your subscription

Azure runs Velt's portable stack: Kubernetes and PostgreSQL instead of Cloud Run and Firebase. Everything is served from one public host, and nothing calls a Velt-owned host at runtime.

| Piece | What you run |
| - | - |
| **Substrate** | An AKS cluster, Azure Database for PostgreSQL Flexible Server (private, customer-managed key), Key Vault, a Blob storage account, managed identities, and an Application Gateway ingress. Created by Velt's signed Terraform module. |
| **Application** | Velt's signed gateway, workers, and migrate images plus an in-cluster Valkey cache, installed from Velt's signed Helm chart and pulled only from your own Azure Container Registry. |
| **Console** | The Velt admin console on the same host, signing in through Entra ID or any OIDC provider. |
| **SDK** | The Velt client SDK bundle served from the same host, so your pages download nothing from Velt. |
| **First workspace** | An API key, an organization, and an admin user seeded into the deployment's own database. |

Azure commercial (`AzureCloud`) and Azure Government (`AzureUSGovernment`) use the same commands. The install guide calls out the few values that differ.

## 1. Check the prerequisites

* An Azure subscription where the deploying identity holds **Owner**, or **Contributor + User Access Administrator**. Contributor alone can't create the Key Vault grant the module needs.
* An Entra tenant where you (or an admin) can create a single-page app registration for console sign-in and a security group for cluster admins.
* vCPU quota in your region. The default footprint (3 × `Standard_D4ds_v5`) needs at least 16 regional and family vCPUs. The small footprint (3 × `Standard_D2ds_v4`) fits a 10-vCPU subscription.
* A region where PostgreSQL Flexible Server is offered to your subscription. The agent checks this before the apply.
* Velt's release registry address. Email [support@velt.dev](mailto:support@velt.dev) to get it.
* Someone available to run an AI coding agent for the duration.

**Tools on the machine that runs the agent:** Azure CLI 2.60+, Terraform 1.6+, Helm 3.17+ (or 4.x), `kubectl`, Azure's `kubelogin`, `cosign`, `oras`, Node 18+, Docker, `curl`, `python3`, `openssl`, `jq`, and `dig`. The agent runs the release's preflight check before it starts and stops at the first problem: tools, permissions, region, quota, or name availability.

> [!WARNING]
>
> Install Azure's `kubelogin` with `brew install Azure/kubelogin/kubelogin`. `brew install kubelogin` installs an unrelated tool with the same name that the install can't use.

## 2. Decide your inputs

Decide these once, up front. The agent asks for all of them before it starts.

| Input | Meaning |
| - | - |
| `SUBSCRIPTION_ID` / `TENANT_ID` / `CLOUD` | Where to deploy: `AzureCloud` or `AzureUSGovernment` |
| `LOCATION` | Azure region for both AKS and PostgreSQL |
| `RESOURCE_GROUP` / `DEPLOYMENT_NAME` | Resource group, and a 3 to 16 character slug that prefixes every resource |
| `PUBLIC_HOST` | The one public hostname for the API, WebSocket, console, and SDK |
| `CONSOLE_AUTH_ISSUER` / `CONSOLE_AUTH_CLIENT_ID` | The console's OIDC provider (Entra ID or any OIDC provider) |
| `ACR_NAME` | The container registry that holds the verified Velt images |
| AKS admin group + operator egress CIDR | Who administers the cluster, and from which network |
| API key, organization ID, admin user ID hash, console admin email | The first workspace |
| Allowed domains + app origins | Where your app runs (identify and CORS) |
| TLS path | Your own certificate (default), a Key Vault certificate, or cert-manager with ACME |

> [!WARNING]
>
> A torn-down deployment's Key Vault reserves `DEPLOYMENT_NAME` for 90 days. Add a suffix (`acmevelt01`) rather than reusing a name.

Optional features (REST API, comment attachments, advanced webhooks, console SAML sign-in and SCIM, FIPS mode, metric alerts) are off by default. You can turn each on later with a `helm upgrade`. The [agent instructions](https://velt.dev/docs/self-hosting/full/azure/install.md) list every input in full.

## 3. Start your agent

Copy the agent instructions from the [Install guide](https://velt.dev/docs/self-hosting/full/azure/install.md) and paste them into your AI coding agent. Then start it with a prompt like this, filled in with your inputs:

```text theme={null}
You are deploying Velt full self-hosting into our own Azure subscription.

Follow the Velt Install Guide (Azure) I gave you, phase by phase. Do not
invent your own procedure.

Inputs:
  REG                 = <release registry address from Velt support>
  SUBSCRIPTION_ID     = <subscription-id>
  TENANT_ID           = <tenant-id>
  CLOUD               = AzureCloud
  LOCATION            = <region>
  RESOURCE_GROUP      = velt-portable
  DEPLOYMENT_NAME     = <deployment-name>
  PUBLIC_HOST         = <velt.example.com>
  ACR_NAME            = <acr-name>
  CONSOLE_ADMIN_EMAIL = <admin@example.com>
  ALLOWED_DOMAINS     = <example.com,app.example.com>
  APP_ORIGIN          = <https://app.example.com>

Maintain velt-selfhost-azure-state.json after every step so this run can be
resumed in a fresh session. Stop and ask me whenever a step needs a human.
```

The agent ends with a final report: your endpoints, your app's config, and where every secret is stored. Keep `velt-selfhost-azure-state.json` in your working directory; it lets a new session resume an interrupted install.

## 4. Stay available for the human steps

The agent pauses and asks at each of these moments, handing you the exact command or portal URL.

| Moment | What you do |
| - | - |
| Sign-in | Run `az login` (or follow the device-code URL) |
| Permissions | Confirm **Owner**, or **Contributor + User Access Administrator**, on the subscription |
| Region | Confirm the region the agent proposes from its checks |
| Quota | Request a vCPU quota increase if your limits are below the footprint, or choose the small footprint |
| Console app registration | Create the Entra single-page app, only if the agent's identity can't |
| Cluster admin group | Approve or supply the Entra security group for cluster admins, only if the agent can't create it |
| Image scan | Sign off the vulnerability scan, if your policy requires one |
| DNS | Add the A record for `PUBLIC_HOST`, unless you use the free Azure DNS label |
| Certificate | Supply the TLS certificate, or approve the Key Vault or cert-manager path |
| Acceptance | Sign in to the console and run the SDK loop in your app |

> [!TIP]
>
> A vCPU family at a quota of 0 usually needs a portal request or a support ticket, which can take days. Check your quota on day 1.

## 5. Wire your app

Set both axes in your app's Velt config: where the SDK bundle downloads **from** (`version` and `proxyConfig.cdnHost`), and where the SDK **talks to** (`selfHosted`).

> [tab] React / Next.js
>
> ```jsx theme={null}
> <VeltProvider
>   apiKey="<api-key>"
>   config={{
>     version: '<sdk-version>',                            // must equal sdk.version in your Helm values
>     proxyConfig: { cdnHost: 'https://<public-host>' },   // serves /lib/sdk@<version>/
>     selfHosted: {
>       enablePortableBackend: true,
>       portableBackendUrl: 'https://<public-host>/api',   // the /api base
>       strict: true,                                      // never fall back to Velt hosts
>     },
>   }}
> >
>   <App />
> </VeltProvider>
> ```

> [tab] Other Frameworks
>
> ```js theme={null}
> const client = await initVelt('<api-key>', {
>   version: '<sdk-version>',                            // must equal sdk.version in your Helm values
>   proxyConfig: { cdnHost: 'https://<public-host>' },   // serves /lib/sdk@<version>/
>   selfHosted: {
>     enablePortableBackend: true,
>     portableBackendUrl: 'https://<public-host>/api',   // the /api base
>     strict: true,                                      // never fall back to Velt hosts
>   },
> });
> ```

**Rules that break production if violated:**

1. Set both axes. `strict: true` silences runtime calls, but only `proxyConfig.cdnHost` and `version` stop the bundle from loading from `cdn.velt.dev`.
2. Pin `version` to the chart's `sdk.version`. It defaults to the wrapper's built-in version, and a mismatch 404s.
3. Never set `staging: true` or `develop: true` on a self-hosted page. Both point at a Velt host.
4. `portableBackendUrl` ends in `/api`. Root paths such as `/identify` are not routed.

## 6. Confirm it is done

The deployment is complete only when all four pass:

1. Console sign-in as the seeded admin email lands on the dashboard.
2. The app loads `velt.js` and its chunks from **your** host, and `window.Velt.version` matches the pin.
3. A comment created in the app is visible in the console.
4. A Network audit on both the app and console sessions shows **no** requests to `velt.dev` or other Velt-owned hosts.

With comment attachments on, a fifth check confirms uploads and downloads go to your own storage account.

## Troubleshooting your app

| Symptom | Likely cause |
| - | - |
| The network log shows `cdn.velt.dev` | `proxyConfig.cdnHost` or `version` is missing, or `staging` or `develop` is set |
| The browser shows a CORS error on `/api/...` | Your app's exact origin isn't in the deployment's allowed origins. Ask the agent to add it |
| Identify fails with "no allowed domain" | The workspace has no allowed domains. Add them in the console |
| `/api/v2/...` returns 404 | The REST API is off by default. Ask the agent to turn on the `rest-api` module |

For infrastructure errors, ask your agent: the agent instructions include the full troubleshooting table.

## Upgrading later

Upgrades are a delta, not a reinstall. Hand your agent the [Upgrade guide](https://velt.dev/docs/self-hosting/full/azure/upgrade.md): it verifies the new release, carries your settings forward, and updates the cluster with the release's own upgrade script. Back up the database first.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.