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

# Deploy Apps to production

> Deploy a published Domino App version at its URL, choose a Hardware Tier, configure autoscaling for your framework, and script deployments with the Apps API.

Deploying starts a published version at the App's URL.

## How deploying works

An App has at most one running instance. Deploying a version replaces the one that was running, so viewers always reach a single version at the App's URL. You can deploy any published version, not only the newest. Deploying an older version is how you [roll back](https://docs.domino.ai/6.3/platform-capabilities/core-concepts/apps/operate.md#roll-back-to-a-previous-version).

A version's [deployment settings](#deployment-settings) decide how and where it runs. Unlike its code, environment, and data configuration, you can change them after publishing: resize or rescale the App for its traffic without a new version. If a [governance](https://docs.domino.ai/6.3/platform-capabilities/core-concepts/apps/govern.md) policy gates deployment, Domino checks it each time the version deploys or restarts.

## Deploy the App

These steps deploy the **Synthetic Transaction Review** version you [published](https://docs.domino.ai/6.3/platform-capabilities/core-concepts/apps/publish.md) and, if required, [governed](https://docs.domino.ai/6.3/platform-capabilities/core-concepts/apps/govern.md).

**1. Choose the Hardware Tier**

On the App's details page, select the version and select **Deploy**, then confirm the Hardware Tier.

The transaction review App does little work per request. It reads a CSV once at startup and calls an endpoint when a reviewer selects **Review**. A small CPU tier is enough for a compliance team. Turn on autoscaling here so the same small tier also handles spikes in demand. See [Size and scale an App](#size-and-scale-an-app).

**2. Deploy and open the App**

Deploy. When the status changes to **Running**, open the App URL and score one transaction.

![Synthetic Transaction Review App overview showing a running version, runtime metrics, Compute Environment, and Hardware Tier.](https://mintcdn.com/dominodatalab-e871cec4/tAN89q5OuNV-ii4x/images/getting-started/synthetic-transaction-review-app-overview.png?fit=max\&auto=format\&n=tAN89q5OuNV-ii4x\&q=85\&s=01b437529970ff7d455143a2952d8654)

Next, [share the App](https://docs.domino.ai/6.3/platform-capabilities/core-concepts/apps/operate.md#share-the-app) with its viewers.

## Deployment settings

Deployment settings control how and where a version runs, not what it runs. Changing one updates the version in place and restarts the running instance. It doesn't create a version.

| Setting | What it does |
| :- | :- |
| **Hardware Tier** | The CPU, memory, and GPU for each pod. See [Size and scale an App](#size-and-scale-an-app). |
| **Autoscaling** | Scales the number of pods with load. See [Configure autoscaling](#configure-autoscaling). |
| **Custom URL path** | A readable path for the App, such as `/apps/demo`. |
| **Enable deep linking** | Lets viewers link to a specific view inside the App. Requires `SecureIdentityPropagationToAppsEnabled`; see [Configuration](https://docs.domino.ai/6.3/platform-capabilities/core-concepts/apps/configuration.md). |

## Size and scale an App

Domino runs an App in a pod on its [Hardware Tier](https://docs.domino.ai/6.3/admin/infrastructure-and-compute/manage-compute-resources/hardware-tiers/hardware-tier-best-practices.md). Turn on autoscaling and pick a lightweight Hardware Tier. Domino adds pods within seconds when demand spikes and removes them when it falls, so you don't size the App for peak traffic or weigh cost against performance. Without autoscaling, size the pod for the viewers you expect. Both are deployment settings. Changing them restarts the App without creating a version.

### Estimate what one pod serves

With autoscaling on, capacity is pods times viewers per pod. If one action uses 100 MB of RAM and 20% of a CPU, a pod with 1 core and 1 GB of RAM serves 5 viewers running that action at once, so 40 such pods serve 200 concurrent reviewers on small, cheap tiers. Without autoscaling, pick a Hardware Tier with enough cores for the viewers you expect; in this example CPU is the limit, not memory. Run heavy or long-running computation as its own execution: start a Job or call an endpoint from the App and show the result when it's ready. The App stays responsive, the work runs on its own Hardware Tier, and each run has its own logs and record.

Depending on the tier, the pod shares a node with other containers or runs on a dedicated node.

### Use every core on the pod

Without autoscaling, make the App use every core on its pod.

**Dash and Flask**

Flask's built-in server, which Dash also uses, is for development. For production traffic, serve the App through a production server such as [`gunicorn`](https://gunicorn.org/), with worker processes sized for the pod.

Dash exposes its Flask server as `app.server`. Add `gunicorn` to the App's Compute Environment, then add one line after the `Dash` constructor:

```python app.py theme={null}
app = Dash(
    __name__,
    title="Synthetic Transaction Review",
    routes_pathname_prefix="/",
    requests_pathname_prefix=domino_path_prefix(),
)
server = app.server
```

Change `app.sh` to run `gunicorn` with 4 worker processes:

```bash app.sh theme={null}
#!/usr/bin/env bash
set -euo pipefail

gunicorn -w 4 -b 0.0.0.0:8888 app:server
```

For a plain Flask App, point `gunicorn` at the Flask object instead, such as `app-flask:app`. See the [Flask deployment documentation](https://flask.palletsprojects.com/en/3.0.x/deploying/) for other options.

**Shiny**

Shiny serves one request per R process, so Domino scales a Shiny App by adding pods rather than cores. See [R and Shiny](#r-and-shiny).

### Configure autoscaling

With autoscaling on, Domino adds and removes pods for the running App dynamically, keeping CPU and memory use across pods near their targets. Scale-up happens within 20 seconds, and scaling happens without a restart or republish.

That lets you choose a lighter-weight, cheaper Hardware Tier than you would for an App that doesn't autoscale and rely on autoscaling to absorb demand spikes. Extra pods run only while demand needs them, so you don't have to trade cost against performance up front.

Turn on autoscaling when you publish or deploy the App. Start from the default parameters, then adjust them for your framework as described below.

| Scaling parameter | Description |
| :- | :- |
| **Maximum Pods** | The maximum number of pods the App can scale up to. The App always runs at least one pod. |
| **CPU % target** | The target CPU utilization across pods. Domino adds or removes pods to keep use near this target. |
| **Memory % target** | The target memory utilization across pods, applied the same way as the CPU target. |
| **Scale up delay** or **Scale down delay** | Delays scaling changes to prevent rapid, repeated adjustments. |
| **Enable session affinity** | Routes all of a viewer's requests to the same pod for their session. Requires `SecureIdentityPropagationToAppsEnabled`. |

The App's **Monitoring** tab shows CPU and memory across all pods with autoscaling events, so you can check the settings under real load. See [Monitor resource consumption](https://docs.domino.ai/6.3/platform-capabilities/core-concepts/apps/operate.md#monitor-resource-consumption).

Custom autoscaling values persist across sessions. On a remote Data Plane, autoscaled pods share the volume your administrator names in `com.cerebro.domino.apps.autoscaledExecutionPvcNamesForRemoteDataPlanes`; see [Configuration](https://docs.domino.ai/6.3/platform-capabilities/core-concepts/apps/configuration.md). On a remote Data Plane, autoscaled pods share the volume your administrator names in `com.cerebro.domino.apps.autoscaledExecutionPvcNamesForRemoteDataPlanes`; see [Configuration](https://docs.domino.ai/6.3/platform-capabilities/core-concepts/apps/configuration.md). On a remote Data Plane, autoscaled pods share the volume your administrator names in `com.cerebro.domino.apps.autoscaledExecutionPvcNamesForRemoteDataPlanes`; see [Configuration](https://docs.domino.ai/6.3/platform-capabilities/core-concepts/apps/configuration.md). On a remote Data Plane, autoscaled pods share the volume your administrator names in `com.cerebro.domino.apps.autoscaledExecutionPvcNamesForRemoteDataPlanes`; see [Configuration](https://docs.domino.ai/6.3/platform-capabilities/core-concepts/apps/configuration.md).

> [!WARNING]
>
> Autoscaled replicas share the same disk for temporary storage and Project files. If the App writes to disk, write to a location unique to each process. Make sure any Compute Environment pre-setup, post-setup, pre-run, or post-run scripts are safe to run in several processes at once, or move that work into the environment definition.

#### R and Shiny

Shiny serves one request per R process, so Domino scales a Shiny App by adding pods.

* Turn on **Enable session affinity** to avoid transient connectivity errors for viewers.
* Pick a small, low-CPU Hardware Tier and a high **Maximum Pods**.

With these settings, a Shiny App supports arbitrarily high viewer counts. See [Make Shiny fast by doing as little work as possible](https://rstudio.com/resources/rstudioconf-2018/make-shiny-fast-by-doing-as-little-work-as-possible/).

#### Streamlit

Streamlit keeps each viewer's session state in server memory, and features such as file uploads and generated media need every request from a session to reach the same pod. Turn on **Enable session affinity** when a Streamlit App autoscales.

#### Flask, Dash, and other frameworks

Leave **Enable session affinity** off unless the framework keeps per-viewer state in memory. Requests then spread across pods, and Domino can scale down sooner. The transaction review App keeps its decisions in the browser session, not in server memory, so it doesn't need affinity.

## Script deployments with the API

The `/api/apps/v1/` endpoints cover the same operations as the UI: create an App, create a Draft App for a Workspace, publish, list and create versions, and start, stop, or live-sync a version. Publishing into an App whose entry point or configuration type doesn't match returns `422`.

The older `/api/apps/beta/` endpoints are unchanged, so existing callers need no migration. App instance reads (list instances, logs, real-time logs, views, and instance delete) exist only on the beta endpoints. Both are documented in the [Domino Platform API reference](https://docs.domino.ai/6.3/reference/api/domino-open-api) under the Apps, AppVersions, and AppInstances tags.

## Related

* [Operate](https://docs.domino.ai/6.3/platform-capabilities/core-concepts/apps/operate.md): Share, monitor, roll back, and troubleshoot the deployed App.
* [Hardware Tier best practices](https://docs.domino.ai/6.3/admin/infrastructure-and-compute/manage-compute-resources/hardware-tiers/hardware-tier-best-practices.md): How administrators size tiers.


## Related topics

- [Integrated deployment to CI/CD workflows](https://docs.domino.ai/6.3/platform-capabilities/features/models/integrate-ci-cd-workflows.md)
- [Apps](https://docs.domino.ai/6.3/platform-capabilities/core-concepts/apps/index.md)
- [Deploy agentic systems](https://docs.domino.ai/6.3/platform-capabilities/features/agents/deploy.md)
- [Govern Apps](https://docs.domino.ai/6.3/platform-capabilities/core-concepts/apps/govern.md)
