---
title: Deploy the Langflow production environment on Kubernetes
slug: /deployment-kubernetes-prod
---

import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

The [Langflow runtime Helm chart](https://github.com/langflow-ai/langflow-helm-charts/blob/main/charts/langflow-runtime) is tailored for deploying applications in a production environment. It is focused on stability, performance, isolation, and security to ensure that applications run reliably and efficiently.

:::warning
For security reasons, the default Langflow runtime Helm chart sets [`readOnlyRootFilesystem: true`](https://github.com/langflow-ai/langflow-helm-charts/blob/main/charts/langflow-runtime/values.yaml#L46). This setting prevents modifications to the container's root filesystem at runtime, which is a recommended security measure in production environments.

If `readOnlyRootFilesystem` is disabled (`false`), it degrades your deployment's security posture. Only disable this setting if you understand the security implications and you have implemented other security measures.

For more information, see the [Kubernetes documentation](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/).
:::

## Prerequisites

- A [Kubernetes](https://kubernetes.io/docs/setup/) server
- [kubectl](https://kubernetes.io/docs/tasks/tools/#kubectl)
- [Helm](https://helm.sh/docs/intro/install/)

## Install the Langflow runtime Helm chart

1. Add the repository to Helm:

    ```shell
    helm repo add langflow https://langflow-ai.github.io/langflow-helm-charts
    helm repo update
    ```

2. Install the Langflow app with the default options in the `langflow` namespace.

    <Tabs groupId="">
    <TabItem value="Install chart with custom image" label="Install chart with custom image" default>

    If you have a [custom image with packaged flows](/deployment-docker#package-your-flow-as-a-docker-image), you can deploy Langflow by overriding the default [`values.yaml`](https://github.com/langflow-ai/langflow-helm-charts/blob/main/charts/langflow-runtime/values.yaml) with the `--set` flag:

    ```shell
    helm install my-langflow-app langflow/langflow-runtime -n langflow --create-namespace --set image.repository=myuser/langflow-hello-world --set image.tag=1.0.0
    ```

    </TabItem>
    <TabItem value="Install chart and download flow" label="Install chart and download flow">

    Install the chart and download flows from a URL with the `--set` flag:

    ```shell
    helm install my-langflow-app-with-flow langflow/langflow-runtime \
      -n langflow \
      --create-namespace \
      --set 'downloadFlows.flows[0].url=https://raw.githubusercontent.com/langflow-ai/langflow/dev/tests/data/basic_example.json'
    ```

    If your shell requires escaping square brackets, modify the `--set` path as needed.
    For example, `--set 'downloadFlows.flows\[0\].url=https://raw.githubusercontent.com/langflow-ai/langflow/dev/tests/data/basic_example.json'`.

    </TabItem>
    </Tabs>

3. Check the status of the pods:

    ```shell
    kubectl get pods -n langflow
    ```

## Access the Langflow runtime

1. Get your service name:

    ```shell
    kubectl get svc -n langflow
    ```

    The service name is your release name suffixed by `-langflow-runtime`. For example, if you used `helm install my-langflow-app-with-flow`, then the service name is `my-langflow-app-with-flow-langflow-runtime`.

2. Enable port forwarding to access Langflow from your local machine:

    ```shell
    kubectl port-forward -n langflow svc/my-langflow-app-with-flow-langflow-runtime 7860:7860
    ```

3. Confirm you can access the API by calling `http://localhost:7860/api/v1/flows/`:

    ```shell
    curl -v http://localhost:7860/api/v1/flows/
    ```

    A successful request returns a list of flows.

4. Run a packaged flow.
The following example gets the first flow ID from the flows list, and then runs the flow:

    ```shell
    # Get flow ID
    id=$(curl -s "http://localhost:7860/api/v1/flows/" | jq -r '.[0].id')

    # Run flow
    curl -X POST \
        "http://localhost:7860/api/v1/run/$id?stream=false" \
        -H 'Content-Type: application/json' \
        -d '{
          "input_value": "Hello!",
          "output_type": "chat",
          "input_type": "chat"
        }'
    ```

## Configure secrets and environment variables

Use the `.env` section of the Langflow runtime Helm chart's [`values.yaml`](https://github.com/langflow-ai/langflow-helm-charts/blob/main/charts/langflow-runtime/values.yaml) file to define environment variables for your Langflow deployment.
This includes built-in [Langflow environment variables](/environment-variables), as well as [global variables](/configuration-global-variables) used by your flows.

Langflow can source global variables from your runtime environment, such as Kubernetes secrets referenced in `values.yaml`.
For example, the Langflow runtime Helm chart's [example flow JSON](https://raw.githubusercontent.com/langflow-ai/langflow-helm-charts/refs/heads/main/examples/flows/basic-prompting-hello-world.json) uses a global variable that is a secret.
If you want to run this flow in your Langflow deployment on Kubernetes, you need to include the secret in your runtime configuration.

:::tip
When you export flows as JSON files, it's recommended to omit secrets.
Whether or not a secret is included depends on how you declare the secret in your flow and whether you use the **Save with my API keys** option.
For more information, see [Import and export flows](/concepts-flows-import).
:::

### Set secrets

Kubernetes secrets are the recommended way to store sensitive values and credentials.

Use `secretKeyRef` to reference a Kubernetes secret in `values.yaml`:

```yaml
env:
  - name: OPENAI_API_KEY
    valueFrom:
      secretKeyRef:
        name: openai-credentials
        key: openai-key
```

<details>
<summary>Create and set secrets with `kubectl` and `helm`</summary>

You can use `kubectl` and `helm` commands to create and set secrets:

1. Create a secret:

    ```shell
    kubectl create secret generic openai-credentials \
      --namespace langflow \
      --from-literal=OPENAI_API_KEY=sk...
    ```

2. Verify the secret exists:

    ```shell
    kubectl get secrets -n langflow openai-credentials
    ```

    The result is encrypted.

3. Upgrade the Helm release to use the secret:

    ```shell
    helm upgrade my-langflow-app-image langflow/langflow-runtime -n langflow \
      --reuse-values \
      --set "extraEnv[0].name=OPENAI_API_KEY" \
      --set "extraEnv[0].valueFrom.secretKeyRef.name=openai-credentials" \
      --set "extraEnv[0].valueFrom.secretKeyRef.key=OPENAI_API_KEY"
    ```

    Escape square brackets if required by your shell.

</details>

### Set the log level and other configuration variables

For non-sensitive variables, such as `LANGFLOW_LOG_LEVEL`, you can set the value directly in `values.yaml`:

```yaml
env:
  - name: LANGFLOW_LOG_LEVEL
    value: "INFO"
```

## Configure scaling

Use `replicaCount` and `resources` in the Langflow runtime Helm chart's [`values.yaml`](https://github.com/langflow-ai/langflow-helm-charts/blob/main/charts/langflow-runtime/values.yaml) file to configure scaling:

* **Horizontal scaling**: Use `replicaCount` to set the number of replicas for your Langflow deployment.

    ```yaml
    replicaCount: 3
    ```

* **Vertical scaling**: Use the `resources` section to adjust pod resources depending on your application's needs.

    ```yaml
    resources:
      requests:
        memory: "2Gi"
        cpu: "1000m"
    ```

## See also

* [Best practices for Langflow on Kubernetes](/deployment-prod-best-practices)
* [Langflow Helm Charts repository](https://github.com/langflow-ai/langflow-helm-charts)