> For the complete documentation index, see [llms.txt](https://v2.dataos.info/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://v2.dataos.info/consume/activate/apis/overview/deploy-a-data-application.md).

# Deploy a data application

Use an `app` Resource when DataOS should run the application from a container image. The Resource defines the runtime container, compute target, HTTP ingress path, environment variables, and catalog relationship to the Data Product.

This page uses an Orders360 Streamlit dashboard as an example.

## Prerequisites

* You have a Data Product that the application consumes.
* You have a container image for the application.
* You have the **Data Consumer and Data Developer** role.
* You have permission to create the Resource within the target Tenant.
* You have `dataos-ctl` configured for the target Tenant.
* You know the target compute name, run-as user, application port, and ingress path.
* You have the Data Product API base URL and authentication token available as runtime configuration.
* For private container images, you have an image pull Secret.

{% stepper %}
{% step %}

### 1. Prepare the manifest

Create an `app` Resource manifest for the application. Replace the names, image, user, paths, Data Product URL, token reference, owners, and product names with values for your environment.

{% code expandable="true" collapsedlinecount="12" %}

```yaml
version: v1alpha
type: app
name: orders360-dashboard
title: Orders360 Dashboard
description: KPI dashboard for the Orders360 (VDE) data product via the Vulcan API.
owner: kanakguptatmdcio
tags:
  - dashboard
  - streamlit
  - orders360
  - vulcan
spec:
  compute: pacific
  runAsUser: kanakguptatmdcio
  logLevel: INFO
  replicas: 1
  resources:
    requests:
      cpu: 250m
      memory: 256Mi
    limits:
      cpu: 500m
      memory: 512Mi
  service:
    type: python
    image: dockerkk97/orders360-dashboard:0.0.1
    imagePullSecret: docker-secret
    command:
      - streamlit
    arguments:
      - run
      - app.py
      - --server.port=8501
      - --server.address=0.0.0.0
      - --server.headless=true
      - --browser.gatherUsageStats=false
    port: 8501
    envs:
      VULCAN_BASE_URL: "https://pacific-051426.dataos.cloud/vulcan/tenants/product-sandbox/data-products/product-sandbox-orders360-vdetrue/api/v1"
      VULCAN_AUTH_TOKEN: "${VULCAN_AUTH_TOKEN}"
    hostname: orders360-dashboard
    stateful: false
    http:
      path: /orders360-dashboard
      stripPath: false
      ingress:
        enabled: true
        path: /orders360-dashboard
        stripPath: false
        appDetailSpec: orders360-dashboard
  app:
    domain: sales_operations
    description: Overview of physical models, semantics, quality, runs, plans, and query usage.
    tags:
      - app
      - dashboard
      - orders360
    owners:
      - kanakguptatmdcio
    products:
      - orders360-vdetrue
    references:
      - title: Vulcan API (Postman)
        url: https://github.com/tmdc-io/vulcan-examples/blob/main/ux/Vulcan%20API%20OSI.postman_collection.json
    link:
      title: Open dashboard
      url: https://pacific-051426.dataos.cloud/orders360-dashboard
```

{% endcode %}
{% endstep %}

{% step %}

### Public application variant

For a public container image, omit `imagePullSecret`. To expose the application path without network authorization, set `noNetworkAuthorization: true` under `spec.service.http`.

{% code expandable="true" collapsedlinecount="8" %}

```yaml
service:
  type: python
  image: dockerkk97/orders360-dashboard-public:public
  http:
    path: /orders360-app
    stripPath: false
    noNetworkAuthorization: true
    ingress:
      enabled: true
      path: /orders360-app
      stripPath: false
      appDetailSpec: orders360-app
```

{% endcode %}
{% endstep %}

{% step %}

### 2. Apply the manifest

Apply the Resource manifest with `dataos-ctl`.

```bash
dataos-ctl resource apply -f app.yaml
```

{% endstep %}

{% step %}

### 3. Configure path access

If the application uses network authorization, configure the required ingress path access for the application path. The example grants access for both `/orders360-dashboard**` and `/orders360-app**`.

{% code expandable="true" collapsedlinecount="12" %}

```yaml
id: orders360-dashboard-app
name: "Orders360 Dashboard"
category: app-management
authorization_atoms:
  - get-path-ingress
  - put-path-ingress
  - post-path-ingress
  - patch-path-ingress
  - delete-path-ingress
values:
  - authorization_atom_id: get-path-ingress
    variable_values:
      - path: /orders360-dashboard**
      - path: /orders360-app**
  - authorization_atom_id: put-path-ingress
    variable_values:
      - path: /orders360-dashboard**
      - path: /orders360-app**
  - authorization_atom_id: post-path-ingress
    variable_values:
      - path: /orders360-dashboard**
      - path: /orders360-app**
  - authorization_atom_id: patch-path-ingress
    variable_values:
      - path: /orders360-dashboard**
      - path: /orders360-app**
  - authorization_atom_id: delete-path-ingress
    variable_values:
      - path: /orders360-dashboard**
      - path: /orders360-app**
```

{% endcode %}
{% endstep %}

{% step %}

### 4. Open the application

After deployment, open the URL configured in `spec.app.link.url`. The application also appears in the catalog with the Data Product relationship defined under `spec.app.products`.
{% endstep %}
{% endstepper %}

## Field reference

<details>

<summary>Field reference</summary>

<table><thead><tr><th width="294.3551025390625">Field</th><th width="111.43798828125">Required</th><th>Purpose</th></tr></thead><tbody><tr><td><code>spec.compute</code></td><td>Yes</td><td>Compute target where the application runs.</td></tr><tr><td><code>spec.runAsUser</code></td><td>Yes</td><td>DataOS user identity used to run the application.</td></tr><tr><td><code>spec.replicas</code></td><td>Yes</td><td>Number of application replicas.</td></tr><tr><td><code>spec.resources.requests</code></td><td>Yes</td><td>CPU and memory requested for the application.</td></tr><tr><td><code>spec.resources.limits</code></td><td>Yes</td><td>CPU and memory limits for the application.</td></tr><tr><td><code>spec.service.type</code></td><td>Yes</td><td>Runtime type, such as <code>python</code>.</td></tr><tr><td><code>spec.service.image</code></td><td>Yes</td><td>Container image that runs the application.</td></tr><tr><td><code>spec.service.imagePullSecret</code></td><td>No</td><td>Secret used to pull a private image.</td></tr><tr><td><code>spec.service.command</code></td><td>Yes</td><td>Entrypoint command for the container.</td></tr><tr><td><code>spec.service.arguments</code></td><td>No</td><td>Arguments passed to the command.</td></tr><tr><td><code>spec.service.port</code></td><td>Yes</td><td>Port exposed by the application container.</td></tr><tr><td><code>spec.service.envs</code></td><td>No</td><td>Environment variables passed to the application.</td></tr><tr><td><code>spec.service.hostname</code></td><td>No</td><td>Hostname assigned to the backing service.</td></tr><tr><td><code>spec.service.stateful</code></td><td>No</td><td>Whether the service runs as stateful.</td></tr><tr><td><code>spec.service.http.path</code></td><td>Yes</td><td>HTTP path used to reach the application.</td></tr><tr><td><code>spec.service.http.stripPath</code></td><td>No</td><td>Whether the gateway strips the path before forwarding.</td></tr><tr><td><code>spec.service.http.noNetworkAuthorization</code></td><td>No</td><td>Whether network authorization is bypassed for the HTTP path.</td></tr><tr><td><code>spec.service.http.ingress.enabled</code></td><td>No</td><td>Whether ingress is enabled for the application.</td></tr><tr><td><code>spec.service.http.ingress.path</code></td><td>No</td><td>External ingress path for the application.</td></tr><tr><td><code>spec.service.http.ingress.appDetailSpec</code></td><td>No</td><td>App detail identifier used by ingress metadata.</td></tr><tr><td><code>spec.app.domain</code></td><td>Yes</td><td>Domain where the application appears in the catalog.</td></tr><tr><td><code>spec.app.description</code></td><td>Yes</td><td>Catalog description for the application.</td></tr><tr><td><code>spec.app.owners</code></td><td>Yes</td><td>Owners responsible for the application.</td></tr><tr><td><code>spec.app.products</code></td><td>No</td><td>Data Products consumed by the application.</td></tr><tr><td><code>spec.app.references</code></td><td>No</td><td>Related links, such as API or documentation references.</td></tr><tr><td><code>spec.app.link.title</code></td><td>No</td><td>Label for the action that opens the application.</td></tr><tr><td><code>spec.app.link.url</code></td><td>No</td><td>URL opened from the application catalog entry.</td></tr></tbody></table>

</details>

## Validate the deployment

<details>

<summary>Validate the deployment</summary>

| Check                                | Expected result                                                                                   |
| ------------------------------------ | ------------------------------------------------------------------------------------------------- |
| Resource applies successfully        | `dataos-ctl` accepts the `app` Resource manifest.                                                 |
| Application URL opens                | The URL in `spec.app.link.url` loads the deployed application.                                    |
| Data Product relationship is visible | The application catalog entry shows the Data Product listed under `spec.app.products`.            |
| Runtime configuration is available   | The application can read environment variables such as `VULCAN_BASE_URL` and `VULCAN_AUTH_TOKEN`. |

</details>

## Troubleshooting

<details>

<summary>Image pull fails</summary>

The image is private or the pull Secret is missing. Add `spec.service.imagePullSecret` with the correct image pull Secret name and re-apply the manifest.

</details>

<details>

<summary>Application opens on the wrong path</summary>

The HTTP path or ingress path does not match the app URL. Confirm `spec.service.http.path`, `spec.service.http.ingress.path`, and `spec.app.link.url` all use the same route.

</details>

<details>

<summary>Data Product relationship is not shown in the catalog</summary>

`spec.app.products` is missing or the product name is incorrect. Add the correct Data Product name under `spec.app.products` and re-apply the manifest.

</details>

<details>

<summary>API calls fail at runtime</summary>

The Data Product API base URL or token is missing from the application environment. Confirm `VULCAN_BASE_URL` and `VULCAN_AUTH_TOKEN` are set correctly in `spec.service.envs`. Use a valid [DataOS API token](/consume/get-started/readme-1.md#get-a-dataos-api-token) for `VULCAN_AUTH_TOKEN`.

</details>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://v2.dataos.info/consume/activate/apis/overview/deploy-a-data-application.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
