Deploying Braintrust with Docker

This guide walks through the process of deploying Braintrust through Docker. Braintrust's self-hosted deployment splits data into a control plane and a data plane. You can self-host the data plane without ever exposing any data to Braintrust's servers or team. The control plane includes the UI and some metadata, and your browser and SDK code communicate directly with the data plane. As a result, you can still visit Braintrust through https://braintrust.dev, but all data will be stored and processed in your own infrastructure.

We recognize that in certain scenarios, you may want the utmost isolation while testing our product and offer a "full" deployment mode that includes the control plane and data plane. This is only available for testing with the intent of using the hybrid configuration in production. Please reach out to support for more information.

The files necessary for launching the data plane deployment are hosted on GitHub. The repository contains a docker compose configuration file which you can deploy or use as a reference. If needed, you may customize the environment variables in the compose file to suit your deployment needs. Although the deployment uses Docker compose, in practice, you only need to deploy 1-2 containers and so you can deploy it however you'd like (on an instance, using Kubernetes, etc.).

To get started, just pull down the deployment repo and launch Braintrust!

Data plane configuration

To launch the data plane:

git clone https://github.com/braintrustdata/braintrust-deployment.git
cd braintrust-deployment/docker
docker compose -f docker-compose.api.yml pull
docker compose -f docker-compose.api.yml up -d --remove-orphans

Once it runs, you can verify the API is running with

curl http://localhost:8000/

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 external port can be configured by adjusting the first value of the port mapping in the compose 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.

Deploying other services

In addition to the API server, you may also deploy the realtime service through docker. The realtime server transfers end-to-end encrypted user data using a key that's only available to the data plane. Self-hosting may be desirable to have complete control over these services and ensure that sensitive data in any form goes through only your own servers.

The realtime service is bundled in the full configuration, and you can include it in the API configuration with minor modifications. The modified docker-compose.api.yml might look as follows:

services:
  braintrust-redis:
    # Same as before.
  braintrust-postgres:
    # Same as before.
  braintrust-standalone-api:
    # Same as before, except we add environment variables pointing the API
    # server to our deployed realtime service.
    environment:
      # We use `host.docker.internal` here because the docker container can only
      # access other services on the same host network through this domain.
      REALTIME_URL: http://host.docker.internal:8788
      # Make sure to leave the other environment variables in.
  braintrust-standalone-realtime:
    # Uncomment the `braintrust-standalone-realtime` block.

If you are deploying the realtime service on a different machine, make sure to adjust the URL set on the braintrust-standalone-api service accordingly. Finally, point the webapp to your realtime URL in the API URLs page .

You will want to use the publicly-accessible form of the URL, rather than the docker-accessible form, so make sure to substitute host.docker.internal with localhost if that applies.

The proxy is now bundled into the API, so you do not need to deploy it as a separate service, as long as your API is at least version 0.0.51.

All URL settings page

If you wish to deploy more services yourself, such as the webapp, you will likely want to switch to the full configuration.

Detailed reference

To see a full list of the containers and environment variables you can configure, see the docker-compose.api.yml file in the braintrust-deployment repository.

Troubleshooting

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   public.ecr.aws/braintrust/standalone-api:latest   "python entrypoint_a…"   16 minutes ago   Up 16 minutes             0.0.0.0:8000->8000/tcp   bt-docker-braintrust-standalone-api-1
6ed70334c6cf   public.ecr.aws/braintrust/postgres:latest         "docker-entrypoint.s…"   16 minutes ago   Up 16 minutes (healthy)   0.0.0.0:5532->5432/tcp   bt-docker-braintrust-postgres-1
37840f55bfd5   public.ecr.aws/braintrust/redis:latest            "docker-entrypoint.s…"   16 minutes ago   Up 16 minutes (healthy)   0.0.0.0:6479->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 support@braintrust.dev.

On this page