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

# porter apply

> Deploy applications using porter.yaml with the porter apply command, supporting container builds, image updates, and preview environments

<Info>
  This command is the recommended way to deploy applications in CI/CD pipelines and for version-controlled infrastructure.
</Info>

`porter apply` is the primary command for deploying applications using configuration-as-code. It reads a `porter.yaml` file, **builds a new container image**, and **deploys your application** to the cluster.

By default, `porter apply` performs a full build and deploy cycle. Use `--no-build` to skip building and deploy with an existing image.

<Info>
  You can run `porter apply` without a `porter.yaml` file to deploy using the existing application configuration. This is useful for triggering a new build and deploy without changing any settings.
</Info>

## Usage

```bash theme={null}
porter apply -f porter.yaml [flags]
```

## Prerequisites

* You've logged in to the Porter CLI after running [porter auth login](/standard/cli/command-reference/porter-auth)
* You're connected to the correct project by running [porter config set-project](/standard/cli/command-reference/porter-config)
* You're connected to the correct cluster by running [porter config set-cluster](/standard/cli/command-reference/porter-config)

## Options

### Deployment Options

| Flag        | Short | Description                                                                   |
| ----------- | ----- | ----------------------------------------------------------------------------- |
| `--file`    | `-f`  | Path to the `porter.yaml` configuration file (optional if app already exists) |
| `--app`     |       | Override the app name specified in `porter.yaml`                              |
| `--target`  | `-x`  | Specify a deployment target (name or ID)                                      |
| `--wait`    | `-w`  | Wait for the deployment to complete before exiting                            |
| `--preview` | `-p`  | Deploy to a preview environment based on current git branch                   |

<Warning>
  **Use `--exact` with caution.** When set, this flag disables config merging with existing app configuration—any settings not explicitly defined in your `porter.yaml` will be overwritten. Most users should avoid this flag unless they need to completely replace the application configuration.
</Warning>

| Flag      | Description                                            |
| --------- | ------------------------------------------------------ |
| `--exact` | Disable config merging with existing app configuration |

### Build Options

| Flag                  | Description                                                 |
| --------------------- | ----------------------------------------------------------- |
| `--no-build`          | Skip building a new image and deploy with an existing image |
| `--no-pull`           | Don't pull the previous image before building               |
| `--tag`               | Specify a custom image tag (overrides value in porter.yaml) |
| `--image-repository`  | Set the image repository to use                             |
| `--build-context`     | Override the build context directory                        |
| `--build-method`      | Set build method: `docker` or `pack`                        |
| `--dockerfile`        | Override the Dockerfile path (for docker builds)            |
| `--builder`           | Set the builder to use (for pack builds)                    |
| `--attach-buildpacks` | Attach buildpacks to use (for pack builds)                  |
| `--verbose`           | Show verbose output during build                            |

### Environment Options

You can pass environment variables and secrets directly via command-line flags without modifying your `porter.yaml`.

| Flag          | Description                                                          |
| ------------- | -------------------------------------------------------------------- |
| `--variables` | Set environment variables as key=value pairs (overrides porter.yaml) |
| `--secrets`   | Set secrets as key=value pairs (overrides porter.yaml)               |

### Validation Options

| Flag         | Description                                                                                   |
| ------------ | --------------------------------------------------------------------------------------------- |
| `--validate` | Check that the `porter.yaml` file is valid YAML syntax                                        |
| `--dry-run`  | Perform server-side validation to confirm the configuration is valid without applying changes |

### Advanced Options

| Flag                    | Short | Description                                          |
| ----------------------- | ----- | ---------------------------------------------------- |
| `--helm-overrides-file` | `-v`  | Path to a file containing Helm value overrides       |
| `--attach-env-groups`   |       | Comma-separated list of environment groups to attach |

## Environment Variables

You can also configure `porter apply` using environment variables. These are automatically set in the GitHub workflow that Porter generates for your application.

| Variable                      | Description                               |
| ----------------------------- | ----------------------------------------- |
| `PORTER_TOKEN`                | Authentication token (required for CI/CD) |
| `PORTER_HOST`                 | Porter API host URL                       |
| `PORTER_PROJECT`              | Target project ID                         |
| `PORTER_CLUSTER`              | Target cluster ID                         |
| `PORTER_APP_NAME`             | App name (alternative to `--app`)         |
| `PORTER_DEPLOYMENT_TARGET_ID` | Deployment target ID                      |
| `PORTER_TAG`                  | Image tag to deploy                       |

## Examples

<CodeGroup>
  ```bash Basic Deployment theme={null}
  # Deploy using porter.yaml in the current directory
  porter apply -f porter.yaml
  ```

  ```bash Wait for Completion theme={null}
  # Deploy and wait for the deployment to complete
  porter apply -f porter.yaml --wait
  ```

  ```bash Preview Environment theme={null}
  # Deploy to a preview environment
  porter apply -f porter.yaml --preview
  ```

  ```bash Validate YAML Syntax theme={null}
  # Check that porter.yaml is valid YAML
  porter apply -f porter.yaml --validate
  ```

  ```bash Dry Run theme={null}
  # Validate the full configuration server-side without deploying
  porter apply -f porter.yaml --dry-run
  ```

  ```bash CI/CD Pipeline theme={null}
  # Deploy in a CI/CD pipeline with explicit configuration
  PORTER_TOKEN=$PORTER_DEPLOY_TOKEN \
  PORTER_PROJECT=$PROJECT_ID \
  PORTER_CLUSTER=$CLUSTER_ID \
  porter apply -f porter.yaml
  ```

  ```bash Skip Build theme={null}
  # Deploy using an existing image (skip build step)
  porter apply -f porter.yaml --no-build --tag v1.2.3
  ```

  ```bash With Environment Variables theme={null}
  # Deploy with runtime environment variables and secrets
  porter apply -f porter.yaml --variables LOG_LEVEL=debug,NODE_ENV=production --secrets API_KEY=secret123
  ```
</CodeGroup>

## Workflow

When you run `porter apply`, the following steps occur:

<Steps>
  <Step title="Parse Configuration">
    Porter reads and validates your `porter.yaml` file (if provided)
  </Step>

  <Step title="Build Image">
    Porter builds and pushes a new container image (unless `--no-build` is specified)
  </Step>

  <Step title="Deploy Services">
    Porter deploys or updates all services defined in the configuration
  </Step>

  <Step title="Wait for Rollout (if --wait)">
    If `--wait` is specified, Porter waits for all services to become healthy
  </Step>
</Steps>

## Configuration File

The `porter apply` command expects a `porter.yaml` file. For detailed documentation on all available configuration options, see the [porter.yaml Reference](/applications/configuration-as-code/reference).

### Minimal Example

```yaml theme={null}
version: v2
name: my-app

services:
  - name: web
    type: web
    run: npm start
    port: 3000
    cpuCores: 0.5
    ramMegabytes: 512
```

## CI/CD Integration

Most users deploy with `porter apply` through GitHub Actions. Porter automatically generates a GitHub workflow for your application that handles authentication and deployment.

<Info>
  The workflow below is similar to what Porter automatically creates when you connect your GitHub repository. You can find it in your repository at `.github/workflows/porter_<app-name>.yml`.
</Info>

### GitHub Actions Workflow

```yaml theme={null}
name: Deploy to my-app

on:
  push:
    branches:
      - main

jobs:
  porter-deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Set Github tag
        id: vars
        run: echo "sha_short=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT

      - name: Setup porter
        uses: porter-dev/setup-porter@v0.1.0

      - name: Deploy stack
        run: porter apply
        timeout-minutes: 30
        env:
          PORTER_CLUSTER: "1"
          PORTER_HOST: https://dashboard.porter.run
          PORTER_PROJECT: "1"
          PORTER_TOKEN: ${{ secrets.PORTER_TOKEN }}
          PORTER_TAG: ${{ steps.vars.outputs.sha_short }}
          PORTER_APP_NAME: my-app
          PORTER_DEPLOYMENT_TARGET_ID: your-deployment-target-id
```

## Related Commands

* [porter app update](/standard/cli/command-reference/porter-app#porter-update) - Update an app without building
* [porter app yaml](/standard/cli/command-reference/porter-app#porter-yaml) - Export the current app configuration as YAML
