This feature was added in: v0.55.0.

This page assumes you’ve gone through the OpenAPI quickstart.

To deploy BAML as a RESTful API, you’ll need to do three things:

  • host your BAML functions in a Docker container
  • update your app to call it
  • run BAML and your app side-by-side using docker-compose

Read on to learn how to do this with docker-compose.

You can also run baml-cli in a subprocess from your app directly, and we may recommend this approach in the future. Please let us know if you’d like to see instructions for doing so, and in what language, by asking in Discord or on the GitHub issue.

Host your BAML functions in a Docker container

In the directory containing your baml_src/ directory, create a baml.Dockerfile to host your BAML functions in a Docker container:

BAML-over-HTTP is currently a preview feature. Please provide feedback either in Discord or on GitHub so that we can stabilize the feature and keep you updated!

baml.Dockerfile
1FROM node:20
2
3WORKDIR /app
4COPY baml_src/ .
5
6# If you want to pin to a specific version (which we recommend):
7# RUN npm install -g @boundaryml/baml@VERSION
8RUN npm install -g @boundaryml/baml
9
10CMD baml-cli serve --preview --port 2024

Assuming you intend to run your own application in a container, we recommend using docker-compose to run your app and BAML-over-HTTP side-by-side:

$docker compose up --build --force-recreate
docker-compose.yaml
1services:
2 baml-over-http:
3 build:
4 # This will build baml.Dockerfile when you run docker-compose up
5 context: .
6 dockerfile: baml.Dockerfile
7 healthcheck:
8 test: [ "CMD", "curl", "-f", "http://localhost:2024/_debug/ping" ]
9 interval: 1s
10 timeout: 100ms
11 retries: 3
12 # This allows you to 'curl localhost:2024/_debug/ping' from your machine,
13 # i.e. the Docker host
14 ports:
15 - "2024:2024"
16
17 debug-container:
18 image: amazonlinux:latest
19 depends_on:
20 # Wait until the baml-over-http healthcheck passes to start this container
21 baml-over-http:
22 condition: service_healthy
23 command: "curl -v http://baml-over-http:2024/_debug/ping"

To call the BAML server from your laptop (i.e. the host machine), you must use localhost:2024. You may only reach it as baml-over-http:2024 from within another Docker container.

To verify for yourself that BAML-over-HTTP is up and running, you can run:

$curl http://localhost:2024/_debug/ping

Update your app to call it

Update your code to use BOUNDARY_ENDPOINT, if set, as the endpoint for your BAML functions.

If you plan to use Boundary Cloud to host your BAML functions, you should also update it to use BOUNDARY_API_KEY.

1import (
2 "os"
3 baml "my-golang-app/baml_client"
4)
5
6func main() {
7 cfg := baml.NewConfiguration()
8 if boundaryEndpoint := os.Getenv("BOUNDARY_ENDPOINT"); boundaryEndpoint != "" {
9 cfg.BasePath = boundaryEndpoint
10 }
11 if boundaryApiKey := os.Getenv("BOUNDARY_API_KEY"); boundaryApiKey != "" {
12 cfg.DefaultHeader["Authorization"] = "Bearer " + boundaryApiKey
13 }
14 b := baml.NewAPIClient(cfg).DefaultAPI
15 // Use `b` to make API calls
16}

Run your app with docker-compose

Replace debug-container with the Dockerfile for your app in the docker-compose.yaml file:

1services:
2 baml-over-http:
3 build:
4 context: .
5 dockerfile: baml.Dockerfile
6 networks:
7 - my-app-network
8 healthcheck:
9 test: [ "CMD", "curl", "-f", "http://localhost:2024/_debug/ping" ]
10 interval: 1s
11 timeout: 100ms
12 retries: 3
13 ports:
14 - "2024:2024"
15
16 my-app:
17 build:
18 context: .
19 dockerfile: my-app.Dockerfile
20 depends_on:
21 baml-over-http:
22 condition: service_healthy
23 environment:
24 - BAML_ENDPOINT=http://baml-over-http:2024
25
26 debug-container:
27 image: amazonlinux:latest
28 depends_on:
29 baml-over-http:
30 condition: service_healthy
31 command: sh -c 'curl -v "$${BAML_ENDPOINT}/_debug/ping"'
32 environment:
33 - BAML_ENDPOINT=http://baml-over-http:2024

Additionally, you’ll want to make sure that you generate the BAML client at image build time, because baml_client/ should not be checked into your repo.

This means that in the CI workflow you use to push your Docker images, you’ll want to do something like this:

.github/workflows/build-image.yaml
1jobs:
2 build:
3 runs-on: ubuntu-latest
4 steps:
5 - uses: actions/checkout@v2
6 - name: Build the BAML client
7 run: |
8 set -eux
9 npx @boundaryml/baml generate
10 docker build -t my-app .

(Optional) Secure your BAML functions

To secure your BAML server, you can also set a password on it using the BAML_PASSWORD environment variable:

$BAML_PASSWORD=sk-baml-your-secret-password \
> baml-cli serve --preview --port 2024

This will require incoming requests to attach your specified password as authorization metadata. You can verify this by confirming that this returns 403 Forbidden:

$curl -v "http://localhost:2024/_debug/status"

If you attach your password to the request, you’ll see that it now returns 200 OK:

$export BAML_PASSWORD=sk-baml-your-secret-password
>curl "http://baml:${BAML_PASSWORD}@localhost:2024/_debug/status"

BAML_PASSWORD will secure all endpoints except /_debug/ping, so that you can always debug the reachability of your BAML server.