> ## 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.

# Authenticated Docker builds

If your Docker build pulls packages from Anaconda channels that require authentication, the build will fail unless the conda client inside the image can authenticate. However, including credentials in a Docker build introduces risk—secrets can leak into image layers or get committed to version control if not handled properly.

This guide shows you how to write a Dockerfile that authenticates to Anaconda channels using secure build secrets, keeping your credentials out of the final image.

## Authentication and API keys

Pulling packages from authenticated Anaconda channels requires an API key—a long-lived, scoped token tied to your Anaconda account that grants read access to the channels that are available to you.

You can obtain an API key using either of the following methods:

> [tab] CLI
>
> Running `anaconda login` automatically generates an API key for you to authenticate your conda client for automated build systems.
>
> View the API key by running `anaconda auth api-key`. For more information, see the [anaconda-auth](https://anaconda.com/docs/cli-reference/anaconda-auth/getting-started.md) developer reference documentation.

> [tab] Web UI
>
> Create an API key from **Account Settings** in Anaconda Platform. For more information, see [API keys](https://anaconda.com/docs/anaconda-platform/user/api-keys.md).

> [!WARNING]
>
> For CI/CD workflows, store your API key in your CI provider's secrets storage (such as [GitHub Actions secrets](https://docs.github.com/en/actions/security-for-github-actions/security-guides/using-secrets-in-github-actions) or [GitLab CI/CD variables](https://docs.gitlab.com/ci/variables/)), expose it as the `ANACONDA_AUTH_API_KEY` environment variable in your workflow, and pass it to `docker build` with `--secret id=ANACONDA_AUTH_API_KEY`. Never hardcode secrets in Dockerfiles or commit them to version control.

## Writing the Dockerfile

The following steps walk through constructing a multi-stage Dockerfile that pulls packages from authenticated Anaconda channels and produces a minimal runtime image. Each step adds to the Dockerfile; the [complete example](#complete-example) at the end shows the finished result.

> [!NOTE]
>
> The `--mount=type=secret` syntax used in this guide requires [Docker BuildKit](https://docs.docker.com/build/buildkit/), which is the default build backend since Docker 23.0. If you are using an older version of Docker, you might need to enable BuildKit by setting `DOCKER_BUILDKIT=1` before running `docker build`.

**1. Choose a base image**

Anaconda provides several [base Docker images](https://github.com/anaconda/docker-images) for you to use as starting points.

Begin the Dockerfile by specifying a base image with conda pre-installed. Pin it to a specific version and assign it an alias so it can be referenced later in the Dockerfile:

```dockerfile theme={null}
FROM continuumio/miniconda3:v25.11.1-1 AS builder
```

**2. Install authentication support**

To authenticate to Anaconda channels during the build, install the `anaconda-registration` package. This package provides plugins that automatically read Docker build secrets and pass them as authentication headers to the repository backend.

Install it into the image's `base` environment before running any conda commands that require authentication:

```dockerfile theme={null}
RUN conda install --name base \
  --channel https://repo.anaconda.cloud/repo/anaconda-tools \
  --override-channels \
  anaconda-registration
```

**3. Define and install your dependencies**

1. Define your application's dependencies in an [environment.yml file](https://anaconda.com/docs/getting-started/working-with-conda/environments.md#creating-an-environment) and copy it into the image:

   ```dockerfile theme={null}
   COPY ./environment.yml ./environment.yml
   ```

2. Mount your API key as a build secret and create the environment. The mount syntax depends on how you plan to pass the secret when you [build the image](#building-the-image):

   > [tab] Environment variable
   >
   > ```dockerfile theme={null}
   > RUN --mount=type=secret,id=ANACONDA_AUTH_API_KEY \
   >   conda env create \
   >   --prefix /env \
   >   --file environment.yml
   > ```
   >
   > > [!NOTE]
   > >
   > > This expects a secret named `ANACONDA_AUTH_API_KEY` to be passed to `docker build`.

   > [tab] .env file
   >
   > If you prefer to store your API key in a file, mount it with `target=.env` as follows:
   >
   > ```dockerfile theme={null}
   > RUN --mount=type=secret,id=dotenv,target=.env \
   >   conda env create \
   >   --prefix /env \
   >   --file environment.yml
   > ```
   >
   > > [!NOTE]
   > >
   > > This expects a secret named `dotenv` pointing to a file that contains `ANACONDA_AUTH_API_KEY=<YOUR_API_KEY>`.

**4. Configure the runtime image**

At this point, the Dockerfile produces an image with two conda environments: `base` (from the Miniconda image) and your custom runtime at `/env`. Shipping `base` is unnecessary and inflates the final image size.

Adding a second stage to the Dockerfile solves this. Start from a minimal base image, copy only the runtime environment from the build stage, and then configure the entrypoint:

```dockerfile theme={null}
FROM debian:13.3-slim

COPY --from=builder /env /env
ENV PATH="/env/bin:${PATH}"

WORKDIR /app
COPY app.py ./

EXPOSE 8000
ENTRYPOINT ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "8000"]
```

> [!NOTE]
>
> The `COPY` and `ENTRYPOINT` values above are specific to this example. Adjust them to match your application's files and start up command.

The final image contains only your runtime environment and application code—no conda installation, no `base` environment, no build tools.

## Building the image

With the Dockerfile written, build the image by passing your API key as a build secret. The method here must match the secret mount syntax used in your Dockerfile:

> [tab] Environment variable
>
> When you pass `--secret id=ANACONDA_AUTH_API_KEY` to `docker build`, Docker automatically looks for an environment variable of the same name.
>
> ```sh Command theme={null}
> docker build --secret id=ANACONDA_AUTH_API_KEY -t <IMAGE_NAME> .
> ```
>
> ```sh One-liner (with CLI) theme={null}
> ANACONDA_AUTH_API_KEY=$(anaconda auth api-key) docker build --secret id=ANACONDA_AUTH_API_KEY -t <IMAGE_NAME> .
> ```
>
> Comments
>
> Replace \<IMAGE\_NAME> with the name you want to give your Docker image.
>
> > [!NOTE]
> >
> > The one-liner retrieves your key with `anaconda auth api-key` and passes it directly into the build.

> [tab] .env file
>
> Create a file (for example, `docker.env`) containing your API key:
>
> ```dotenv theme={null}
> ANACONDA_AUTH_API_KEY=<YOUR_API_KEY>
> ```
>
> Then pass the file as a secret when building:
>
> ```sh theme={null}
> docker build --secret id=dotenv,src=./docker.env -t <IMAGE_NAME> .
> ```
>
> Comments
>
> Replace \<IMAGE\_NAME> with the name you want to give your Docker image.

> [!TIP]
>
> For the full list of options for passing build secrets, see the [Docker build secrets documentation](https://docs.docker.com/build/building/secrets/).

## Complete example

The following Dockerfile is based on the [conda.Dockerfile](https://github.com/anaconda/docker-examples/blob/main/examples/conda.Dockerfile) example.

```dockerfile expandable theme={null}
# Create the runtime conda environment
FROM continuumio/miniconda3:v25.11.1-1 AS builder

COPY ./environment.yml ./environment.yml

# Install the registration plugin for authenticated channel access
RUN conda install --name base anaconda-registration \
  --channel https://repo.anaconda.cloud/repo/anaconda-tools \
  --override-channels

# Mount the API key as a build secret and create the runtime environment
RUN --mount=type=secret,id=ANACONDA_AUTH_API_KEY \
  conda env create \
  --prefix /env \
  --file environment.yml

# Copy the environment into a minimal base image
FROM debian:13.3-slim

COPY --from=builder /env /env
ENV PATH="/env/bin:${PATH}"

WORKDIR /app
COPY app.py ./

EXPOSE 8000
ENTRYPOINT ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "8000"]
```

Build the image by passing your API key as a build secret:

```sh theme={null}
docker build --secret id=ANACONDA_AUTH_API_KEY -t my-app .
```

## Additional examples

The [anaconda/docker-examples](https://github.com/anaconda/docker-examples) repository provides additional working examples, including conda-lock and `.env` file workflows. Contributions are welcome.
