Skip to main content
Your config.yaml is the declarative surface for everything your model bundles, builds, and pulls. Use it to include custom Python packages, run shell commands during the build, swap in a custom Docker base image, and authenticate to private registries.

Python packages

Truss lets you include custom modules or third-party packages not available on PyPI using two methods:
  1. The packages directory: for bundling small, Truss-specific packages.
  2. The external_package_dirs configuration: for sharing packages across multiple Trusses.

Use the packages directory

Each Truss includes a packages/ directory where you place Python modules to include at build time. Use this method for lightweight, Truss-specific packages. Example directory structure:
Project structure
Importing a package in model.py:
model.py

Use external_package_dirs

If multiple Trusses need access to the same external package, define external_package_dirs in config.yaml. A package here refers to an importable directory with Python source code. Example directory structure:
Project structure
Configuring external_package_dirs in config.yaml:
config.yaml
Paths must be relative to config.yaml.
Include any requirements for these packages in your Truss configuration. Referencing external packages in model.py:
model.py

Build commands

The build_commands feature runs custom Docker commands during the build stage, enabling advanced caching, dependency management, and environment setup. Use cases:
  • Clone GitHub repositories.
  • Install dependencies.
  • Create directories.
  • Pre-download model weights.

Run build commands in config.yaml

Add build_commands to your config.yaml:
config.yaml
This clones the GitHub repository, checks out the specified commit, and installs dependencies. Everything is cached at build time, reducing deployment cold starts.

Create directories

Use build_commands to create directories directly in the container. This is useful for large codebases requiring additional structure.
config.yaml

Cache model weights efficiently

For large weights (10GB+), use the Baseten Delivery Network (BDN) instead of baking them into the image.
For smaller weights, use wget in build_commands:
config.yaml
Preloading model weights during the build stage reduces startup time and ensures availability without runtime downloads.

Run any shell command

build_commands runs any shell command at build time and caches the result, so it doesn’t re-run on every cold start.

Base images

Use a custom base image when you need specific system packages or a different runtime than the default Truss image provides.

Set a base image in config.yaml

Specify a custom base image in config.yaml:
config.yaml
  • image: the Docker image to use.
  • python_executable_path: the path to the Python binary inside the container.

NVIDIA NeMo model

Use a custom image to deploy the NVIDIA NeMo TitaNet model:
config.yaml

Use private base images

If your base image is private, configure your model to use a private registry.

Create a custom base image

Build a new base image using Truss’s base images as a foundation. Available images are listed on Docker Hub.

Customize a Truss base image

Dockerfile

Build and push your custom image

Ensure Docker is installed and running. Then build, tag, and push your image:
Terminal

Private registries

When deploying a custom base image or custom server from a private registry, grant Baseten access to pull the image. For AWS ECR and Google Cloud registries, configure docker_auth in config.yaml with OIDC (recommended), IAM, or a service account. For every other registry, store credentials as a Baseten secret named DOCKER_REGISTRY_<registry-host>, where <registry-host> matches the hostname in your image URL. For a registry not listed below, see Other registries. The value of a DOCKER_REGISTRY_* secret must be the Base64 encoding of username:password; a raw token or personal access token won’t work. Baseten validates the value when you save the secret and rejects values that aren’t Base64 or don’t decode to a username:password pair.

AWS Elastic Container Registry (ECR)

AWS supports three authentication methods: OIDC (recommended), IAM service accounts, and access tokens. OIDC provides short-lived, narrowly scoped tokens for secure authentication without managing long-lived credentials. To authenticate to ECR with AWS OIDC:
  1. Configure AWS to trust the Baseten OIDC provider and create an IAM role with ECR permissions.
  2. Add the OIDC configuration to your config.yaml:
config.yaml
No secrets needed. The aws_oidc_role_arn and aws_oidc_region are not sensitive and can be committed to your repository.
See the OIDC authentication guide for detailed setup instructions and best practices.

AWS IAM service accounts

To authenticate to ECR with an IAM service account (long-lived access):
  1. Get an AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY from the AWS dashboard.
  2. Add these as secrets in Baseten. Name them aws_access_key_id and aws_secret_access_key.
  3. Configure docker_auth in your config.yaml:
config.yaml
The registry value must match the hostname portion of the image URL. To use different secret names, configure the aws_access_key_id_secret_name and aws_secret_access_key_secret_name options under docker_auth:
config.yaml

Access token

To authenticate to ECR with an access token:
  1. Get the Base64-encoded secret:
Terminal
  1. Add a new secret to Baseten named DOCKER_REGISTRY_<aws-account-id>.dkr.ecr.<region>.amazonaws.com with the Base64-encoded secret as the value.
  2. Add the secret name to the secrets section of config.yaml:
config.yaml
ECR authorization tokens expire after 12 hours, so later builds fail until you update the secret. For a durable setup, use OIDC or an IAM service account instead.

Google Cloud Artifact Registry

GCP supports three authentication methods: OIDC (recommended), service accounts, and access tokens.
All three methods also work with Google Container Registry (gcr.io, <region>.gcr.io).
OIDC provides short-lived, narrowly scoped tokens for secure authentication without managing long-lived credentials. To authenticate to Artifact Registry with GCP OIDC:
  1. Configure GCP Workload Identity to trust the Baseten OIDC provider and grant Artifact Registry permissions.
  2. Add the OIDC configuration to your config.yaml:
config.yaml
No secrets needed. The service account and workload identity provider are not sensitive and can be committed to your repository.
See the OIDC authentication guide for detailed setup instructions and best practices.

Service account

To authenticate to Artifact Registry with a service account:
  1. Get your service account key as a JSON key blob.
  2. Add a new secret to Baseten named gcp-service-account (or similar) with the JSON key blob as the value.
  3. Add the secret name to the secrets section of config.yaml:
config.yaml
  1. Configure the docker_auth section of your base_image to use service account authentication:
config.yaml
secret_name must match the secret you created in step 2.

Access token

To authenticate to Artifact Registry with an access token:
  1. Get the Base64-encoded secret. The username is the literal string oauth2accesstoken:
Terminal
  1. Add a new secret to Baseten named DOCKER_REGISTRY_<region>-docker.pkg.dev with the Base64-encoded secret as the value.
  2. Add the secret name to the secrets section of config.yaml:
config.yaml
GCP access tokens expire after about an hour, so later builds fail until you update the secret. For a durable setup, use OIDC or a service account instead.

Docker Hub

To authenticate to Docker Hub:
  1. Get the Base64-encoded secret:
Terminal
  1. Add a new secret to Baseten named DOCKER_REGISTRY_https://index.docker.io/v1/ with the Base64-encoded secret as the value.
  1. Add the secret name to the secrets section of config.yaml:
config.yaml

GitHub Container Registry (GHCR)

To authenticate to GHCR:
  1. Create a GitHub Personal Access Token with the read:packages scope. Use a classic token, not fine-grained.
  2. Get the Base64-encoded secret:
Terminal
  1. Add a new secret to Baseten named DOCKER_REGISTRY_ghcr.io with the Base64-encoded secret as the value.
  1. Add the secret name to the secrets section of config.yaml:
config.yaml

NVIDIA NGC

To authenticate to NVIDIA NGC:
  1. Generate an NGC API Key from your NVIDIA NGC account.
  2. Get the Base64-encoded secret:
Terminal
The username $oauthtoken is a literal string, not a variable. Use it exactly as shown.
  1. Add a new secret to Baseten named DOCKER_REGISTRY_nvcr.io with the Base64-encoded secret as the value.
  1. Add the secret name to the secrets section of config.yaml:
config.yaml

Other registries

Any registry that supports docker login with a username and password works with a DOCKER_REGISTRY_* secret. To authenticate to any other private registry:
  1. Get the Base64-encoded secret:
Terminal
If your registry issues tokens or personal access tokens instead of passwords, pair the token with the username your registry’s documentation specifies for token logins. This is often a literal placeholder: NVIDIA NGC uses $oauthtoken, and some registries use -. Encoding the token by itself, without a username and colon, won’t authenticate.
  1. Add a new secret to Baseten named DOCKER_REGISTRY_<registry-host>, where <registry-host> matches the hostname in your image URL:
  1. Add the secret name to the secrets section of config.yaml:
config.yaml

Next steps

Configuration

The full set of config.yaml options for packages, resources, and the build environment.

Secrets

Store and reference API keys and registry credentials securely.

Custom servers

Run your own server image instead of the default Truss server.

Private registry access

Set up OIDC for short-lived, credential-free registry authentication.