Deploying Braintrust with Docker

This guide walks through the process of deploying Braintrust through Docker. Broadly, we support two configurations:

  • [Recommended] API: deploys the backend data service of the application through docker. If you choose this option, then all of your data will be stored in the docker containers, and our servers will never be able to access it. However, you'll still be able to visit Braintrust through, and your browser will communicate with the API server running in docker directly. This is analogous to the self-hosted AWS configuration.

  • Full: a heavier-weight configuration that deploys the entire Braintrust application in a standalone fashion, including the API, web app, and auxiliary services. Choose the full configuration if you do not wish to rely on any centrally hosted components. If you plan to run this configuration in production, please reach out to us so we can work out how to best support you.

The files necessary for launching these deployments are hosted on GitHub. The repository contains a docker compose configuration file for each deployment, as well as a .env file you can customize (if needed).

To get started, just pull down the deployment repo, pick a docker-compose file, and launch Braintrust! The rest of this guide walks through the details of each configuration.

API vs. Full configuration

The primary difference between the two options is that the API configuration allows you to host the most sensitive data in docker, behind an API which changes infrequently (you need to update roughly 1-2 times per month), while allowing the Braintrust team to host the web app and metadata database which are updated multiple times per day. On the other hand, the full configuration allows you to host the webserver and metadata database in your own environment, ensuring total isolation, but with additional maintenance overhead.

To clarify which data is stored in which location, here is a breakdown of the data stored in each place:

Experiment records (input, output, expected, scores, metadata, traces, spans)DockerDocker
Log records (input, output, expected, scores, metadata, traces, spans)DockerDocker
Dataset records (input, output, metadata)DockerDocker
Prompt playground promptsDockerDocker
Prompt playground completionsDockerDocker
Human review scoresDockerDocker
Experiment and dataset namesGlobalDocker
Project namesGlobalDocker
Project settingsGlobalDocker
Git metadata about experimentsGlobalDocker
Organization info (name, settings)GlobalDocker
Login info (name, email, avatar URL)GlobalDocker
Auth credentialsAWS Cognito (SSO, passwords)Docker (password)
API keys (hashed)GlobalDocker
LLM provider secrets (encrypted)GlobalDocker

API configuration

To launch the API configuration:

git clone
cd braintrust-deployment/docker
docker compose -f docker-compose.api.yml pull
docker compose -f docker-compose.api.yml up -d --remove-orphans

The services can be shutdown with docker compose as well:

docker compose -f docker-compose.api.yml down

Once you have started the docker containers, navigate to the API URL section of the settings page. Enter the URL of your server in the "API URL" section. The docker server defaults to http://localhost:8000, which will work as long as the browser is running on the same machine as the API server. The port can be configured in the .env file.

API URL settings page

If the browser is successfully able to connect to your server, you should see the message "API ping successful". At this point, you should be able to use Braintrust as usual!

If this is your first time using Braintrust, you may want to go through the quickstart guide next.

Setting up HTTPS

If you wish to deploy the API server to a non-localhost URL, it will need to be exposed on an HTTPS endpoint. A common way to accomplish this is to obtain an SSL certificate for your domain, and forward traffic to your API server using a reverse proxy, such as nginx.

Full configuration

To run the full stack in Docker, in addition to the API, you need to run the Braintrust web servers and the metadata database. The web servers run in docker containers managed in docker-compose.full.yml, while the metadata database uses Supabase, which is launched as a separate set of containers. To download and launch the full configuration:

# Launch Braintrust containers.
git clone
cd braintrust-deployment/docker
docker compose -f docker-compose.full.yml pull
docker compose -f docker-compose.full.yml up -d --remove-orphans
# Launch Supabase.
cd ../..
cd braintrust-supabase
npm install
npx supabase start
npx supabase migration up

Launching supabase requires having NodeJS and npm installed (version >= 18). See the NodeJS docs for installation instructions. Alternatively, see the Supabase CLI docs for instructions on how to install the CLI as a standalone binary.

The braintrust cluster can be shutdown with docker compose, and the supabase cluster can be shutdown with npx:

# Shutdown Braintrust.
cd braintrust-deployment/docker
docker compose -f docker-compose.full.yml down
# Shutdown Supabase.
cd ../../braintrust-supabase
npx supabase stop

The repository includes a Makefile in the braintrust-supabase directory for starting and stopping Supabase. You can run make up to start Supabase and make down to stop it.

At this point, the app should be accessible at the PUBLIC_BASE_DOMAIN in your .env file (defaults to localhost). When you navigate to the sign-in page, instead of the normal third-party authentication workflow, you should see a field to provide an API key:

API Key Signin Page

To create the very first API key, you can curl a webserver in the Braintrust Docker cluster (specifically the braintrust-standalone-aux service). The webserver is listening on port 8100 and is password-protected by the CONTAINER_SERVER_SECRET environment variable defined in your .env file. To create an API key, simply curl the webserver, with a JSON payload describing the org and user the key is associated with:

curl "http://localhost:8100/create-api-key" -H "Authorization: Bearer [CONTAINER_SERVER_SECRET]" -d '{"org_name": "[YOUR_ORG_NAME]", "user_email": "[YOUR_USER_EMAIL]"}'

You can edit the options in .env at any time. Just make sure to restart the Braintrust Docker cluster for the changes to take effect.

The server should respond with an API key, that you can copy-paste into the sign-in page. Once you have logged in, you can create further API keys using the Settings page, or continue to use the webserver if you need to create new organizations or users.


The standard google auth signin workflow is not enabled for the local fullstack deployment because the authentication redirect URLs are externally fixed. Make sure to keep track of the API key you created above for future logins.

At this point, you should be able to use the full Braintrust application as usual! If this is your first time using Braintrust, you may want to go through the quickstart guide next.


The state of the Braintrust deployment is fully managed on docker. Therefore, if something is not running as expected, you should be able to inspect the container, either by dumping its logs or opening up a shell inside the container to poke around. For instance, after launching the API configuration, you should see three containers:

% docker ps
CONTAINER ID   IMAGE                                             COMMAND                  CREATED          STATUS                    PORTS                    NAMES
c67b49727823   "python entrypoint_a…"   16 minutes ago   Up 16 minutes   >8000/tcp   bt-docker-braintrust-standalone-api-1
6ed70334c6cf         "docker-entrypoint.s…"   16 minutes ago   Up 16 minutes (healthy)>5432/tcp   bt-docker-braintrust-postgres-1
37840f55bfd5            "docker-entrypoint.s…"   16 minutes ago   Up 16 minutes (healthy)>6379/tcp   bt-docker-braintrust-redis-1

You can dump the logs of the API container using docker logs [CONTAINER ID], or spawn a shell inside the container using docker exec -it [CONTAINER ID] bash. For further questions, feel free to reach out at