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

# Fast Bakery

Fast Bakery is the platform's containerization backend. It packages the dependencies you declare with `@pypi` or `@conda` into reproducible container images automatically, so your flows deploy and scale without manual image builds. For background on how it works, see [Fast, Automatic Containerization of ML and AI Projects with Fast Bakery](https://www.anaconda.com/blog/containerize-with-fast-bakery).

To activate Fast Bakery, run or deploy a flow that uses `@pypi` or `@conda` with the `--environment=fast-bakery` flag:

```sh theme={null}
# For local Kubernetes runs
python flow.py --environment=fast-bakery run --with kubernetes

# For Argo Workflows
python flow.py --environment=fast-bakery argo-workflows create
python flow.py argo-workflows trigger
```

## Using private packages and registries

Out of the box, Fast Bakery resolves publicly available Python packages and can use any public image as a base image. To work with private Python packages, private conda channels, or private container images, create a resource integration that gives Fast Bakery access to your private sources, then register the repository or channel against that integration.

The sections below cover the most common scenarios. Each shows a canonical example; for the complete set of options for each command, see [Integration types](https://anaconda.com/docs/platform/cli/integrations/integration-types).

> [!NOTE]
>
> To run the commands in these sections, you must have:
>
> * The `outerbounds` CLI installed and configured. (See [Getting started with the platform CLI](https://anaconda.com/docs/platform/cli.md)).
> * Admin privileges on the platform.

### Private container image registries

Fast Bakery builds containers by pulling a base image first. To use a base image hosted in a private registry, create a `container-registry` integration.

For a private registry on Amazon ECR, there are two ways to grant access:

1. **Assumed role**: Create an IAM role with permissions to pull images from your ECR registry, configured to be assumable by the platform's task role, then create the integration with the role ARN:

   ```sh theme={null}
   outerbounds integrations container-registry create <INTEGRATION_NAME> \
     --description "<DESCRIPTION>" \
     --registry-domain <REGISTRY_DOMAIN> \
     --target-role-arn <ROLE_ARN>
   ```

   Comments

   Replace \<INTEGRATION\_NAME> with a name for the integration.\\

   Replace \<DESCRIPTION> with a short description of the registry.\\

   Replace \<REGISTRY\_DOMAIN> with your ECR registry domain, (Example: `123456789012.dkr.ecr.us-west-2.amazonaws.com/`).\\

   Replace \<ROLE\_ARN> with the ARN of the IAM role that can pull images from the registry.

2. **Task role**: Grant the perimeter's task IAM role permissions to pull images from your ECR registry, then create the integration with `--use-task-role`:

   ```sh theme={null}
   outerbounds integrations container-registry create <INTEGRATION_NAME> \
     --description "<DESCRIPTION>" \
     --registry-domain <REGISTRY_DOMAIN> \
     --use-task-role
   ```

   Comments

   Replace \<INTEGRATION\_NAME> with a name for the integration.\\

   Replace \<DESCRIPTION> with a short description of the registry.\\

   Replace \<REGISTRY\_DOMAIN> with your ECR registry domain.

   After the integration exists, you can use any image in the registry as a base image:

   ```python theme={null}
   @kubernetes(image="<REGISTRY_DOMAIN>/myimage:v0.1.0")
   @pypi(
       packages={
           "pandas": "2.3.3",
           "scikit-learn": "1.7.2",
       },
       python="3.12",
   )
   ```

#### GitLab container registry

For container images in a GitLab container registry, create the integration with username and password credentials:

```sh theme={null}
outerbounds integrations container-registry create <INTEGRATION_NAME> \
  --description "<DESCRIPTION>" \
  --registry-domain <REGISTRY_DOMAIN> \
  --username <USERNAME> \
  --password <PASSWORD>
```

Comments

Replace \<INTEGRATION\_NAME> with a name for the integration.\\

Replace \<DESCRIPTION> with a short description of the registry.\\

Replace \<REGISTRY\_DOMAIN> with the registry domain, for example `registry.gitlab.com/myorg/mygroup`.\\

Replace \<USERNAME> and \<PASSWORD> with credentials that have read access to the registry, such as a project access token or a personal access token.

To rotate the credentials, run the same command with `update` instead of `create` and pass the new credentials.

### Private PyPI packages

Fast Bakery supports private PyPI repositories by formulating `pip` index URLs with credentials for each build. The configuration follows the same pattern for every provider: create an integration for the provider, then register each private repository against it with `private-pypi-repositories add`.

#### AWS CodeArtifact

1. Create an IAM role with permissions to download packages from your CodeArtifact repositories, configured to be assumable by the platform's task role.

2. Create a `code-artifacts` integration:

   ```sh theme={null}
   outerbounds integrations code-artifacts create <INTEGRATION_NAME> \
     --description "<DESCRIPTION>" \
     --domain <DOMAIN> \
     --domain-owner <AWS_ACCOUNT_ID> \
     --aws-region <REGION> \
     --target-role <ROLE_ARN>
   ```

   Comments

   Replace \<INTEGRATION\_NAME> with a name for the integration.\\

   Replace \<DESCRIPTION> with a short description of the integration.\\

   Replace \<DOMAIN> with your CodeArtifact domain.\\

   Replace \<AWS\_ACCOUNT\_ID> with the AWS account ID that owns the domain.\\

   Replace \<REGION> with the AWS region of the repositories.\\

   Replace \<ROLE\_ARN> with the ARN of the IAM role from step 1.

3. Register each repository against the integration:

   ```sh theme={null}
   outerbounds integrations private-pypi-repositories add \
     --repository-name <REPOSITORY_NAME> \
     --repository-host-integration-name <INTEGRATION_NAME>
   ```

   Comments

   Replace \<REPOSITORY\_NAME> with the name of the CodeArtifact repository.\\

   Replace \<INTEGRATION\_NAME> with the name of the integration from step 2.

#### GitLab package registry

1. Generate credentials with read permissions for the GitLab package registry, such as a project access token or a personal access token.

2. Create a `gitlab-artifacts` integration:

   ```sh theme={null}
   outerbounds integrations gitlab-artifacts create <INTEGRATION_NAME> \
     --description "<DESCRIPTION>" \
     --gitlab-url <GITLAB_URL> \
     --project-id <PROJECT_ID> \
     --username <USERNAME> \
     --password <PASSWORD>
   ```

   Comments

   Replace \<INTEGRATION\_NAME> with a name for the integration.\\

   Replace \<DESCRIPTION> with a short description of the integration.\\

   Replace \<GITLAB\_URL> with your GitLab instance URL. Defaults to `gitlab.com`.\\

   Replace \<PROJECT\_ID> with the numeric ID of the GitLab project that hosts the packages.\\

   Replace \<USERNAME> and \<PASSWORD> with the credentials from step 1.

3. Register the repository:

   ```sh theme={null}
   outerbounds integrations private-pypi-repositories add \
     --repository-name <REPOSITORY_NAME> \
     --repository-host-integration-name <INTEGRATION_NAME>
   ```

   Comments

   Replace \<REPOSITORY\_NAME> with the repository name to register.\\

   Replace \<INTEGRATION\_NAME> with the name of the integration from step 2.

#### Azure DevOps Artifacts

Azure DevOps Artifacts supports two authentication approaches. With managed identity (recommended), grant the perimeter's managed identity access to your feed in Azure DevOps, then create the integration without credentials:

```sh theme={null}
outerbounds integrations azure-artifacts create <INTEGRATION_NAME> \
  --description "<DESCRIPTION>" \
  --organization <ORGANIZATION> \
  --project-name <PROJECT_NAME>
```

Comments

Replace \<INTEGRATION\_NAME> with a name for the integration.\\

Replace \<DESCRIPTION> with a short description of the integration.\\

Replace \<ORGANIZATION> with your Azure DevOps organization.\\

Replace \<PROJECT\_NAME> with the Azure DevOps project that hosts the feed.

With static credentials, pass a personal access token instead:

```sh theme={null}
outerbounds integrations azure-artifacts create <INTEGRATION_NAME> \
  --description "<DESCRIPTION>" \
  --organization <ORGANIZATION> \
  --project-name <PROJECT_NAME> \
  --username <USERNAME> \
  --password <PASSWORD>
```

Comments

Replace \<INTEGRATION\_NAME> with a name for the integration.\\

Replace \<DESCRIPTION> with a short description of the integration.\\

Replace \<ORGANIZATION> with your Azure DevOps organization.\\

Replace \<PROJECT\_NAME> with the Azure DevOps project that hosts the feed.\\

Replace \<USERNAME> and \<PASSWORD> with a personal access token that has read access to the feed.

In both cases, register each feed against the integration:

```sh theme={null}
outerbounds integrations private-pypi-repositories add \
  --repository-name <REPOSITORY_NAME> \
  --repository-host-integration-name <INTEGRATION_NAME>
```

Comments

Replace \<REPOSITORY\_NAME> with the name of the feed.\\

Replace \<INTEGRATION\_NAME> with the name of the integration.

#### Artifactory (JFrog)

1. Generate credentials for a user with permission to download packages from the PyPI repositories.

2. Create an `artifactory` integration:

   ```sh theme={null}
   outerbounds integrations artifactory create <INTEGRATION_NAME> \
     --description "<DESCRIPTION>" \
     --domain <DOMAIN> \
     --username <USERNAME> \
     --password <PASSWORD>
   ```

   Comments

   Replace \<INTEGRATION\_NAME> with a name for the integration.\\

   Replace \<DESCRIPTION> with a short description of the integration.\\

   Replace \<DOMAIN> with your Artifactory domain, for example `mycompany.jfrog.io`.\\

   Replace \<USERNAME> and \<PASSWORD> with the credentials from step 1.

3. Register each repository:

   ```sh theme={null}
   outerbounds integrations private-pypi-repositories add \
     --repository-name <REPOSITORY_NAME> \
     --repository-host-integration-name <INTEGRATION_NAME>
   ```

   Comments

   Replace \<REPOSITORY\_NAME> with the repository name to register.\\

   Replace \<INTEGRATION\_NAME> with the name of the integration from step 2.

### PyPI packages from private Git repositories

The `@pypi` decorator installs packages directly from private Git repositories:

```python theme={null}
@pypi(
    packages={
        "git+https://github.com/<ORG>/<REPO>.git@main": ""
    },
    python="3.12",
)
```

Comments

Replace \<ORG> and \<REPO> with the GitHub organization and repository that host the package.

To grant Fast Bakery access, create a `git-pypi-repository` integration with credentials that have read access to the repository:

```sh theme={null}
outerbounds integrations git-pypi-repository create <INTEGRATION_NAME> \
  --description "<DESCRIPTION>" \
  --repository-url <REPOSITORY_URL> \
  --username <USERNAME> \
  --password <PASSWORD>
```

Comments

Replace \<INTEGRATION\_NAME> with a name for the integration.\\

Replace \<DESCRIPTION> with a short description of the integration.\\

Replace \<REPOSITORY\_URL> with the repository or organization URL, for example `https://github.com/myorg`.\\

Replace \<USERNAME> and \<PASSWORD> with credentials that have read access to the repository.

Fast Bakery applies these credentials as a `git config` URL substitution, so you can scope them at the repository or organization level. This configuration also covers transitive dependencies that reference other private Git URLs.

### Private conda packages

Fast Bakery supports packages from private conda channels by formulating channel URLs with static or short-lived credentials for each build request. Artifactory is currently the only supported private conda channel provider.

1. Generate credentials for a user with permission to download packages from the private conda channels.

2. Create an `artifactory` integration:

   ```sh theme={null}
   outerbounds integrations artifactory create <INTEGRATION_NAME> \
     --description "<DESCRIPTION>" \
     --domain <DOMAIN> \
     --username <USERNAME> \
     --password <PASSWORD>
   ```

   Comments

   Replace \<INTEGRATION\_NAME> with a name for the integration.\\

   Replace \<DESCRIPTION> with a short description of the integration.\\

   Replace \<DOMAIN> with your Artifactory domain.\\

   Replace \<USERNAME> and \<PASSWORD> with the credentials from step 1.

3. Register each channel with `private-conda-channels add`:

   ```sh theme={null}
   outerbounds integrations private-conda-channels add \
     --repository-name <CHANNEL_NAME> \
     --repository-host-integration-name <INTEGRATION_NAME>
   ```

   Comments

   Replace \<CHANNEL\_NAME> with the name of the conda channel.\\

   Replace \<INTEGRATION\_NAME> with the name of the integration from step 2.

If your use case requires private network connectivity or a provider not covered here, contact Anaconda support.
