breadboard-ai / breadboard

A library for prototyping generative AI applications.
Apache License 2.0
160 stars 22 forks source link

[board-server] Allow Board Server to run in a container as a self-contained deployment #2889

Closed wfaithfull closed 2 weeks ago

wfaithfull commented 3 weeks ago

The Board Server is an incredibly exciting development for the share-ability of boards, but currently the means of deploying it is very GCP-centric, and the storage depends on Firestore. I would like to:

timswanson-google commented 3 weeks ago

@aomarks has been looking at this

wfaithfull commented 3 weeks ago

Is there a duplicate issue? I didn't spot one. @aomarks let me know what you've already done towards this - I've got a branch going but I will happily defer that and/or contribute into work you already have if you are further along this objective.

aomarks commented 3 weeks ago

Is there a duplicate issue? I didn't spot one. @aomarks let me know what you've already done towards this - I've got a branch going but I will happily defer that and/or contribute into work you already have if you are further along this objective.

Nope, I was just looking into this yesterday for the first time. All I've got is this quick first stab at a Dockerfile for the visual editor:

FROM node:20
WORKDIR /app
RUN git clone https://github.com/breadboard-ai/breadboard.git . -b @breadboard-ai/visual-editor@1.14.0
RUN npm ci
WORKDIR packages/visual-editor
RUN npm run build
CMD ["npm", "run", "serve", "--", "--host=0.0.0.0"]

One thing I was pondering was whether the Dockerfile should pull source directly from GitHub like I did above, or go through npm? I think I lean towards the GitHub approach since it lets you switch branches without a publish step, provides a reliable/self-documenting path back to the source, and is just one less layer of infrastructure to think about.

Could you share your branch @wfaithfull to compare?

wfaithfull commented 3 weeks ago

Bulk of my changes are here: reimplementing Store with a SQLite backend instead of firestore. ⚠️ here be dragons, very much WIP ⚠️

I've focussed exclusively so far on breaking the dependency on firestore rather than on containerising - because I want the whole thing to be able to be self-contained as a deployment. For the container question I think it's a question of where we intend to publish the resulting image from - if we publish it from a github action here into GHCR.io, I think it definitely makes sense that we take the github approach. If I was going to publish a dockerfile as an independent third party I might differ.

timswanson-google commented 3 weeks ago

Tangential to this issue (specifically wrt not depending on Firestore), I've filed #2896 to stop using Firestore for CORS config.

wfaithfull commented 3 weeks ago

First successful test run of a fully self-contained, containerised board server with SQLite storage, running in a container.

(base) ➜  board-server git:(2889-board-server-sqlite) ✗ docker run -e GOOGLE_CLOUD_PROJECT=foo -p 3000:3000 board-server

> @breadboard-ai/board-server@0.4.6 serve
> wireit --host=0.0.0.0

Analyzing
 71% [12 / 17] [0 running] [0 services]
Running on "http://localhost:3000"...
100% [17 / 17] [1 running] [1 service] serve
(base) ➜  board-server git:(2889-board-server-sqlite) ✗ curl -s localhost:3000/boards | jq 
[
  {
    "title": "test",
    "path": "wfaithfull/test.json",
    "username": "wfaithfull",
    "readonly": true,
    "mine": false,
    "tags": "published"
  }
]

For the moment, my dockerfile definition looks like so:

FROM node:20
COPY --from=breadboard . /breadboard/
WORKDIR /breadboard
RUN npm ci
WORKDIR /breadboard/packages/board-server
RUN npm run build
CMD ["npm", "run", "serve", "--", "--host=0.0.0.0"]

This build context malarky is a little ugly but preferable in order to allow the dockerfile to build within the context of the board-server package (since docker doesn't allow straightforward operations like ../ in the build context). You can build it like so:

docker build --build-context breadboard=../../ -t board-server .

I'll refine this a bit more but it's a good start.

wfaithfull commented 2 weeks ago

Some updates since I just merged in @timswanson-google's changes adding a ServerConfig object.

So I'm adding some integration tests, for that reason I've broken out the "server start" machinery into a separate file so that I can call it from tests to bootstrap a server to test against:

https://github.com/ExaDev/breadboard/blob/2889-board-server-sqlite/packages/board-server/src/index.ts

Secondly, I've added some global error handling & 500 responses to the router so that the whole thing doesn't crash on unhandled exceptions.

https://github.com/ExaDev/breadboard/blob/2889-board-server-sqlite/packages/board-server/src/router.ts#L16

timswanson-google commented 2 weeks ago

Thanks Will. Can we get that minimal change ("server start" to server.ts) pulled into the breadboard-ai main branch? I'd like to make a change on top of it for #2896.

wfaithfull commented 2 weeks ago

I have to go to something in 15 minutes I'm afraid so I'm not going to get around to that until tomorrow... you can pick it off my branch if you like and roll it in from your branch? I am happy to accept the merge pain 😄

timswanson-google commented 2 weeks ago

Will do, thanks

timswanson-google commented 2 weeks ago

Merged #2905 into main. Since I'm no git wizard, I did it the old fashioned way using copy-paste.