-
Notifications
You must be signed in to change notification settings - Fork 9
Open WebUI: Add full end-to-end example rig #1038
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
11 commits
Select commit
Hold shift + click to select a range
dc7cf27
Open WebUI: Add full end-to-end example rig
amotl a36c497
Open WebUI: Add missing `.env` file
amotl 56eb694
Open WebUI: Improve documentation
amotl 7b07179
Open WebUI: Address review suggestions by CodeRabbit
amotl bce6cf6
Open WebUI: Refactor bootstrapping code to `init` subdirectory
amotl 3c1de23
Open WebUI: Add basic software test and CI/GHA configuration
amotl b747ac1
Open WebUI: Update to MCPO v0.0.6
amotl ad8b384
Open WebUI: Configure »General » Advanced Parameters"
amotl 06c91e8
Open WebUI: Add Jupyter for code interpretation and execution
amotl 8e91e9e
Open WebUI: Streamline environment variables
amotl 357914e
Open WebUI: Update to CrateDB MCPO 0.0.7
amotl File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,56 @@ | ||
| name: "Open WebUI" | ||
|
|
||
| on: | ||
| pull_request: | ||
| paths: | ||
| - '.github/workflows/application-open-webui.yml' | ||
| - 'application/open-webui/**' | ||
| push: | ||
| branches: [ main ] | ||
| paths: | ||
| - '.github/workflows/application-open-webui.yml' | ||
| - 'application/open-webui/**' | ||
|
|
||
| # Allow job to be triggered manually. | ||
| workflow_dispatch: | ||
|
|
||
| # Run job each night after CrateDB nightly has been published. | ||
| #schedule: | ||
| # - cron: '0 3 * * *' | ||
|
|
||
| # Cancel in-progress jobs when pushing to the same branch. | ||
| concurrency: | ||
| cancel-in-progress: true | ||
| group: ${{ github.workflow }}-${{ github.ref }} | ||
|
|
||
| jobs: | ||
|
|
||
| test: | ||
| runs-on: ${{ matrix.os }} | ||
|
|
||
| strategy: | ||
| fail-fast: true | ||
| matrix: | ||
| os: [ "ubuntu-latest" ] | ||
|
|
||
| name: OS ${{ matrix.os }} | ||
|
|
||
| env: | ||
| OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} | ||
|
|
||
| steps: | ||
|
|
||
| - name: Acquire sources | ||
| uses: actions/checkout@v4 | ||
|
|
||
| - name: Validate application/open-webui | ||
| run: | | ||
| # TODO: Generalize invocation into `ngr` test runner. | ||
|
|
||
| # Invoke software stack. | ||
| cd application/open-webui | ||
| docker compose up --detach | ||
|
|
||
| # Invoke validation payload. | ||
| # TODO: Currently does not work on GHA. | ||
| # docker compose run --rm test |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| # ------------------------------------------ | ||
| # User configuration | ||
| # ------------------------------------------ | ||
|
|
||
| # Define your OpenAI API key here if you want to make it persistent. | ||
| # You can also use other models with Open WebUI, however that is | ||
| # currently out of the scope of this miniature rig. | ||
|
|
||
| # OPENAI_API_KEY=your_openai_api_key |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,131 @@ | ||
| # Use CrateDB with Open WebUI | ||
|
|
||
| ## About | ||
|
|
||
| A complete end-to-end rig including CrateDB, CrateDB MCPO, and Open WebUI, | ||
| including a touch of integration tests on CI/GHA. | ||
|
|
||
| This stack is intended solely for demonstration purposes and does **not** | ||
| implement any security hardening. Do **not** deploy it to production. | ||
|
|
||
| ## Introduction | ||
|
|
||
| [Open WebUI] is an extensible, feature-rich, and user-friendly self-hosted AI | ||
| platform designed to operate entirely offline. It supports various LLM runners | ||
| like Ollama and OpenAI-compatible APIs, with built-in inference engine for RAG, | ||
| making it a powerful AI deployment solution. | ||
|
|
||
| CrateDB MCPO is an adapter wrapper around the [CrateDB MCP] server. Because | ||
| Open WebUI uses [OpenAPI Tool Servers] to integrate external tooling and data | ||
| sources into LLM agents and workflows, standard MCP servers need to adapt to | ||
| how [Open WebUI MCP Support] works. | ||
|
|
||
| ## Usage | ||
|
|
||
| ### Sources | ||
|
|
||
| It is advised to clone the Git repository and run the demo stack from there. | ||
| In this spirit, it will be easy for you to receive updates. | ||
| ```shell | ||
| git clone https://github.com/crate/cratedb-examples | ||
| cd cratedb-examples/application/open-webui | ||
| ``` | ||
|
|
||
| ### Start services | ||
|
|
||
| Configure the API key for OpenAI within the `.env` file next to `compose.yml` | ||
| to make it persistent for unattended service operations. | ||
| ```dotenv | ||
| # .env | ||
| OPENAI_API_KEY=your_openai_api_key_here | ||
| ``` | ||
| Or export it for a one-off run: | ||
| ```shell | ||
| export OPENAI_API_KEY=your_openai_api_key_here | ||
| ``` | ||
|
|
||
| Spin up the software stack. On the first occasion, it will take a while to | ||
| download the OCI images and let Open WebUI do its thing when bootstrapping | ||
| the very first time. | ||
| ```shell | ||
| docker compose up | ||
| ``` | ||
|
|
||
| ### User interface | ||
|
|
||
| You can access the service's resources on those URLs. | ||
|
|
||
| - CrateDB: http://localhost:4200/ | ||
| - Open WebUI: http://localhost:6200/ | ||
|
|
||
| Explore the APIs here. | ||
|
|
||
| - CrateDB MCPO: | ||
| - Swagger: http://localhost:5200/docs | ||
| - OpenAPI: http://localhost:5200/openapi.json | ||
| - Open WebUI: | ||
| - Swagger: http://localhost:6200/docs | ||
| - OpenAPI: http://localhost:6200/openapi.json | ||
| - Jupyter: | ||
| - http://localhost:7200/ | ||
|
|
||
| ### Configure | ||
|
|
||
| To make the ensemble work well, you need to configure a few bits on the Open WebUI | ||
| user interface. | ||
|
|
||
| - Make sure to enable the "CrateDB" tool. The toggle switch is located within the | ||
| flyout menu on the left side of the query prompt, which can be opened using the | ||
| `More (+)` button. | ||
|
|
||
| - In the "Chat Controls" flyout widget, located in the top right corner of the page, | ||
| - make sure to enable `Function Calling: Native`, see [OPEN-WEBUI-15939], | ||
| - and dial down to `Temperature: 0.0`. | ||
|
|
||
| ### Example questions | ||
|
|
||
| Enjoy conversations with CrateDB (talk to your data) and its documentation | ||
| (talk to your knowledgebase). | ||
|
|
||
| - Text-to-SQL: _What is the average value for sensor 1?_ | ||
| - Knowledgebase: _How do I use CrateDB with SQLAlchemy?_ | ||
|
|
||
| ### Stop services | ||
| Tear down services. | ||
| ```shell | ||
| docker compose down | ||
| ``` | ||
| Delete all volumes. | ||
| ```shell | ||
| docker compose down --volumes | ||
| ``` | ||
| Delete individual volumes. | ||
| ```shell | ||
| docker volume rm open-webui_open-webui | ||
| ``` | ||
| ```shell | ||
| docker volume rm open-webui_cratedb | ||
| ``` | ||
|
|
||
| ### Jobs | ||
| Invoke individual jobs defined in the Compose file. | ||
| ```shell | ||
| export BUILDKIT_PROGRESS=plain | ||
| docker compose run --rm setup | ||
| docker compose run --rm test | ||
| ``` | ||
|
|
||
| ## What's inside | ||
|
|
||
| - `.env`: The dotenv file defines `OPENAI_API_KEY` for `compose.yml`. | ||
| - `compose.yml`: The service composition file defines four main services: | ||
| CrateDB, CrateDB MCPO, Open WebUI, and Jupyter. Helper jobs (setup, test, ...) | ||
| excluded for brevity. Use it with Docker or Podman. | ||
| - `init/`: Runtime configuration snippets. | ||
|
|
||
|
|
||
| [CrateDB MCP]: https://cratedb.com/docs/guide/integrate/mcp/cratedb-mcp.html | ||
| [OpenAPI Tool Servers]: https://docs.openwebui.com/openapi-servers/ | ||
| [Open WebUI]: https://docs.openwebui.com/ | ||
| [Open WebUI MCP Support]: https://docs.openwebui.com/openapi-servers/mcp/ | ||
| [OPEN-WEBUI-15939]: https://github.com/open-webui/open-webui/issues/15939#issuecomment-3108279768 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,179 @@ | ||
| # Use CrateDB with Open WebUI | ||
| # | ||
| # https://cratedb.com/docs/ | ||
| # https://docs.openwebui.com/getting-started/quick-start | ||
| --- | ||
| networks: | ||
| llm-demo: | ||
| name: llm-demo | ||
| driver: bridge | ||
|
|
||
| volumes: | ||
| cratedb: | ||
| open-webui: | ||
| jupyter: | ||
|
|
||
| services: | ||
|
|
||
| # ------- | ||
| # CrateDB | ||
| # ------- | ||
| cratedb: | ||
| image: docker.io/crate/crate:6.0.0 | ||
| environment: | ||
| CRATE_HEAP_SIZE: 2g | ||
| ports: | ||
| - "4200:4200" | ||
| - "5432:5432" | ||
| command: [ | ||
| "crate", | ||
| "-Cdiscovery.type=single-node", | ||
| "-Ccluster.routing.allocation.disk.threshold_enabled=false", | ||
| ] | ||
| networks: | ||
| - llm-demo | ||
| volumes: | ||
| - cratedb:/data | ||
| healthcheck: | ||
| test: [ "CMD", "curl", "--fail", "http://localhost:4200" ] | ||
| start_period: 3s | ||
| interval: 10s | ||
|
|
||
| # ------------ | ||
| # CrateDB MCPO | ||
| # ------------ | ||
| cratedb-mcpo: | ||
| image: ghcr.io/crate/cratedb-mcpo:0.0.7 | ||
| environment: | ||
| CRATEDB_CLUSTER_URL: http://crate:crate@cratedb:4200/ | ||
| ports: | ||
| - "5200:8000" | ||
| networks: | ||
| - llm-demo | ||
| healthcheck: | ||
| test: [ "CMD", "curl", "--fail", "http://localhost:8000/docs" ] | ||
| start_period: 3s | ||
| interval: 10s | ||
| depends_on: | ||
| cratedb: | ||
| condition: service_healthy | ||
|
|
||
| # ---------- | ||
| # Open WebUI | ||
| # ---------- | ||
| open-webui: | ||
| image: ghcr.io/open-webui/open-webui:0.6.18 | ||
| # https://docs.openwebui.com/getting-started/env-configuration | ||
| # https://docs.openwebui.com/getting-started/api-endpoints/#swagger-documentation-links | ||
| environment: | ||
| # From caller's environment or `.env` file. | ||
| OPENAI_API_KEY: ${OPENAI_API_KEY} | ||
| # Currently defined here. | ||
| ENABLE_SIGNUP: "false" | ||
| ENABLE_LOGIN_FORM: "false" | ||
| WEBUI_AUTH: "false" | ||
| DEFAULT_MODELS: "gpt-4.1" | ||
| DEFAULT_USER_ROLE: "admin" | ||
| ENABLE_CHANNELS: "true" | ||
| RESPONSE_WATERMARK: "This text is AI generated" | ||
| WEBUI_NAME: "CrateDB LLM Cockpit" | ||
| BYPASS_MODEL_ACCESS_CONTROL: "true" | ||
| ENABLE_OLLAMA_API: "false" | ||
| ENABLE_OPENAI_API: "true" | ||
| ENABLE_DIRECT_CONNECTIONS: "true" | ||
| ENV: "dev" | ||
| # Jupyter code execution and interpreter. | ||
| ENABLE_CODE_INTERPRETER: "true" | ||
| CODE_EXECUTION_ENGINE: "jupyter" | ||
| CODE_EXECUTION_JUPYTER_URL: "http://jupyter:8888" | ||
| CODE_EXECUTION_JUPYTER_AUTH: "token" | ||
| CODE_EXECUTION_JUPYTER_AUTH_TOKEN: "123456" | ||
| CODE_EXECUTION_JUPYTER_TIMEOUT: 60 | ||
| CODE_INTERPRETER_ENGINE: "jupyter" | ||
| CODE_INTERPRETER_JUPYTER_URL: "http://jupyter:8888" | ||
| CODE_INTERPRETER_JUPYTER_AUTH: "token" | ||
| CODE_INTERPRETER_JUPYTER_AUTH_TOKEN: "123456" | ||
| CODE_INTERPRETER_JUPYTER_TIMEOUT: 60 | ||
| ports: | ||
| - "6200:8080" | ||
| networks: | ||
| - llm-demo | ||
| volumes: | ||
| - open-webui:/app/backend/data | ||
| healthcheck: | ||
| test: [ "CMD", "curl", "--fail", "http://localhost:8080" ] | ||
| start_period: 3s | ||
| interval: 10s | ||
| retries: 60 | ||
| timeout: 90s | ||
| depends_on: | ||
| cratedb-mcpo: | ||
| condition: service_healthy | ||
| jupyter: | ||
| condition: service_healthy | ||
|
|
||
| # ------- | ||
| # Jupyter | ||
| # ------- | ||
| jupyter: | ||
| image: quay.io/jupyter/minimal-notebook:notebook-7.4.4 | ||
| # https://docs.openwebui.com/tutorials/jupyter/ | ||
| environment: | ||
| JUPYTER_ENABLE_LAB: "yes" | ||
| JUPYTER_TOKEN: "123456" | ||
| ports: | ||
| - "7200:8888" | ||
| networks: | ||
| - llm-demo | ||
| volumes: | ||
| - jupyter:/home/jovyan/work | ||
| healthcheck: | ||
| test: [ "CMD", "curl", "--fail", "http://localhost:8888" ] | ||
| start_period: 3s | ||
| interval: 10s | ||
| retries: 60 | ||
| timeout: 90s | ||
|
|
||
| # ----- | ||
| # Setup | ||
| # ----- | ||
| setup: | ||
| build: | ||
| context: init | ||
| command: bash /app/setup.sh | ||
| networks: | ||
| - llm-demo | ||
| depends_on: | ||
| cratedb: | ||
| condition: service_healthy | ||
| cratedb-mcpo: | ||
| condition: service_healthy | ||
| open-webui: | ||
| condition: service_healthy | ||
|
|
||
| # ---- | ||
| # Test | ||
| # ---- | ||
| test: | ||
| build: | ||
| context: init | ||
| command: bash /app/test.sh | ||
| networks: | ||
| - llm-demo | ||
| depends_on: | ||
| setup: | ||
| condition: service_completed_successfully | ||
| deploy: | ||
| replicas: 0 | ||
|
|
||
| # ------- | ||
| # Bundler | ||
| # ------- | ||
| # Wait for all defined services to be fully available by probing their health | ||
| # status, even when using `docker compose up --detach`. | ||
| # https://marcopeg.com/2019/docker-compose-healthcheck/ | ||
| start-dependencies: | ||
| image: docker.io/dadarek/wait-for-dependencies | ||
| depends_on: | ||
| setup: | ||
| condition: service_completed_successfully | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.