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

# Deploy code to multiple Dag bundles

> Split the code on an Astro Deployment into named Dag bundles that you deploy and version independently.

<Info>
  This feature is in [Public Preview](/docs/astro/feature-previews).
</Info>

A *bundle* is a unit of code that you deploy to a Deployment. Astro supports two kinds:

* **Dag bundles** carry Dag files. Each Dag bundle has a name, its own version history, and its own deploys.
* **Non-Dag bundles** carry supporting code, such as a dbt project. Each non-Dag bundle is identified by the path it's mounted at, and is served alongside one or more Dag bundles.

Every Deployment with Dag-only deploys enabled has a Dag bundle named `main`. It's the default target for `astro deploy --dags`, and you can't delete it. On Airflow 3 Deployments, you can create more named Dag bundles and deploy to each one separately.

Multiple Dag bundles are useful when several teams or repositories share a Deployment. Each team deploys its own bundle without carrying the other teams' code, and a change to one bundle doesn't redeploy the rest.

<Note>
  **Airflow 3**

  Creating Dag bundles other than `main` requires an Airflow 3.x Deployment. Airflow 2 Deployments keep the single `main` bundle.
</Note>

## Prerequisites

* An Astro Deployment running Airflow 3 with [Dag-only deploys](/docs/astro/deploy-dags) enabled.
* The [Astro CLI](/docs/cli/v1.46/install-cli) version 1.46 or later.
* Workspace Author permissions or higher to create, update, and delete bundles. Workspace Member permissions are enough to view them.

Bundles aren't available on Deployments that use [Remote Execution](/docs/astro/execution-mode#remote-execution). Those Deployments configure Dag bundles through the Remote Execution Agent instead. See [Configure Dag sources](/docs/astro/remote-execution/remote-execution-configure-dag-sources).

## How bundles relate to each other

A Deployment has one or more Dag bundles and any number of non-Dag bundles, up to a combined limit. Each non-Dag bundle is associated with at least one Dag bundle, which determines the Airflow workers that download it.

For example, a Deployment shared by a finance team and a machine learning team might have three Dag bundles, `main`, `finance`, and `ml`, alongside a dbt project mounted at `/usr/local/airflow/dbt/revenue` and shared helper code mounted at `/usr/local/airflow/include/shared`.

The finance team deploys to `finance` on its own schedule, and the machine learning team deploys to `ml` on its own schedule. Neither deploy affects the other. The dbt project is served alongside `finance` only, and the shared helper code is served alongside both.

## Create a Dag bundle

Astro creates the `main` bundle automatically when you enable Dag-only deploys. For every other Dag bundle, you must create it before you can deploy to it — Astro doesn't create them automatically.

Bundle names must be 1-32 characters and can contain only lowercase letters, numbers, dashes, and underscores. The name `main` is reserved.

<Tabs>
  <Tab title="Astro UI">
    1. In the Astro UI, click **Deployments**, then select a Deployment.
    2. Click **Bundles**, then click **Dag**.
    3. Click **New Dag bundle**.
    4. Enter a **Name**, optionally add a **Description**, then click **Create bundle**.
  </Tab>

  <Tab title="Astro CLI">
    Run [`astro deployment bundle create`](/docs/cli/v1.46/astro-deployment-bundle-create):

    ```bash theme={null}
    astro deployment bundle create --deployment-id <deployment-id> --name finance
    ```
  </Tab>
</Tabs>

A new Dag bundle has no version until you deploy to it. Until then, it's registered on the Deployment but isn't served to Airflow.

## Deploy Dags to a named bundle

Use the `--dag-bundle-name` flag to target a bundle:

```bash theme={null}
astro deploy <deployment-id> --dags --dag-bundle-name finance
```

The bundle must already exist. If it doesn't, the deploy fails and the Astro CLI tells you to create it first.

Without `--dag-bundle-name`, a Dag deploy targets `main`, so existing commands and CI/CD pipelines keep working unchanged:

```bash theme={null}
astro deploy <deployment-id> --dags
```

Each bundle replaces its own contents on deploy. Deploying to `finance` replaces the Dags in `finance` and leaves every other bundle alone.

<Note>
  You can't use `--dag-bundle-name` with `--image`. Named bundles apply only to deploys that include Dags.
</Note>

## Deploy a non-Dag bundle

A non-Dag bundle is created the first time you deploy to a mount path that the Deployment hasn't seen before. To deploy one and choose where it mounts:

```bash theme={null}
astro deploy <deployment-id> --non-dags \
  --non-dags-mount-path /usr/local/airflow/dbt/revenue \
  --non-dags-bundle-type dbt
```

* `--non-dags-mount-path` is required. It's the absolute path the bundle mounts at on your Airflow components, and it's how Astro identifies the bundle. It can't overlap `/usr/local/airflow/dags`.
* `--non-dags-bundle-type` is a free-form label, such as `dbt`. It defaults to `none`.

A new non-Dag bundle is served alongside `main` unless you associate it with other Dag bundles. To change the association after the first deploy, update the bundle rather than redeploying it.

You can also register a non-Dag bundle before you deploy to it. In the Astro UI, click **Bundles**, click **Non-Dag**, then click **New non-Dag bundle** and set its **Mount path** and **Served alongside** bundles. The bundle stays empty until your first deploy to that mount path.

To deploy a dbt project with the dedicated dbt commands instead, see [Deploy dbt projects to Astro](/docs/astro/deploy-dbt-project).

## View the bundles on a Deployment

<Tabs>
  <Tab title="Astro UI">
    1. In the Astro UI, click **Deployments**, then select a Deployment.
    2. Click **Bundles**.
    3. Click **Dag** or **Non-Dag**.

    **Dag** lists each Dag bundle with its **Name**, **Description**, **Version**, and **Last deploy**. The bundle named `main` carries a **Default** badge.

    **Non-Dag** lists each non-Dag bundle with its **Mount path**, **Type**, **Description**, **Served alongside** Dag bundles, **Version**, and **Last deploy**.

    A bundle that's still rolling out shows a **Deploying** badge next to its version. A bundle you've deleted shows **Deletion pending** until your Deployment finishes removing it.
  </Tab>

  <Tab title="Astro CLI">
    ```bash theme={null}
    astro deployment bundle list --deployment-id <deployment-id>
    ```

    Add `--json` to get machine-readable output, which is useful in CI/CD:

    ```bash theme={null}
    astro deployment bundle list --deployment-id <deployment-id> --json
    ```
  </Tab>
</Tabs>

To confirm which bundle a Dag came from, open the Dag in the Airflow UI, click **Details**, then find **Bundle Name** under **Latest Dag Version**.

## Change which Dag bundles serve a non-Dag bundle

Set the complete list of Dag bundles you want the non-Dag bundle served alongside. The new list replaces the existing one and can't be empty.

<Tabs>
  <Tab title="Astro UI">
    1. In the Astro UI, click **Deployments**, then select a Deployment.
    2. Click **Bundles**, then click **Non-Dag**.
    3. Open the actions menu for the bundle, then click **Edit bundle**.
    4. Change **Served alongside**, then click **Save**.
  </Tab>

  <Tab title="Astro CLI">
    Run `astro deployment bundle list` first to get the Dag bundle IDs, then:

    ```bash theme={null}
    astro deployment bundle update --deployment-id <deployment-id> \
      --mount-path /usr/local/airflow/dbt/revenue \
      --dag-bundle-ids <dag-bundle-id>,<dag-bundle-id>
    ```
  </Tab>
</Tabs>

You can also update any bundle's description:

```bash theme={null}
astro deployment bundle update --deployment-id <deployment-id> --name finance --description "Finance team Dags"
```

A description is the only field you can change on a Dag bundle. Bundle names and mount paths are fixed after you create them.

## Delete a bundle

Deleting a Dag bundle stops Astro from serving its Dags to your Deployment. Airflow might then drop the Dag records for those Dags, and task runs still in flight might fail. Deleting a non-Dag bundle removes its files from the Airflow components that served it. Neither deletes your source code.

<Note>
  On Astro Runtime 3.0-1 through 3.2-4, Airflow doesn't remove a deleted bundle's Dag records automatically. Remove them manually after you delete the bundle.
</Note>

<Tabs>
  <Tab title="Astro UI">
    1. In the Astro UI, click **Deployments**, then select a Deployment.
    2. Click **Bundles**, then click **Dag** or **Non-Dag**.
    3. Open the actions menu for the bundle you want to delete, then click **Delete bundle**.
    4. Enter the bundle's name, or its mount path for a non-Dag bundle, then click **Delete bundle**.
  </Tab>

  <Tab title="Astro CLI">
    ```bash theme={null}
    astro deployment bundle delete --deployment-id <deployment-id> --name finance
    ```

    For a non-Dag bundle, identify it by its mount path:

    ```bash theme={null}
    astro deployment bundle delete --deployment-id <deployment-id> --mount-path /usr/local/airflow/dbt/revenue
    ```

    Add `--force` to skip the confirmation prompt.
  </Tab>
</Tabs>

Two rules apply:

* You can't delete `main`.
* You can't delete a Dag bundle if that would leave a non-Dag bundle with no Dag bundle to be served alongside. Associate those non-Dag bundles with another Dag bundle, or delete them, first.

A deleted bundle stays visible with a pending-deletion state until your Deployment finishes removing it.

## Limits and requirements

| Item | Value |
| - | - |
| Bundles per Deployment | 200, counting Dag and non-Dag bundles together |
| Dag bundle name | 1-32 characters, lowercase letters, numbers, dashes, and underscores |
| Reserved Dag bundle name | `main` |
| Minimum Airflow version for named Dag bundles | Airflow 3 |
| Minimum Astro CLI version | 1.46 |

## Move a Dag to a different bundle

You can move a Dag from one bundle to another and keep its history. To do this, deploy the destination bundle before you deploy the source bundle, so the Dag is never missing from Airflow. In the following steps, the Dag moves from bundle A to bundle B:

1. In your project, move the Dag file from bundle A's Dag folder to bundle B's Dag folder.

2. Deploy bundle B's Dag folder to bundle B:

   ```bash theme={null}
   astro deploy <deployment-id> --dags --dag-bundle-name <bundle-b>
   ```

3. Deploy bundle A's Dag folder to bundle A:

   ```bash theme={null}
   astro deploy <deployment-id> --dags --dag-bundle-name <bundle-a>
   ```

To move a Dag out of the `main` bundle, use `main` as bundle A and omit `--dag-bundle-name` in step 3.

Between steps 2 and 3, the Dag ID exists in both bundles, so the bundle name that the Airflow UI shows for the Dag can alternate between the two. This is expected and ends after step 3, when the Airflow UI reports only bundle B. See [Dag IDs must be unique across bundles](#dag-ids-must-be-unique-across-bundles).

## Dag IDs must be unique across bundles

Airflow identifies a Dag by its Dag ID alone, so a Dag ID must be unique across every bundle on a Deployment, not only within one bundle.

If the same Dag ID exists in two bundles, the bundle that parsed most recently wins. That can change from one parse to the next, so the Dag can alternate between bundles. Any consistent behavior you observe isn't guaranteed to continue. On Airflow 3.4 and later, Airflow also records a duplicate Dag ID warning naming the other file and bundle.

Before you split code into bundles, check that you don't have duplicate Dag IDs across the repositories you're splitting.

## Deploy history and rollbacks

Each bundle deploy is its own entry in your Deployment's deploy history, recording which bundle it changed. See [Deploy history and rollbacks](/docs/astro/deploy-history).

Rollbacks apply to the whole Deployment, not to one bundle. Rolling back returns every bundle to the state captured in the deploy you select, which means:

* Bundles that changed after that deploy return to their earlier versions.
* Bundles you created after that deploy are deleted.
* Bundles you deleted after that deploy are restored.

Before the rollback runs, the confirmation lists every bundle it affects under **Bundles affected**, and every bundle it removes under **Bundles to be deleted**.

## See also

* [Deploy Dags](/docs/astro/deploy-dags)
* [Deploy dbt projects to Astro](/docs/astro/deploy-dbt-project)
* [Deploy history and rollbacks](/docs/astro/deploy-history)
* [Deploy code to Astro](/docs/astro/deploy-code)
* [Develop a CI/CD workflow for deploying code to Astro](/docs/astro/set-up-ci-cd)
* [Choose a code repository strategy](/docs/astro/best-practices/repo-structure)
