> ## Documentation Index
> Fetch the complete documentation index at: https://porter-mintlify-87472b99.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Deploying multiple apps with porter.yaml

> Define and deploy multiple Porter applications alongside datastores and custom Helm chart addons in a single porter.yaml file using porter apply

You can deploy multiple Porter apps alongside multiple Porter addons in a single `porter.yaml` file. This is particularly useful when you need to deploy related services that work together, such as a web application with its associated database or cache.

<Warning> This feature is in development and is subject to change. </Warning>

### Usage

To enable this feature, set the `PORTER_ADDON_YAML` environment variable while running the apply command.

```bash theme={null}
PORTER_ADDON_YAML=true porter apply -f porter.yaml
```

## Example Configuration

```yaml theme={null}
apps:
  - version: v2
    name: backend
    services:
      - name: server
        run: ""
        type: web
        instances: 1
        cpuCores: 0.2
        ramMegabytes: 100
        terminationGracePeriodSeconds: 30
        port: 80
        sleep: false
        private: true
    envGroups: # Environment groups can be used to inject environment variables from the addons into the service.
      - cache
      - db
    image:
      repository: nginx
      tag: latest
  - version: v2
    name: frontend
    services:
      - name: dashboard
        run: ""
        type: web
        instances: 1
        cpuCores: 0.2
        ramMegabytes: 100
        terminationGracePeriodSeconds: 30
        port: 80
        sleep: false
        private: true
    envGroups:
      - cache
      - db
    image:
      repository: nginx
      tag: latest
  - version: v2
    name: api
    services:
      - name: worker
        run: ""
        type: worker
        instances: 1
        cpuCores: 0.2
        ramMegabytes: 100
        terminationGracePeriodSeconds: 30
        port: 80
        sleep: false
    envGroups:
      - cache
      - db
    image:
      repository: nginx
      tag: latest
addons:
  - name: cache
    type: MANAGED-REDIS
    engine: REDIS
    values:
      config:
        name: cache
        masterUserPassword: password
        allocatedStorage: 2 # Persistent storage size in GB. Cannot be changed after creation.
        cpuCores: 0.1
        ramMegabytes: 110
  - name: db
    type: MANAGED-POSTGRES
    engine: POSTGRES
    values:
      config:
        name: db
        masterUserPassword: password
        allocatedStorage: 2
        cpuCores: 0.1
        ramMegabytes: 110
```

## Validating datastore addons

When your `porter.yaml` defines one or more `addons`, the CLI validates each in-cluster datastore addon (Postgres and Redis) before applying it. This surfaces common configuration mistakes locally as clear errors instead of opaque backend failures.

Validation runs automatically as part of:

* `porter apply -f porter.yaml` — before any addon is applied
* `porter apply validate` and `porter apply -f porter.yaml --validate` — without applying

### What is validated

For every datastore addon block, the CLI checks that:

| Field                     | Requirement                                                         |
| ------------------------- | ------------------------------------------------------------------- |
| `name`                    | Must be set                                                         |
| `type`                    | Must be `POSTGRES` or `REDIS`                                       |
| `kind`                    | Must be `IN_CLUSTER` (the only kind currently validated by the CLI) |
| `config.storageGigabytes` | Must be greater than `0`                                            |
| `config.cpuCores`         | Must be greater than `0`                                            |
| `config.ramMegabytes`     | Must be greater than `0`                                            |

If any check fails, `porter apply` exits with a non-zero status and prints the failing field. No apps or addons are applied until the errors are fixed.

### Example

```bash theme={null}
PORTER_ADDON_YAML=true porter apply -f porter.yaml --validate
```

A missing or zero field produces output similar to:

```
✗ porter.yaml validation failed
addon 'config.storageGigabytes' must be greater than 0
```

<Info>
  Only in-cluster Postgres and Redis datastores are validated by the CLI today. Managed datastores and custom Helm chart addons skip CLI validation and are validated server-side at apply time.
</Info>
