├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.yaml │ └── feature_request.yaml ├── labeler.yml └── workflows │ ├── build-images.yml │ ├── integration-test.yml │ ├── labeler.yml │ ├── lint.yml │ ├── manual-build-image.yml │ └── release.yml ├── .gitignore ├── CODEOWNERS ├── LICENSE ├── Makefile ├── README.md ├── RELEASE.md ├── bin └── minikube_cluster.sh ├── charts └── chromadb-chart │ ├── .helmignore │ ├── Chart.yaml │ ├── README.md │ ├── templates │ ├── NOTES.txt │ ├── _helpers.tpl │ ├── config.yaml │ ├── ingress.yaml │ ├── service.yaml │ ├── statefulset.yaml │ └── tests │ │ ├── test-api.yaml │ │ └── test-connection.yaml │ └── values.yaml ├── image ├── Dockerfile └── docker_entrypoint.sh ├── requirements.txt └── tests ├── __init__.py └── test_chroma.py /.github/ISSUE_TEMPLATE/bug_report.yaml: -------------------------------------------------------------------------------- 1 | name: 🐞 Bug Report 2 | description: File a bug report with ChromaDB Chart 3 | title: "[Bug]: " 4 | labels: ["bug", "triage"] 5 | # assignees: 6 | # - octocat 7 | body: 8 | - type: markdown 9 | attributes: 10 | value: | 11 | Thanks for taking the time to fill out this bug report! 12 | - type: dropdown 13 | id: chroma-version 14 | attributes: 15 | label: ChromaDB Version 16 | description: What is your chromaDB version? 17 | options: 18 | - 0.4.x 19 | - 0.5.x 20 | validations: 21 | required: true 22 | - type: dropdown 23 | id: kube-version 24 | attributes: 25 | label: Kubernetes Version 26 | description: What is your Kubernetes version? 27 | options: 28 | - 1.24.x 29 | - 1.25.x 30 | - 1.26.x 31 | - 1.27.x 32 | - 1.28.x 33 | - 1.29.x 34 | - 1.30.x 35 | - 1.31.x 36 | - 1.32.x 37 | validations: 38 | required: true 39 | - type: textarea 40 | id: what-happened 41 | attributes: 42 | label: What happened? 43 | description: Also tell us, what did you expect to happen? 44 | placeholder: Tell us what happened and a way to reproduce it (also specify chart version, chroma API version and kubernetes version) 45 | # value: "A bug happened!" 46 | validations: 47 | required: true 48 | - type: textarea 49 | id: versions 50 | attributes: 51 | label: Environment details 52 | description: Tell us about your environment setup. 53 | placeholder: On-prem k3s/minikube/kind, GKE, EKS, etc. 54 | validations: 55 | required: true 56 | - type: textarea 57 | id: logs 58 | attributes: 59 | label: Logs, Kubectl output, Manifests, etc. 60 | description: Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks. 61 | render: shell 62 | # - type: checkboxes 63 | # id: terms 64 | # attributes: 65 | # label: Code of Conduct 66 | # description: By submitting this issue, you agree to follow our [Code of Conduct](https://example.com) 67 | # options: 68 | # - label: I agree to follow this project's Code of Conduct 69 | # required: true 70 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.yaml: -------------------------------------------------------------------------------- 1 | name: "✨ Feature Request" 2 | description: Suggest an idea for ChromaDB Chart 3 | title: "[Feature Request]: " 4 | labels: ["enhancement", "triage"] 5 | body: 6 | - type: markdown 7 | attributes: 8 | value: | 9 | Thanks for taking the time to request this feature! 10 | - type: textarea 11 | id: problem 12 | attributes: 13 | label: Describe the problem 14 | description: Please provide a clear and concise description the problem this feature would solve. The more information you can provide here, the better. 15 | placeholder: I prefer if... 16 | validations: 17 | required: true 18 | - type: textarea 19 | id: solution 20 | attributes: 21 | label: Describe the proposed solution 22 | description: Please provide a clear and concise description of what you would like to happen. 23 | placeholder: I would like to see... 24 | validations: 25 | required: true 26 | - type: textarea 27 | id: alternatives 28 | attributes: 29 | label: Alternatives considered 30 | description: "Please provide a clear and concise description of any alternative solutions or features you've considered." 31 | - type: dropdown 32 | id: importance 33 | attributes: 34 | label: Importance 35 | description: How important is this feature to you? 36 | options: 37 | - nice to have 38 | - would make my life easier 39 | - I cannot run the chart without it 40 | validations: 41 | required: true 42 | - type: textarea 43 | id: additional-context 44 | attributes: 45 | label: Additional Information 46 | description: Add any other context or screenshots about the feature request here. 47 | -------------------------------------------------------------------------------- /.github/labeler.yml: -------------------------------------------------------------------------------- 1 | chart: 2 | - charts/chromadb-chart/* -------------------------------------------------------------------------------- /.github/workflows/build-images.yml: -------------------------------------------------------------------------------- 1 | name: Build Images 2 | 3 | on: 4 | push: 5 | branches: 6 | - release 7 | workflow_dispatch: 8 | 9 | env: 10 | REGISTRY: ghcr.io 11 | IMAGE_NAME: "ghcr.io/amikos-tech/chromadb-chart/chroma" 12 | LATEST_VERSION: "0.5.23" 13 | 14 | jobs: 15 | build-images: 16 | strategy: 17 | matrix: 18 | chroma-version: 19 | [ 20 | 0.4.9, 21 | 0.4.24, 22 | 0.5.23, 23 | ] 24 | runs-on: ubuntu-latest 25 | steps: 26 | - name: Checkout 27 | uses: actions/checkout@v2 28 | with: 29 | fetch-depth: 0 30 | - name: Log in to the Container registry 31 | uses: docker/login-action@v2.1.0 32 | with: 33 | registry: ${{ env.REGISTRY }} 34 | username: ${{ github.actor }} 35 | password: ${{ secrets.GITHUB_TOKEN }} 36 | - name: Docker meta 37 | id: meta 38 | uses: docker/metadata-action@v4 39 | with: 40 | images: ${{ env.IMAGE_NAME }} 41 | - name: Set up QEMU 42 | uses: docker/setup-qemu-action@v2 43 | - name: Set up Docker Buildx 44 | uses: docker/setup-buildx-action@v2 45 | - name: Build and push release Docker image 46 | uses: docker/build-push-action@v3.2.0 47 | if: ${{ env.LATEST_VERSION == matrix.chroma-version }} 48 | with: 49 | context: . 50 | file: image/Dockerfile 51 | push: true 52 | platforms: linux/amd64,linux/arm64 53 | build-args: | 54 | CHROMA_VERSION=${{ matrix.chroma-version }} 55 | tags: "${{ env.IMAGE_NAME }}:${{ matrix.chroma-version }},${{ env.IMAGE_NAME }}:latest" 56 | - name: Build and push release Docker image 57 | if: ${{ env.LATEST_VERSION != matrix.chroma-version }} 58 | uses: docker/build-push-action@v3.2.0 59 | with: 60 | context: . 61 | file: image/Dockerfile 62 | push: true 63 | platforms: linux/amd64,linux/arm64 64 | build-args: | 65 | CHROMA_VERSION=${{ matrix.chroma-version }} 66 | tags: "${{ env.IMAGE_NAME }}:${{ matrix.chroma-version }}" 67 | 68 | -------------------------------------------------------------------------------- /.github/workflows/integration-test.yml: -------------------------------------------------------------------------------- 1 | name: Integration test 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | paths: 8 | - charts/** 9 | - tests/** 10 | pull_request: 11 | branches: 12 | - main 13 | - '**' 14 | paths: 15 | - charts/** 16 | - tests/** 17 | workflow_dispatch: 18 | 19 | env: 20 | LATEST_VERSION: "1.0.10" 21 | jobs: 22 | integration-test: 23 | strategy: 24 | matrix: 25 | kubernetes-version: [1.23.0, 1.33.1] 26 | chroma-version: 27 | [ 28 | 0.6.3, 29 | 1.0.10, 30 | ] 31 | runs-on: ubuntu-latest 32 | steps: 33 | - name: Checkout 34 | uses: actions/checkout@v3 35 | 36 | - name: Install Helm 37 | uses: azure/setup-helm@v4.2.0 38 | 39 | - name: start minikube 40 | id: minikube 41 | uses: medyagh/setup-minikube@latest 42 | with: 43 | kubernetes-version: ${{ matrix.kubernetes-version }} 44 | - name: Install chromadb 45 | run: | 46 | set -e 47 | sleep 20 48 | helm install chromadb ./charts/chromadb-chart \ 49 | --set chromadb.isPersistent=true \ 50 | --set chromadb.allowReset=true \ 51 | --set chromadb.apiVersion=${{ matrix.chroma-version }} 52 | - name: Wait for deployment to be ready 53 | run: | 54 | kubectl wait \ 55 | --for=condition=ready pod \ 56 | --selector=app.kubernetes.io/name=chromadb \ 57 | --timeout=120s 58 | - name: Test 59 | run: | 60 | set -e 61 | kubectl get pods -A 62 | kubectl get svc -A 63 | helm test chromadb 64 | - name: Debug 65 | if: failure() 66 | run: | 67 | kubectl get pods -A 68 | kubectl get svc -A 69 | kubectl logs --selector=app.kubernetes.io/name=chromadb --previous 70 | - name: Setup tmate session 71 | if: failure() 72 | uses: mxschmitt/action-tmate@v3 73 | with: 74 | limit-access-to-actor: true 75 | -------------------------------------------------------------------------------- /.github/workflows/labeler.yml: -------------------------------------------------------------------------------- 1 | name: "Pull Request Labeler" 2 | on: 3 | pull_request: 4 | branches: 5 | - main 6 | - '**' 7 | 8 | jobs: 9 | triage: 10 | permissions: 11 | contents: read 12 | pull-requests: write 13 | runs-on: ubuntu-latest 14 | steps: 15 | - name: Checkout 16 | uses: actions/checkout@v2 17 | with: 18 | fetch-depth: 0 19 | - uses: actions/labeler@v4 -------------------------------------------------------------------------------- /.github/workflows/lint.yml: -------------------------------------------------------------------------------- 1 | name: Lint on PR 2 | on: 3 | pull_request: 4 | branches: 5 | - main 6 | - '**' 7 | paths: 8 | - charts/** 9 | workflow_dispatch: 10 | env: 11 | REGISTRY: ghcr.io 12 | IMAGE_NAME: "ghcr.io/amikos-tech/chromadb-chart/chroma" 13 | 14 | jobs: 15 | release: 16 | runs-on: ubuntu-latest 17 | steps: 18 | - name: Checkout 19 | uses: actions/checkout@v2 20 | with: 21 | fetch-depth: 0 22 | 23 | - name: Configure Git 24 | run: | 25 | git config user.name "$GITHUB_ACTOR" 26 | git config user.email "$GITHUB_ACTOR@users.noreply.github.com" 27 | 28 | - name: Install Helm 29 | uses: azure/setup-helm@v4.2.0 30 | 31 | - name: Lint chart 32 | id: helm-lint 33 | uses: helm/chart-testing-action@v2.6.1 34 | with: 35 | command: lint 36 | chart_path: charts/chromadb-chart 37 | -------------------------------------------------------------------------------- /.github/workflows/manual-build-image.yml: -------------------------------------------------------------------------------- 1 | name: Build Image - Manual 2 | 3 | on: 4 | workflow_dispatch: 5 | inputs: 6 | chroma-version: 7 | description: "Chroma version" 8 | required: true 9 | default: "0.5.23" 10 | type: string 11 | latest-version: 12 | description: "Set the latest version tag to this version" 13 | required: false 14 | default: false 15 | type: boolean 16 | ghcr-release: 17 | description: "Push to GHCR" 18 | required: false 19 | default: true 20 | type: boolean 21 | docker-release: 22 | description: "Push to Docker hub" 23 | required: false 24 | default: true 25 | type: boolean 26 | 27 | env: 28 | REGISTRY: ghcr.io 29 | IMAGE_NAME: "ghcr.io/amikos-tech/chromadb-chart/chroma" 30 | DH_IMAGE_NAME: "amikos/chroma" 31 | 32 | jobs: 33 | build-images: 34 | runs-on: ubuntu-latest 35 | steps: 36 | - name: Checkout 37 | uses: actions/checkout@v2 38 | with: 39 | fetch-depth: 0 40 | - name: Log in to the Container registry 41 | uses: docker/login-action@v2.1.0 42 | with: 43 | registry: ${{ env.REGISTRY }} 44 | username: ${{ github.actor }} 45 | password: ${{ secrets.GITHUB_TOKEN }} 46 | - name: Docker meta 47 | id: meta 48 | uses: docker/metadata-action@v4 49 | with: 50 | images: ${{ env.IMAGE_NAME }} 51 | - name: Set up QEMU 52 | uses: docker/setup-qemu-action@v2 53 | - name: Set up Docker Buildx 54 | uses: docker/setup-buildx-action@v2 55 | - name: Build and push release Docker image 56 | if: ${{ github.event.inputs.ghcr-release == true }} 57 | uses: docker/build-push-action@v3.2.0 58 | with: 59 | context: . 60 | file: image/Dockerfile 61 | push: true 62 | platforms: linux/amd64,linux/arm64 63 | build-args: | 64 | CHROMA_VERSION=${{ github.event.inputs.chroma-version }} 65 | tags: | 66 | ${{ env.IMAGE_NAME }}:${{ github.event.inputs.chroma-version }} 67 | - name: Build and push release Docker image 68 | if: ${{ github.event.inputs.latest-version == 'true' && github.event.inputs.ghcr-release == 'true' }} 69 | uses: docker/build-push-action@v3.2.0 70 | with: 71 | context: . 72 | file: image/Dockerfile 73 | push: true 74 | platforms: linux/amd64,linux/arm64 75 | build-args: | 76 | CHROMA_VERSION=${{ github.event.inputs.chroma-version }} 77 | tags: | 78 | ${{ env.IMAGE_NAME }}:${{ github.event.inputs.chroma-version }} 79 | ${{ env.IMAGE_NAME}}:latest 80 | - name: Login to DockerHub 81 | uses: docker/login-action@v1 82 | with: 83 | registry: docker.io 84 | username: ${{ secrets.DOCKERHUB_USERNAME }} 85 | password: ${{ secrets.DOCKERHUB_TOKEN }} 86 | - name: Build and push release Docker image 87 | if: ${{ github.event.inputs.docker-release == 'true' }} 88 | uses: docker/build-push-action@v3.2.0 89 | with: 90 | context: . 91 | file: image/Dockerfile 92 | push: true 93 | platforms: linux/amd64,linux/arm64 94 | build-args: | 95 | CHROMA_VERSION=${{ github.event.inputs.chroma-version }} 96 | tags: | 97 | ${{ env.DH_IMAGE_NAME }}:${{ github.event.inputs.chroma-version }} 98 | - name: Build and push release Docker image 99 | if: ${{ github.event.inputs.latest-version == 'true' && github.event.inputs.docker-release == 'true' }} 100 | uses: docker/build-push-action@v3.2.0 101 | with: 102 | context: . 103 | file: image/Dockerfile 104 | push: true 105 | platforms: linux/amd64,linux/arm64 106 | build-args: | 107 | CHROMA_VERSION=${{ github.event.inputs.chroma-version }} 108 | tags: | 109 | ${{ env.DH_IMAGE_NAME }}:${{ github.event.inputs.chroma-version }} 110 | ${{ env.DH_IMAGE_NAME }}:latest 111 | 112 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release Charts 2 | 3 | on: 4 | push: 5 | branches: 6 | - release 7 | workflow_dispatch: 8 | env: 9 | REGISTRY: ghcr.io 10 | IMAGE_NAME: "ghcr.io/amikos-tech/chromadb-chart/chroma" 11 | 12 | jobs: 13 | release: 14 | runs-on: ubuntu-latest 15 | steps: 16 | - name: Checkout 17 | uses: actions/checkout@v2 18 | with: 19 | fetch-depth: 0 20 | 21 | - name: Configure Git 22 | run: | 23 | git config user.name "$GITHUB_ACTOR" 24 | git config user.email "$GITHUB_ACTOR@users.noreply.github.com" 25 | 26 | - name: Install Helm 27 | uses: azure/setup-helm@v4.2.0 28 | 29 | - name: Run chart-releaser 30 | id: releaser 31 | uses: helm/chart-releaser-action@v1.6.0 32 | env: 33 | CR_TOKEN: "${{ secrets.GITHUB_TOKEN }}" 34 | 35 | - name: Latest release 36 | run: | 37 | echo "Latest release: ${{ steps.releaser.outputs.chart_version }}" 38 | echo "Changed charts: ${{ steps.releaser.outputs.changed_charts }}" 39 | - name: Log in to the Container registry 40 | # if: ${{ steps.releaser.outputs.changed_charts == '' }} 41 | uses: docker/login-action@v2.1.0 42 | with: 43 | registry: ${{ env.REGISTRY }} 44 | username: ${{ github.actor }} 45 | password: ${{ secrets.GITHUB_TOKEN }} 46 | - name: Docker meta 47 | id: meta 48 | uses: docker/metadata-action@v4 49 | with: 50 | images: ${{ env.IMAGE_NAME }} 51 | - name: Set up QEMU 52 | uses: docker/setup-qemu-action@v2 53 | - name: Set up Docker Buildx 54 | uses: docker/setup-buildx-action@v2 55 | - name: Build and push release Docker image 56 | # if: ${{ steps.releaser.outputs.changed_charts == '' }} 57 | uses: docker/build-push-action@v3.2.0 58 | with: 59 | context: . 60 | file: image/Dockerfile 61 | push: true 62 | platforms: linux/amd64,linux/arm64 63 | tags: "${{ env.IMAGE_NAME }}:latest" -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/* 2 | *.iws 3 | out/ 4 | .idea_modules/ 5 | atlassian-ide-plugin.xml 6 | .idea/replstate.xml 7 | .idea/sonarlint/ 8 | com_crashlytics_export_strings.xml 9 | crashlytics.properties 10 | crashlytics-build.properties 11 | fabric.properties 12 | .idea/httpRequests 13 | .idea/caches/build_file_checksums.ser 14 | __pycache__/ 15 | *.py[cod] 16 | *$py.class 17 | *.so 18 | .Python 19 | build/ 20 | develop-eggs/ 21 | dist/ 22 | downloads/ 23 | eggs/ 24 | .eggs/ 25 | lib/ 26 | lib64/ 27 | parts/ 28 | sdist/ 29 | var/ 30 | wheels/ 31 | share/python-wheels/ 32 | *.egg-info/ 33 | .installed.cfg 34 | *.egg 35 | MANIFEST 36 | *.manifest 37 | *.spec 38 | pip-log.txt 39 | pip-delete-this-directory.txt 40 | htmlcov/ 41 | .tox/ 42 | .nox/ 43 | .coverage 44 | .coverage.* 45 | .cache 46 | nosetests.xml 47 | coverage.xml 48 | *.cover 49 | *.py,cover 50 | .hypothesis/ 51 | .pytest_cache/ 52 | cover/ 53 | *.mo 54 | *.pot 55 | *.log 56 | local_settings.py 57 | db.sqlite3 58 | db.sqlite3-journal 59 | instance/ 60 | .webassets-cache 61 | .scrapy 62 | docs/_build/ 63 | .pybuilder/ 64 | target/ 65 | .ipynb_checkpoints 66 | profile_default/ 67 | ipython_config.py 68 | .pdm.toml 69 | __pypackages__/ 70 | celerybeat-schedule 71 | celerybeat.pid 72 | *.sage.py 73 | .env 74 | .venv 75 | env/ 76 | venv/ 77 | ENV/ 78 | env.bak/ 79 | venv.bak/ 80 | .spyderproject 81 | .spyproject 82 | .ropeproject 83 | /site 84 | .mypy_cache/ 85 | .dmypy.json 86 | dmypy.json 87 | .pyre/ 88 | .pytype/ 89 | cython_debug/ 90 | 91 | # macOS temporary files 92 | .DS_Store -------------------------------------------------------------------------------- /CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @tazarov -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Copyright (c) 2023 Amikos Tech Ltd. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: lint 2 | lint: 3 | helm lint charts/chromadb-chart -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Kubernetes Chart for Chroma AI application database 2 | 3 | [![Artifact Hub](https://img.shields.io/endpoint?url=https://artifacthub.io/badge/repository/chromadb-helm)](https://artifacthub.io/packages/search?repo=chromadb-helm) 4 | 5 | This chart deploys a single-node Chroma database on a Kubernetes cluster using the Helm package manager. 6 | 7 | > [!TIP] 8 | > Deploying and managing multiple Chroma nodes support will arrive with 9 | > the [Chroma single-node Operator](https://github.com/amikos-tech/chromadb-operator). 10 | 11 | 12 | > [!WARNING] 13 | > Chroma 1.0.0-1.0.10 does not yet support authentication and authorization. While the feature is added, we advise using 14 | > network-level security controls, deploying behind a secure API gateway, or upgrading to a newer version if your use 15 | > case 16 | > requires authentication. 17 | 18 | ## Roadmap 19 | 20 | - [ ] `Work in progress` Security - the ability to secure chroma API with TLS 21 | - [ ] `Work in progress` Backup and restore - the ability to back up and restore the index data 22 | - [ ] `Work in progress` Observability - the ability to monitor the cluster using Prometheus and Grafana 23 | 24 | ## Prerequisites 25 | 26 | > [!NOTE] 27 | > Note: These prerequisites are necessary for local testing. If you have a Kubernetes cluster already setup you can skip 28 | 29 | - Docker 30 | - Minikube 31 | - Helm 32 | 33 | ## Installing the Chart 34 | 35 | Setup the helm repo: 36 | 37 | ```bash 38 | helm repo add chroma https://amikos-tech.github.io/chromadb-chart/ 39 | helm repo update 40 | helm search repo chroma/ 41 | ``` 42 | 43 | Update the `values.yaml` file to match your environment. 44 | 45 | ```bash 46 | helm install chroma chroma/chromadb -f values.yaml 47 | ``` 48 | 49 | Example `values.yaml` file: 50 | 51 | ```yaml 52 | chromadb: 53 | allowReset: "true" 54 | ``` 55 | 56 | Alternatively you can specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. 57 | 58 | ```bash 59 | helm install chroma chroma/chromadb --set chromadb.allowReset="true" 60 | ``` 61 | 62 | ## Chart Configuration Values 63 | 64 | | Key | Type | Default | Description | 65 | |-----------------------------------------------------|---------|---------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| 66 | | `chromadb.apiVersion` | string | `1.0.10` (Chart app version) | The ChromaDB version. Supported version `0.4.3` - `1.0.x` | 67 | | `chromadb.allowReset` | boolean | `false` | Allows resetting the index (delete all data) | 68 | | `chromadb.isPersistent` | boolean | `true` | A flag to control whether data is persisted | 69 | | `chromadb.persistDirectory` | string | `/data` | The location to store the index data. This configure both chromadb and underlying persistent volume | 70 | | `chromadb.anonymizedTelemetry` | boolean | `false` | The flag to send anonymized stats using posthog. By default this is enabled in the chromadb however for user's privacy we have disabled it so it is opt-in | 71 | | `chromadb.corsAllowOrigins` | list | N/A | The CORS config. Wildcard ["*"] is not supported in version 1.0.0 or later. | 72 | | `chromadb.apiImpl` | string | `- "chromadb.api.segment.SegmentAPI"` | The default API impl. It uses SegmentAPI however FastAPI is also available. Note: FastAPI seems to be bugging so we discourage users to use it in releases prior or equal to 0.4.3 Deprecated in since 0.1.23 (will be removed in 0.2.0) | 73 | | `chromadb.serverHost` | string | `0.0.0.0` | The API server host. | 74 | | `chromadb.serverHttpPort` | int | `8000` | The API server port. | 75 | | `chromadb.data.volumeSize` | string | `1Gi` | The data volume size. | 76 | | `chromadb.data.storageClass` | string | `null` (default storage class) | The storage class | 77 | | `chromadb.data.accessModes` | string | `ReadWriteOnce` | The volume access mode. | 78 | | `chromadb.data.retentionPolicyOnDelete` | string | `"Delete"` | The retention policy on removal. By default the PVC will be remove when Chroma chart is uninstalled. If you wish to keep it set this value to `Retain`. | 79 | | `chromadb.auth.enabled` | boolean | `true` | A flag to enable/disable authentication in Chroma. **Note**: This is not supported in Chroma version 1.0.0 or later. | 80 | | `chromadb.auth.type` | string | `token` | Type of auth. Currently "token" (apiVersion>=0.4.8) and "basic" (apiVersion>=0.4.7) are supported. **Note**: This is not supported in Chroma version 1.0.0 or later. | 81 | | `chromadb.auth.token.headerType` | string | `Authorization` | The header type for the token. Possible values: `Authorization` or `X-Chroma-Token` (also works with `X_CHROMA_TOKEN`). **Note**: This is not supported in Chroma version 1.0.0 or later. | 82 | | `chromadb.auth.existingSecret` | string | `""` | Name of an [existing secret](#using-customexisting-secret) with the auth credentials. For token auth the secret should have `token` data and for basic auth the secret should have `username` and `password` data. **Note**: This is not supported in Chroma version 1.0.0 or later. | 83 | | `image.repository` | string | `ghcr.io/chroma-core/chroma` | The repository of the image. | 84 | | `chromadb.logging.root` | string | `INFO` | The root logging level. **Note**: This is not supported in Chroma version 1.0.0 or later. | 85 | | `chromadb.logging.chromadb` | string | `DEBUG` | The chromadb logging level. **Note**: This is not supported in Chroma version 1.0.0 or later. | 86 | | `chromadb.logging.uvicorn` | string | `INFO` | The uvicorn logging level. **Note**: This is not supported in Chroma version 1.0.0 or later. | 87 | | `chromadb.logConfigMap` | string | `null` | The name of the config map with the logging configuration. If not set, the default logging configuration will be used. By default the chart ships with `log-config` config map, but you can provide your own logging configuration map. **Note**: This is not supported in Chroma version 1.0.0 or later. | 88 | | `chromadb.maintenance.collection_cache_policy` | string | `null` | The collection cache policy. Possible values: null or "LRU". Read more [here](https://cookbook.chromadb.dev/strategies/memory-management/#lru-cache-strategy). **Note**: This is not supported in Chroma version 1.0.0 or later. | 89 | | `chromadb.maintenance.collection_cache_limit_bytes` | int | `1000000000` | The collection cache limit in bytes. **Note**: This is not supported in Chroma version 1.0.0 or later. | 90 | | `chromadb.maxPayloadSizeBytes` | int | `41943040` | The size in bytes of the maximum payload that can be sent to Chroma. This is supported in v1.0.0 or later. | 91 | | `chromadb.telemetry.enabled` | boolean | `false` | Enables chroma to send OTEL telemetry | 92 | | `chromadb.telemetry.endpoint` | string | `` | OTEL collector endpoint e.g. "http://otel-collector:4317" | 93 | | `chromadb.telemetry.serviceName` | string | `chroma` | The service name that will show up in traces. | 94 | 95 | ## Verifying installation 96 | 97 | ```bash 98 | minikube service chroma-chromadb --url 99 | ``` 100 | 101 | ## Building the Docker image 102 | 103 | ```bash 104 | docker build --no-cache -t -f image/Dockerfile . 105 | docker push 106 | ``` 107 | 108 | ## Setup Kubernetes Cluster 109 | 110 | For this example we'll set up a Kubernetes cluster using minikube. 111 | 112 | ```bash 113 | minikube start --addons=ingress -p chroma #create a simple minikube cluster with ingress addon 114 | minikube profile chroma #select chroma profile in minikube as active for kubectl commands 115 | ``` 116 | 117 | ## Chroma Authentication 118 | 119 | > [!NOTE] 120 | > Token auth is enabled by default. **Not supported in Chroma 1.0.x.** 121 | 122 | By default, the chart will use a `chromadb-auth` secret in Chroma's namespace to authenticate requests. This secret is 123 | generated at install time. 124 | 125 | Chroma authentication is supported for the following API versions: 126 | 127 | - `basic` >= 0.4.7 128 | - `token` >= 0.4.8 129 | 130 | > [!NOTE] 131 | > Using auth parameters with lower version will result in auth parameters being ignored. 132 | 133 | ### Token Auth 134 | 135 | Token Auth works with two types of headers that can be configured via `chromadb.auth.token.tokenHeader`: 136 | 137 | - `AUTHORIZATION` (default) - the clients are expected to pass `Authorization: Bearer ` header 138 | - `X-CHROMA-TOKEN` (also works with `X_CHROMA_TOKEN`) - the clients are expected to pass `X-Chroma-Token: ` 139 | header 140 | 141 | > [!NOTE] 142 | > The header type is case-insensitive. 143 | 144 | Get the token: 145 | 146 | ```bash 147 | export CHROMA_TOKEN=$(kubectl --namespace default get secret chromadb-auth -o jsonpath="{.data.token}" | base64 --decode) 148 | export CHROMA_HEADER_NAME=$(kubectl --namespace default get configmap chroma-chromadb-token-auth-config -o jsonpath="{.data.CHROMA_AUTH_TOKEN_TRANSPORT_HEADER}") 149 | ``` 150 | 151 | > [!NOTE] 152 | > Note: The above examples assume `default` namespace is used for Chroma deployment. 153 | 154 | Test the token: 155 | 156 | ```bash 157 | curl -v http://localhost:8000/api/v1/collections -H "${CHROMA_HEADER_NAME}: Bearer ${CHROMA_TOKEN}" 158 | ``` 159 | 160 | > [!NOTE] 161 | > The above `curl` assumes a localhost forwarding is made to port 8000 162 | > If auth header is `AUTHORIZATION` then add `Bearer` prefix to the token when using curl. 163 | 164 | ### Basic Auth 165 | 166 | Get auth credentials: 167 | 168 | ```bash 169 | CHROMA_BASIC_AUTH_USERNAME=$(kubectl --namespace default get secret chromadb-auth -o jsonpath="{.data.username}" | base64 --decode) 170 | CHROMA_BASIC_AUTH_PASSWORD=$(kubectl --namespace default get secret chromadb-auth -o jsonpath="{.data.password}" | base64 --decode) 171 | ``` 172 | 173 | > [!NOTE] 174 | > The above examples assume `default` namespace is used for Chroma deployment. 175 | 176 | Test the token: 177 | 178 | ```bash 179 | curl -v http://localhost:8000/api/v1/collections -u "${CHROMA_BASIC_AUTH_USERNAME}:${CHROMA_BASIC_AUTH_PASSWORD}" 180 | curl -v http://localhost:8000/api/v1/collections -u "${CHROMA_BASIC_AUTH_USERNAME}:${CHROMA_BASIC_AUTH_PASSWORD}" 181 | ``` 182 | 183 | > [!NOTE] 184 | > The above `curl` assumes a localhost forwarding is made to port 8000 185 | 186 | ### Using custom/existing secret 187 | 188 | Create a secret with the auth credentials: 189 | 190 | ```bash 191 | kubectl create secret generic chromadb-auth-custom --from-literal=token="my-token" 192 | ``` 193 | 194 | To use a custom/existing secret for auth credentials, set `chromadb.auth.existingSecret` to the name of the secret. 195 | 196 | ```yaml 197 | chromadb: 198 | auth: 199 | existingSecret: "chromadb-auth-custom" 200 | ``` 201 | 202 | or 203 | 204 | ```bash 205 | kubectl create secret generic chromadb-auth-custom --from-literal=token="my-token" 206 | helm install chroma chroma/chromadb --set chromadb.auth.existingSecret="chromadb-auth-custom" 207 | ``` 208 | 209 | Verify the auth is working: 210 | 211 | ```bash 212 | export CHROMA_TOKEN=$(kubectl --namespace default get secret chromadb-auth-custom -o jsonpath="{.data.token}" | base64 --decode) 213 | export CHROMA_HEADER_NAME=$(kubectl --namespace default get configmap chroma-chromadb-token-auth-config -o jsonpath="{.data.CHROMA_AUTH_TOKEN_TRANSPORT_HEADER}") 214 | curl -v http://localhost:8000/api/v1/collections -H "${CHROMA_HEADER_NAME}: Bearer ${CHROMA_TOKEN}" 215 | ``` 216 | 217 | ## Using the chart as a dependency 218 | 219 | To use the chart as a dependency, add the following to your `Chart.yaml` file: 220 | 221 | ```yaml 222 | dependencies: 223 | - name: chromadb 224 | version: 0.1.24 225 | repository: "https://amikos-tech.github.io/chromadb-chart/" 226 | ``` 227 | 228 | Then, run `helm dependency update` to install the chart. 229 | 230 | ## References 231 | 232 | - Chroma: https://docs.trychroma.com/docs/overview/getting-started 233 | - Helm install: https://helm.sh/docs/intro/install/ 234 | - Minikube install: https://minikube.sigs.k8s.io/docs/start/ -------------------------------------------------------------------------------- /RELEASE.md: -------------------------------------------------------------------------------- 1 | # About Release 2 | 3 | 1. Lint on PR to main (this needs to be auto approved) 4 | 2. Run integration tests on approve of PR to main 5 | 3. Merge PR to main 6 | 4. -------------------------------------------------------------------------------- /bin/minikube_cluster.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | minikube start --profile=chroma 4 | -------------------------------------------------------------------------------- /charts/chromadb-chart/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *.orig 18 | *~ 19 | # Various IDEs 20 | .project 21 | .idea/ 22 | *.tmproj 23 | .vscode/ 24 | -------------------------------------------------------------------------------- /charts/chromadb-chart/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: chromadb 3 | maintainers: 4 | - name: Amikos Tech 5 | email: opensource@amikos.tech 6 | url: https://amikos.tech 7 | home: "https://github.com/amikos-tech/chromadb-chart" 8 | sources: 9 | - "https://github.com/amikos-tech/chromadb-chart" 10 | description: A Helm chart for Chroma DB vector store 11 | icon: https://github.com/chroma-core/docs/blob/0b58523496c3e6d07aac39f066f73378ed926750/static/img/chroma.png 12 | keywords: 13 | - chromadb 14 | - vectordb 15 | - vectorstore 16 | - ai/ml 17 | type: application 18 | 19 | version: 0.1.24 20 | appVersion: "1.0.10" 21 | -------------------------------------------------------------------------------- /charts/chromadb-chart/README.md: -------------------------------------------------------------------------------- 1 | # Installation 2 | 3 | To quickly start: 4 | 5 | ```bash 6 | helm repo add chroma https://amikos-tech.github.io/chromadb-chart/ 7 | helm repo update 8 | helm search repo chroma/ 9 | helm install chroma chroma/chromadb 10 | ``` 11 | 12 | For configuration see: https://github.com/amikos-tech/chromadb-chart 13 | 14 | 15 | ## Local Cluster 16 | 17 | ```bash 18 | minikube start --addons=ingress -p chroma 19 | minikube profile chroma 20 | # install chart 21 | ``` 22 | -------------------------------------------------------------------------------- /charts/chromadb-chart/templates/NOTES.txt: -------------------------------------------------------------------------------- 1 | Congratulations you have successfully installed Chroma version {{ .Values.chromadb.apiVersion | default .Chart.AppVersion }}, Chart version {{ .Chart.Version }}! 2 | 3 | Visit the official Chroma documentation for more information: https://docs.trychroma.com/. 4 | For tips and recipes, check out the Chroma cookbook: https://cookbook.chromadb.dev/. 5 | 6 | You can access your Chroma instance by forwarding the port to your local machine: 7 | 8 | ```bash 9 | kubectl port-forward --namespace {{ .Release.Namespace }} svc/{{ include "chart.fullname" . }} {{ .Values.chromadb.serverHttpPort }}:{{ .Values.chromadb.serverHttpPort }} 10 | ``` 11 | 12 | {{- if and (semverCompare "< 1.0.0" (include "chromadb.apiVersion" .)) (.Values.chromadb.auth.enabled) }} 13 | 14 | {{ .Values.chromadb.auth.type }} authentication is enabled. 15 | 16 | {{- if and .Values.chromadb.auth.enabled (eq .Values.chromadb.auth.type "token") }} 17 | It uses {{ .Values.chromadb.auth.token.headerType }} header for token. 18 | 19 | Python: 20 | 21 | {{- if eq .Values.chromadb.auth.type "token" }} 22 | 23 | Get the token from the secret: 24 | 25 | {{ if .Values.chromadb.auth.existingSecret }} 26 | ```bash 27 | export CHROMA_TOKEN=$(kubectl --namespace {{ .Release.Namespace }} get secret {{ .Values.chromadb.auth.existingSecret }} -o jsonpath="{.data.token}" | base64 --decode) 28 | ``` 29 | {{ else }} 30 | ```bash 31 | export CHROMA_TOKEN=$(kubectl --namespace {{ .Release.Namespace }} get secret chromadb-auth -o jsonpath="{.data.token}" | base64 --decode) 32 | ``` 33 | {{ end }} 34 | ```python 35 | import os 36 | import chromadb 37 | from chromadb.config import Settings 38 | 39 | client = chromadb.HttpClient( 40 | settings=Settings( 41 | chroma_client_auth_provider="chromadb.auth.token_authn.TokenAuthClientProvider", 42 | chroma_auth_token_transport_header="{{ include "chromadb.auth.token.headerType" . }}", 43 | chroma_client_auth_credentials=os.environ.get("CHROMA_TOKEN") 44 | ) 45 | ) 46 | 47 | # if everything is correctly configured the below should list all collections 48 | client.list_collections() 49 | ``` 50 | {{- end }} 51 | {{- if eq .Values.chromadb.auth.type "basic" }} 52 | 53 | Get the username and password from the secret: 54 | 55 | ```bash 56 | export CHROMA_USERNAME=$(kubectl --namespace {{ .Release.Namespace }} get secret chromadb-auth -o json | jq -r '(.data.username | @base64d)') 57 | export CHROMA_PASSWORD=$(kubectl --namespace {{ .Release.Namespace }} get secret chromadb-auth -o json | jq -r '(.data.password | @base64d)') 58 | ``` 59 | 60 | ```python 61 | import chromadb 62 | from chromadb.config import Settings 63 | 64 | client = chromadb.HttpClient( 65 | settings=Settings( 66 | chroma_client_auth_provider="chromadb.auth.basic_authn.BasicAuthClientProvider", 67 | chroma_client_auth_credentials=":") 68 | ) 69 | 70 | # if everything is correctly configured the below should list all collections 71 | client.list_collections() 72 | ``` 73 | {{- end }} 74 | 75 | > Note: Visit https://cookbook.chromadb.dev/security/auth/ for more information on authentication. 76 | 77 | {{- end }} 78 | 79 | {{- end }} 80 | -------------------------------------------------------------------------------- /charts/chromadb-chart/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* 2 | Expand the name of the chart. 3 | */}} 4 | {{- define "chart.name" -}} 5 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} 6 | {{- end }} 7 | 8 | {{/* 9 | Create a default fully qualified app name. 10 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 11 | If release name contains chart name it will be used as a full name. 12 | */}} 13 | {{- define "chart.fullname" -}} 14 | {{- if .Values.fullnameOverride }} 15 | {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} 16 | {{- else }} 17 | {{- $name := default .Chart.Name .Values.nameOverride }} 18 | {{- if contains $name .Release.Name }} 19 | {{- .Release.Name | trunc 63 | trimSuffix "-" }} 20 | {{- else }} 21 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} 22 | {{- end }} 23 | {{- end }} 24 | {{- end }} 25 | 26 | {{/* 27 | Create chart name and version as used by the chart label. 28 | */}} 29 | {{- define "chart.chart" -}} 30 | {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} 31 | {{- end }} 32 | 33 | {{/* 34 | Common labels 35 | */}} 36 | {{- define "chart.labels" -}} 37 | helm.sh/chart: {{ include "chart.chart" . }} 38 | {{ include "chart.selectorLabels" . }} 39 | {{- if .Chart.AppVersion }} 40 | app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} 41 | {{- end }} 42 | app.kubernetes.io/managed-by: {{ .Release.Service }} 43 | {{- end }} 44 | 45 | {{/* 46 | Selector labels 47 | */}} 48 | {{- define "chart.selectorLabels" -}} 49 | app.kubernetes.io/name: {{ include "chart.name" . }} 50 | app.kubernetes.io/instance: {{ .Release.Name }} 51 | {{- end }} 52 | 53 | {{/* 54 | Create the name of the service account to use 55 | */}} 56 | {{- define "chart.serviceAccountName" -}} 57 | {{- if .Values.serviceAccount.create }} 58 | {{- default (include "chart.fullname" .) .Values.serviceAccount.name }} 59 | {{- else }} 60 | {{- default "default" .Values.serviceAccount.name }} 61 | {{- end }} 62 | {{- end }} 63 | 64 | {{/* 65 | Get the chroma api version 66 | */}} 67 | {{- define "chromadb.apiVersion" -}} 68 | {{- if .Values.chromadb.apiVersion }} 69 | {{- .Values.chromadb.apiVersion }} 70 | {{- else }} 71 | {{- .Chart.AppVersion }} 72 | {{- end }} 73 | {{- end }} 74 | 75 | {{/* 76 | Get the Chroma auth token header type 77 | */}} 78 | {{- define "chromadb.auth.token.headerType" -}} 79 | {{- $headerType := "authorization" }} 80 | {{- if .Values.chromadb.auth.token.headerType }} 81 | {{- $headerType = lower .Values.chromadb.auth.token.headerType }} 82 | {{- end }} 83 | {{- if eq $headerType "authorization" }}Authorization 84 | {{- else if or (eq $headerType "x_chroma_token") (eq $headerType "x-chroma-token") }}X-Chroma-Token{{- else }} 85 | {{- fail (printf "Invalid ChromaDB auth token header type: %s. Allowed values: Authorization, X-Chroma-Token" .Values.chromadb.auth.token.headerType) }} 86 | {{- end }} 87 | {{- end }} -------------------------------------------------------------------------------- /charts/chromadb-chart/templates/config.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: log-config 5 | namespace: {{ .Release.Namespace }} 6 | data: 7 | log_config.yaml: |- 8 | version: 1 9 | disable_existing_loggers: False 10 | formatters: 11 | default: 12 | "()": uvicorn.logging.DefaultFormatter 13 | format: '%(levelprefix)s [%(asctime)s] %(message)s' 14 | use_colors: null 15 | datefmt: '%d-%m-%Y %H:%M:%S' 16 | access: 17 | "()": uvicorn.logging.AccessFormatter 18 | format: '%(levelprefix)s [%(asctime)s] %(client_addr)s - "%(request_line)s" %(status_code)s' 19 | datefmt: '%d-%m-%Y %H:%M:%S' 20 | handlers: 21 | default: 22 | formatter: default 23 | class: logging.StreamHandler 24 | stream: ext://sys.stderr 25 | access: 26 | formatter: access 27 | class: logging.StreamHandler 28 | stream: ext://sys.stdout 29 | console: 30 | class: logging.StreamHandler 31 | stream: ext://sys.stdout 32 | formatter: default 33 | loggers: 34 | root: 35 | level: {{ .Values.chromadb.logging.root | upper | default "WARN" }} 36 | handlers: [console] 37 | chromadb: 38 | level: {{ .Values.chromadb.logging.chromadb | upper | default "DEBUG" }} 39 | uvicorn: 40 | level: {{ .Values.chromadb.logging.uvicorn | upper | default "INFO" }} 41 | --- 42 | {{- if and .Values.chromadb.auth.enabled (eq .Values.chromadb.auth.type "token") (eq .Values.chromadb.auth.existingSecret "") }} 43 | apiVersion: v1 44 | kind: Secret 45 | metadata: 46 | name: chromadb-auth 47 | namespace: {{ .Release.Namespace }} 48 | annotations: 49 | "helm.sh/hook": "pre-install,pre-upgrade" 50 | "helm.sh/hook-weight": "-5" 51 | type: Opaque 52 | {{- if (lookup "v1" "Secret" .Release.Namespace "chromadb-auth") }} 53 | immutable: true 54 | {{- end }} 55 | data: 56 | {{- $existingSecret := (lookup "v1" "Secret" .Release.Namespace "chromadb-auth") }} 57 | {{- if $existingSecret }} 58 | token: {{ index $existingSecret.data "token" }} 59 | {{- else }} 60 | token: {{ .Values.chromadb.auth.token.value | default ( randAlphaNum 32 ) | b64enc | quote }} 61 | {{- end }} 62 | {{- end }} 63 | --- 64 | {{- if and (semverCompare ">= 0.4.7" (include "chromadb.apiVersion" .)) .Values.chromadb.auth.enabled (eq .Values.chromadb.auth.type "basic") (eq .Values.chromadb.auth.existingSecret "") }} 65 | apiVersion: v1 66 | kind: Secret 67 | metadata: 68 | name: chromadb-auth 69 | namespace: {{ .Release.Namespace }} 70 | annotations: 71 | "helm.sh/hook": "pre-install,pre-upgrade" 72 | "helm.sh/hook-weight": "-5" 73 | type: Opaque 74 | {{- $existingSecret := (lookup "v1" "Secret" .Release.Namespace "chromadb-auth") }} 75 | {{- if $existingSecret }} 76 | immutable: true 77 | {{- end }} 78 | data: 79 | {{- if $existingSecret }} 80 | username: {{ index $existingSecret.data "username" }} 81 | password: {{ index $existingSecret.data "password" }} 82 | {{- else }} 83 | username: {{ .Values.chromadb.auth.basic.username | b64enc | quote }} 84 | password: {{ .Values.chromadb.auth.basic.password | default (randAlphaNum 16) | b64enc | quote }} 85 | {{- end }} 86 | {{- end }} 87 | --- 88 | {{- if and .Values.chromadb.auth.enabled (eq .Values.chromadb.auth.type "basic") }} 89 | apiVersion: v1 90 | kind: ConfigMap 91 | metadata: 92 | name: {{ include "chart.fullname" . }}-basic-auth-config 93 | namespace: {{ .Release.Namespace }} 94 | annotations: 95 | "helm.sh/hook": "pre-install,pre-upgrade" 96 | "helm.sh/hook-weight": "-5" 97 | data: 98 | {{- $existingConfigMap := (lookup "v1" "ConfigMap" .Release.Namespace (include "chart.fullname" . | printf "%s-basic-auth-config")) }} 99 | {{- $newData := dict }} 100 | {{- if and (semverCompare ">= 0.4.7" (include "chromadb.apiVersion" .)) (semverCompare "< 0.5.0" (include "chromadb.apiVersion" .)) }} 101 | {{- $_ := set $newData "CHROMA_SERVER_AUTH_CREDENTIALS_PROVIDER" "chromadb.auth.providers.HtpasswdFileServerAuthCredentialsProvider" }} 102 | {{- $_ := set $newData "CHROMA_SERVER_AUTH_PROVIDER" "chromadb.auth.basic.BasicAuthServerProvider" }} 103 | {{- $_ := set $newData "CHROMA_SERVER_AUTH_CREDENTIALS_FILE" "/chroma/auth/server.htpasswd" }} 104 | {{- else if (semverCompare ">= 0.5.0" (include "chromadb.apiVersion" .)) }} 105 | {{- $_ := set $newData "CHROMA_SERVER_AUTHN_CREDENTIALS_FILE" "/chroma/auth/server.htpasswd" }} 106 | {{- $_ := set $newData "CHROMA_SERVER_AUTHN_PROVIDER" "chromadb.auth.basic_authn.BasicAuthenticationServerProvider" }} 107 | {{- end }} 108 | {{- if $existingConfigMap }} 109 | {{- range $key, $value := $existingConfigMap.data }} 110 | {{- if not (hasKey $newData $key) }} 111 | {{- $_ := set $newData $key $value }} 112 | {{- end }} 113 | {{- end }} 114 | {{- end }} 115 | {{- range $key, $value := $newData }} 116 | {{ $key }}: {{ $value | quote }} 117 | {{- end }} 118 | {{- end }} 119 | --- 120 | {{- if and .Values.chromadb.auth.enabled (eq .Values.chromadb.auth.type "token") }} 121 | apiVersion: v1 122 | kind: ConfigMap 123 | metadata: 124 | name: {{ include "chart.fullname" . }}-token-auth-config 125 | namespace: {{ .Release.Namespace }} 126 | annotations: 127 | "helm.sh/hook": "pre-install,pre-upgrade" 128 | "helm.sh/hook-weight": "-5" 129 | data: 130 | {{- $existingConfigMap := (lookup "v1" "ConfigMap" .Release.Namespace (include "chart.fullname" . | printf "%s-token-auth-config")) }} 131 | {{- $newData := dict }} 132 | {{- if and (semverCompare ">= 0.4.7" (include "chromadb.apiVersion" .)) (semverCompare "< 0.5.0" (include "chromadb.apiVersion" .)) }} 133 | {{- $_ := set $newData "CHROMA_SERVER_AUTH_CREDENTIALS_PROVIDER" "chromadb.auth.token.TokenConfigServerAuthCredentialsProvider" }} 134 | {{- $_ := set $newData "CHROMA_SERVER_AUTH_PROVIDER" "chromadb.auth.token.TokenAuthServerProvider" }} 135 | {{- else if (semverCompare ">= 0.5.0" (include "chromadb.apiVersion" .)) }} 136 | {{- $_ := set $newData "CHROMA_SERVER_AUTHN_PROVIDER" "chromadb.auth.token_authn.TokenAuthenticationServerProvider" }} 137 | {{- $_ := set $newData "CHROMA_AUTH_TOKEN_TRANSPORT_HEADER" (include "chromadb.auth.token.headerType" .) }} 138 | {{- end }} 139 | {{- if $existingConfigMap }} 140 | {{- range $key, $value := $existingConfigMap.data }} 141 | {{- if not (hasKey $newData $key) }} 142 | {{- $_ := set $newData $key $value }} 143 | {{- end }} 144 | {{- end }} 145 | {{- end }} 146 | {{- range $key, $value := $newData }} 147 | {{ $key }}: {{ $value | quote }} 148 | {{- end }} 149 | {{- end }} 150 | --- 151 | apiVersion: v1 152 | kind: ConfigMap 153 | metadata: 154 | name: v1-config 155 | namespace: {{ .Release.Namespace }} 156 | annotations: 157 | "helm.sh/hook": "pre-install,pre-upgrade" 158 | "helm.sh/hook-weight": "-5" 159 | data: 160 | config.yaml: |- 161 | {{- if .Values.chromadb.telemetry.enabled }} 162 | open_telemetry: 163 | service_name: {{ .Values.chromadb.telemetry.serviceName }} 164 | endpoint: {{ .Values.chromadb.telemetry.endpoint }} 165 | {{- end }} 166 | port: {{ .Values.chromadb.serverHttpPort }} 167 | listen_address: {{ .Values.chromadb.serverHost }} 168 | max_payload_size_bytes: {{ .Values.chromadb.maxPayloadSizeBytes | int64 }} 169 | {{- if .Values.chromadb.corsAllowOrigins }} 170 | {{- if and (eq (len .Values.chromadb.corsAllowOrigins) 1) (eq (index .Values.chromadb.corsAllowOrigins 0) "*") }} 171 | {{ fail "cors_allow_origins must not be set to '*' when only one origin is allowed" }} 172 | {{- end }} 173 | cors_allow_origins: {{ .Values.chromadb.corsAllowOrigins | toJson }} 174 | {{- end }} 175 | persist_path: {{ .Values.chromadb.persistDirectory }} 176 | allow_reset: {{ .Values.chromadb.allowReset }} -------------------------------------------------------------------------------- /charts/chromadb-chart/templates/ingress.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | {{- if .Values.ingress.enabled -}} 3 | {{- $fullName := include "chart.fullname" . -}} 4 | {{- $svcPort := .Values.chromadb.serverHttpPort -}} 5 | {{- if and .Values.ingress.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }} 6 | {{- if not (hasKey .Values.ingress.annotations "kubernetes.io/ingress.class") }} 7 | {{- $_ := set .Values.ingress.annotations "kubernetes.io/ingress.class" .Values.ingress.className}} 8 | {{- end }} 9 | {{- end }} 10 | {{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion -}} 11 | apiVersion: networking.k8s.io/v1 12 | {{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}} 13 | apiVersion: networking.k8s.io/v1beta1 14 | {{- else -}} 15 | apiVersion: extensions/v1beta1 16 | {{- end }} 17 | kind: Ingress 18 | metadata: 19 | name: {{ $fullName }} 20 | labels: 21 | {{- include "chart.labels" . | nindent 4 }} 22 | {{- with .Values.ingress.annotations }} 23 | annotations: 24 | {{- toYaml . | nindent 4 }} 25 | {{- end }} 26 | spec: 27 | {{- if and .Values.ingress.className (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }} 28 | ingressClassName: {{ .Values.ingress.className }} 29 | {{- end }} 30 | {{- if .Values.ingress.tls }} 31 | tls: 32 | {{- range .Values.ingress.tls }} 33 | - hosts: 34 | {{- range .hosts }} 35 | - {{ . | quote }} 36 | {{- end }} 37 | secretName: {{ .secretName }} 38 | {{- end }} 39 | {{- end }} 40 | rules: 41 | {{- range .Values.ingress.hosts }} 42 | - host: {{ .host | quote }} 43 | http: 44 | paths: 45 | {{- range .paths }} 46 | - path: {{ .path }} 47 | {{- if and .pathType (semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion) }} 48 | pathType: {{ .pathType }} 49 | {{- end }} 50 | backend: 51 | {{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }} 52 | service: 53 | name: {{ $fullName }} 54 | port: 55 | number: {{ $svcPort }} 56 | {{- else }} 57 | serviceName: {{ $fullName }} 58 | servicePort: {{ $svcPort }} 59 | {{- end }} 60 | {{- end }} 61 | {{- end }} 62 | {{- end }} 63 | -------------------------------------------------------------------------------- /charts/chromadb-chart/templates/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ include "chart.fullname" . }} 5 | labels: 6 | {{- include "chart.labels" . | nindent 4 }} 7 | spec: 8 | type: {{ .Values.service.type }} 9 | ports: 10 | - port: {{ .Values.chromadb.serverHttpPort }} 11 | targetPort: {{ .Values.chromadb.serverHttpPort }} 12 | protocol: TCP 13 | name: http 14 | {{- if .Values.service.nodePort }} 15 | nodePort: {{ .Values.service.nodePort }} 16 | {{- end }} 17 | selector: 18 | {{- include "chart.selectorLabels" . | nindent 4 }} 19 | -------------------------------------------------------------------------------- /charts/chromadb-chart/templates/statefulset.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: StatefulSet 3 | metadata: 4 | name: {{ include "chart.fullname" . }} 5 | namespace: "{{ .Release.Namespace }}" 6 | labels: 7 | {{- include "chart.labels" . | nindent 4 }} 8 | spec: 9 | serviceName: "{{ include "chart.fullname" . }}" 10 | podManagementPolicy: "Parallel" # This setting means that the StatefulSet controller doesn't block applying changes until the existing Pod is READY. 11 | replicas: {{ .Values.replicaCount }} 12 | selector: 13 | matchLabels: 14 | {{- include "chart.selectorLabels" . | nindent 6 }} 15 | template: 16 | metadata: 17 | labels: 18 | {{- include "chart.labels" . | nindent 8 }} 19 | annotations: 20 | checksum/config: {{ include (print $.Template.BasePath "/config.yaml") . | sha256sum }} # Automatically Roll Deployments 21 | {{- with .Values.podSpec.podAnnotations }} 22 | {{- toYaml . | nindent 8 }} 23 | {{- end }} 24 | spec: 25 | securityContext: {{ toYaml .Values.podSpec.securityContext | nindent 8 }} 26 | terminationGracePeriodSeconds: {{ .Values.podSpec.terminationGracePeriodSeconds }} 27 | {{- with .Values.imagePullSecrets }} 28 | imagePullSecrets: 29 | {{- toYaml . | nindent 8 }} 30 | {{- end }} 31 | {{- with .Values.nodeSelector }} 32 | nodeSelector: 33 | {{- toYaml . | nindent 8 }} 34 | {{- end }} 35 | {{- if and (semverCompare ">= 0.4.7" (include "chromadb.apiVersion" .)) .Values.chromadb.auth.enabled (eq .Values.chromadb.auth.type "basic") }} 36 | initContainers: 37 | - name: generate-htpasswd 38 | image: {{ .Values.initImage }} 39 | env: 40 | - name: CHROMA_BASIC_USER 41 | valueFrom: 42 | secretKeyRef: 43 | name: {{ .Values.chromadb.auth.existingSecret | default "chromadb-auth" }} 44 | key: username 45 | - name: CHROMA_BASIC_PASSWORD 46 | valueFrom: 47 | secretKeyRef: 48 | name: {{ .Values.chromadb.auth.existingSecret | default "chromadb-auth" }} 49 | key: password 50 | command: 51 | - sh 52 | - -c 53 | - | 54 | htpasswd -Bbn ${CHROMA_BASIC_USER} ${CHROMA_BASIC_PASSWORD} > /chroma/auth/server.htpasswd 55 | chmod 444 /chroma/auth/server.htpasswd 56 | volumeMounts: 57 | - mountPath: /chroma/auth/ 58 | name: htpasswd-volume 59 | {{- end }} 60 | tolerations: 61 | {{- toYaml .Values.tolerations | nindent 8 }} 62 | affinity: 63 | {{- toYaml .Values.affinity | nindent 8 }} 64 | containers: 65 | - name: "chromadb" 66 | image: "{{ .Values.image.repository }}:{{ .Values.chromadb.apiVersion | default .Chart.AppVersion }}" 67 | imagePullPolicy: "{{ .Values.image.pullPolicy }}" 68 | {{- if and (semverCompare "< 1.0.0" (include "chromadb.apiVersion" .)) .Values.chromadb.auth.enabled }} 69 | envFrom: 70 | - configMapRef: 71 | {{- if (eq .Values.chromadb.auth.type "token") }} 72 | name: {{ include "chart.fullname" . }}-token-auth-config 73 | {{- end }} 74 | {{- if (eq .Values.chromadb.auth.type "basic") }} 75 | name: {{ include "chart.fullname" . }}-basic-auth-config 76 | {{- end }} 77 | {{- end }} 78 | env: 79 | - name: POD_NAME 80 | valueFrom: 81 | fieldRef: 82 | fieldPath: metadata.name 83 | {{- if and (semverCompare "< 1.0.0" (include "chromadb.apiVersion" .)) }} 84 | - name: IS_PERSISTENT 85 | value: "{{ .Values.chromadb.isPersistent }}" 86 | - name: PERSIST_DIRECTORY 87 | value: "{{ .Values.chromadb.persistDirectory }}" 88 | - name: ALLOW_RESET 89 | value: "{{ .Values.chromadb.allowReset | default false}}" 90 | - name: ANONYMIZED_TELEMETRY 91 | value: "{{ .Values.chromadb.anonymizedTelemetry | default false }}" 92 | {{- if .Values.chromadb.corsAllowOrigins }} 93 | - name: CHROMA_SERVER_CORS_ALLOW_ORIGINS 94 | value: '{{ .Values.chromadb.corsAllowOrigins | join "\",\"" | printf "[\"%s\"]"}}' 95 | {{- end }} 96 | - name: ROOT_LOG_LEVEL 97 | value: "{{ .Values.chromadb.logging.root | upper | default "WARN" }}" 98 | - name: CHROMA_LOG_LEVEL 99 | value: "{{ .Values.chromadb.logging.chromadb | upper | default "DEBUG" }}" 100 | - name: UVICORN_LOG_LEVEL_UVICORN 101 | value: "{{ .Values.chromadb.logging.uvicorn | upper | default "INFO" }}" 102 | {{- if .Values.chromadb.maintenance.collection_cache_policy }} 103 | {{- if ne .Values.chromadb.maintenance.collection_cache_policy "LRU" }} 104 | {{- fail "collection_cache_policy must be 'LRU'" }} 105 | {{- end }} 106 | - name: CHROMA_SEGMENT_CACHE_POLICY 107 | value: "{{ .Values.chromadb.maintenance.collection_cache_policy }}" 108 | - name: CHROMA_MEMORY_LIMIT_BYTES 109 | {{- $bytes := int .Values.chromadb.maintenance.collection_cache_limit_bytes }} 110 | {{- if le $bytes 0 }} 111 | {{- fail "collection_cache_limit_bytes must be a positive integer" }} 112 | {{- end }} 113 | value: "{{ $bytes }}" 114 | {{- end }} 115 | {{- end }} 116 | {{- if .Values.chromadb.serverHttpPort }} 117 | - name: CHROMA_SERVER_HTTP_PORT 118 | value: "{{ .Values.chromadb.serverHttpPort }}" 119 | {{- end }} 120 | # We keep this for backwards compatibility log levels below are used for the new images 121 | {{- if and (semverCompare "< 1.0.0" (include "chromadb.apiVersion" .)) .Values.chromadb.logConfigFileLocation }} 122 | - name: CHROMA_LOG_CONFIG 123 | {{- if .Values.chromadb.logConfigMap }} 124 | value: "/chroma/log_config.yaml" 125 | {{- else }} 126 | value: "{{ .Values.chromadb.logConfigFileLocation }}" 127 | {{- end }} 128 | {{- end }} 129 | {{- if and (semverCompare "< 1.0.0" (include "chromadb.apiVersion" .)) .Values.chromadb.auth.enabled (eq .Values.chromadb.auth.type "token") }} 130 | {{- if and (semverCompare ">= 0.4.7" (include "chromadb.apiVersion" .)) (semverCompare "< 0.5.0" (include "chromadb.apiVersion" .)) }} 131 | - name: CHROMA_SERVER_AUTH_CREDENTIALS 132 | {{- else if (semverCompare ">= 0.5.0" (include "chromadb.apiVersion" .))}} 133 | - name: CHROMA_SERVER_AUTHN_CREDENTIALS 134 | {{- end }} 135 | valueFrom: 136 | secretKeyRef: 137 | name: {{ .Values.chromadb.auth.existingSecret | default "chromadb-auth" }} 138 | key: token 139 | {{- end }} 140 | ports: 141 | - containerPort: {{ .Values.chromadb.serverHttpPort }} 142 | name: http 143 | {{- if or .Values.resources.requests .Values.resources.limits}} 144 | resources: 145 | {{- if .Values.resources.requests }} 146 | requests: {{ .Values.resources.requests | toYaml | nindent 14 }} 147 | {{- end }} 148 | {{- if .Values.resources.limits }} 149 | limits: {{ .Values.resources.limits | toYaml | nindent 14 }} 150 | {{- end }} 151 | {{- end }} 152 | securityContext: {{ .Values.podSpec.securityContext | toYaml | nindent 14 }} 153 | volumeMounts: 154 | {{- if and (semverCompare "< 1.0.0" (include "chromadb.apiVersion" .)) (semverCompare ">= 0.6.0" (include "chromadb.apiVersion" .)) }} 155 | - mountPath: "/chroma/log_config.yaml" 156 | name: log-config 157 | subPath: log_config.yaml 158 | {{- else if (semverCompare "< 0.5.0" (include "chromadb.apiVersion" .))}} 159 | - mountPath: "/chroma/log_config.yaml" 160 | name: log-config-legacy 161 | subPath: log_config.yaml 162 | {{- end }} 163 | {{- if eq .Values.chromadb.isPersistent true }} 164 | - mountPath: "{{.Values.chromadb.persistDirectory}}" 165 | name: data 166 | {{- end }} 167 | {{- if and (semverCompare "< 1.0.0" (include "chromadb.apiVersion" .)) (semverCompare ">= 0.4.7" (include "chromadb.apiVersion" .)) .Values.chromadb.auth.enabled (eq .Values.chromadb.auth.type "basic") }} 168 | - mountPath: /chroma/auth/ 169 | name: htpasswd-volume 170 | {{- end }} 171 | {{- if (semverCompare ">= 1.0.0" (include "chromadb.apiVersion" .)) }} 172 | - mountPath: /config.yaml 173 | name: v1-config 174 | subPath: config.yaml 175 | {{- end }} 176 | readinessProbe: 177 | tcpSocket: 178 | port: {{ .Values.chromadb.serverHttpPort }} 179 | failureThreshold: {{ .Values.readinessProbe.failureThreshold }} 180 | timeoutSeconds: {{ .Values.readinessProbe.timeoutSeconds }} 181 | periodSeconds: {{ .Values.readinessProbe.periodSeconds }} 182 | livenessProbe: 183 | tcpSocket: 184 | port: {{ .Values.chromadb.serverHttpPort }} 185 | failureThreshold: {{ .Values.livenessProbe.failureThreshold }} 186 | timeoutSeconds: {{ .Values.livenessProbe.timeoutSeconds }} 187 | periodSeconds: {{ .Values.livenessProbe.periodSeconds }} 188 | startupProbe: 189 | tcpSocket: 190 | port: {{ .Values.chromadb.serverHttpPort }} 191 | failureThreshold: {{ .Values.startupProbe.failureThreshold }} 192 | periodSeconds: {{ .Values.startupProbe.periodSeconds }} 193 | initialDelaySeconds: {{ .Values.startupProbe.initialDelaySeconds }} 194 | volumes: 195 | {{- if and (semverCompare "< 1.0.0" (include "chromadb.apiVersion" .)) (semverCompare ">= 0.4.7" (include "chromadb.apiVersion" .)) .Values.chromadb.auth.enabled (eq .Values.chromadb.auth.type "basic") }} 196 | - name: htpasswd-volume 197 | emptyDir: { } 198 | {{- end }} 199 | {{- if (semverCompare "< 0.5.0" (include "chromadb.apiVersion" .)) }} 200 | - name: log-config-legacy 201 | configMap: 202 | name: "log-config" 203 | defaultMode: 0644 204 | {{- end }} 205 | {{- if .Values.chromadb.logConfigMap }} 206 | - name: log-config 207 | configMap: 208 | name: "{{ .Values.chromadb.logConfigMap }}" 209 | defaultMode: 0644 210 | {{- else }} 211 | - name: log-config 212 | configMap: 213 | name: "log-config" 214 | defaultMode: 0644 215 | {{- end }} 216 | {{- if (semverCompare ">= 1.0.0" (include "chromadb.apiVersion" .)) }} 217 | - name: v1-config 218 | configMap: 219 | name: v1-config 220 | defaultMode: 0644 221 | {{- end }} 222 | {{- if eq .Values.chromadb.isPersistent true }} 223 | volumeClaimTemplates: 224 | - metadata: 225 | name: data 226 | spec: 227 | accessModes: {{ .Values.chromadb.data.accessModes | toYaml | nindent 14 }} 228 | {{- if .Values.chromadb.data.storageClass }} 229 | storageClassName: "{{ .Values.chromadb.data.storageClass }}" 230 | {{- end }} 231 | resources: 232 | requests: 233 | storage: {{ .Values.chromadb.data.volumeSize }} 234 | persistentVolumeClaimRetentionPolicy: 235 | whenDeleted: {{ .Values.chromadb.data.retentionPolicyOnDelete | default "Delete" }} 236 | {{- end }} 237 | -------------------------------------------------------------------------------- /charts/chromadb-chart/templates/tests/test-api.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: batch/v1 2 | kind: Job 3 | metadata: 4 | name: "{{ include "chart.fullname" . }}-test-api" 5 | labels: 6 | {{- include "chart.labels" . | nindent 4 }} 7 | annotations: 8 | "helm.sh/hook": test 9 | "helm.sh/hook-delete-policy": hook-succeeded 10 | spec: 11 | ttlSecondsAfterFinished: 100 12 | template: 13 | spec: 14 | restartPolicy: Never 15 | containers: 16 | - name: curl 17 | image: curlimages/curl:latest 18 | command: ['curl'] 19 | args: 20 | - '-v' 21 | - 'http://{{ include "chart.fullname" . }}:{{ .Values.chromadb.serverHttpPort }}/api/v1/collections' 22 | {{- if eq .Values.chromadb.auth.type "token" }} 23 | {{- $existingConfigMap := (lookup "v1" "ConfigMap" .Release.Namespace (include "chart.fullname" . | printf "%s-token-auth-config")) }} 24 | {{- $existingSecret := (lookup "v1" "Secret" .Release.Namespace (.Values.chromadb.auth.existingSecret | default "chromadb-auth")) }} # TODO support existing secret 25 | {{- if $existingSecret }} 26 | - '-H' 27 | {{- if eq $existingConfigMap.data.CHROMA_AUTH_TOKEN_TRANSPORT_HEADER "Authorization" }} # Authorization: Bearer 28 | - '{{ $existingConfigMap.data.CHROMA_AUTH_TOKEN_TRANSPORT_HEADER }}: Bearer {{ $existingSecret.data.token | b64dec }}1' 29 | {{- else }} # X-Chroma-Token 30 | - '{{ $existingConfigMap.data.CHROMA_AUTH_TOKEN_TRANSPORT_HEADER }}: {{ $existingSecret.data.token | b64dec }}' 31 | {{- end }} 32 | {{- end }} 33 | {{- else if eq .Values.chromadb.auth.type "basic" }} 34 | {{- $existingSecret := (lookup "v1" "Secret" .Release.Namespace (.Values.chromadb.auth.existingSecret | default "chromadb-auth")) }} # TODO support existing secret 35 | {{- if $existingSecret }} 36 | - '--user' 37 | - "{{ $existingSecret.data.username }}:{{ $existingSecret.data.password }}" 38 | {{- end }} 39 | {{- end }} 40 | -------------------------------------------------------------------------------- /charts/chromadb-chart/templates/tests/test-connection.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: batch/v1 2 | kind: Job 3 | metadata: 4 | name: "{{ include "chart.fullname" . }}-test-connection" 5 | labels: 6 | {{- include "chart.labels" . | nindent 4 }} 7 | annotations: 8 | "helm.sh/hook": test 9 | "helm.sh/hook-delete-policy": hook-succeeded 10 | spec: 11 | ttlSecondsAfterFinished: 100 12 | template: 13 | spec: 14 | restartPolicy: Never 15 | containers: 16 | - name: curl 17 | image: curlimages/curl:latest 18 | command: ['curl'] 19 | args: 20 | - '-v' 21 | - 'http://{{ include "chart.fullname" . }}:{{ .Values.chromadb.serverHttpPort }}/api/v1/hearbeat' 22 | {{- if eq .Values.chromadb.auth.type "token" }} 23 | {{- $existingConfigMap := (lookup "v1" "ConfigMap" .Release.Namespace (include "chart.fullname" . | printf "%s-token-auth-config")) }} 24 | {{- $existingSecret := (lookup "v1" "Secret" .Release.Namespace (.Values.chromadb.auth.existingSecret | default "chromadb-auth")) }} # TODO support existing secret 25 | {{- if $existingSecret }} 26 | - '-H' 27 | {{- if eq $existingConfigMap.data.CHROMA_AUTH_TOKEN_TRANSPORT_HEADER "Authorization" }} # Authorization: Bearer 28 | - '{{ $existingConfigMap.data.CHROMA_AUTH_TOKEN_TRANSPORT_HEADER }}: Bearer {{ $existingSecret.data.token | b64dec }}1' 29 | {{- else }} # X-Chroma-Token 30 | - '{{ $existingConfigMap.data.CHROMA_AUTH_TOKEN_TRANSPORT_HEADER }}: {{ $existingSecret.data.token | b64dec }}' 31 | {{- end }} 32 | {{- end }} 33 | {{- else if eq .Values.chromadb.auth.type "basic" }} 34 | {{- $existingSecret := (lookup "v1" "Secret" .Release.Namespace (.Values.chromadb.auth.existingSecret | default "chromadb-auth")) }} # TODO support existing secret 35 | {{- if $existingSecret }} 36 | - '--user' 37 | - "{{ $existingSecret.data.username }}:{{ $existingSecret.data.password }}" 38 | {{- end }} 39 | {{- end }} 40 | -------------------------------------------------------------------------------- /charts/chromadb-chart/values.yaml: -------------------------------------------------------------------------------- 1 | # Default values for chart. 2 | # This is a YAML-formatted file. 3 | # Declare variables to be passed into your templates. 4 | 5 | replicaCount: 1 6 | 7 | image: 8 | repository: ghcr.io/chroma-core/chroma 9 | pullPolicy: IfNotPresent 10 | 11 | # initContainer image 12 | initImage: docker.io/httpd:2 13 | 14 | imagePullSecrets: [ ] 15 | nameOverride: "" 16 | fullnameOverride: "" 17 | 18 | serviceAccount: 19 | # Specifies whether a service account should be created 20 | create: true 21 | # Annotations to add to the service account 22 | annotations: { } 23 | # The name of the service account to use. 24 | # If not set and create is true, a name is generated using the fullname template 25 | name: "" 26 | 27 | 28 | service: 29 | type: ClusterIP # ClusterIP, NodePort, LoadBalancer 30 | nodePort: null 31 | 32 | ingress: 33 | enabled: false 34 | className: "" 35 | annotations: { } 36 | # kubernetes.io/ingress.class: nginx 37 | # kubernetes.io/tls-acme: "true" 38 | hosts: 39 | - host: chart-example.local 40 | paths: 41 | - path: / 42 | pathType: ImplementationSpecific 43 | tls: [ ] 44 | # - secretName: chart-example-tls 45 | # hosts: 46 | # - chart-example.local 47 | 48 | resources: {} 49 | # We usually recommend not to specify default resources and to leave this as a conscious 50 | # choice for the user. This also increases chances charts run on environments with little 51 | # resources, such as Minikube. If you do want to specify resources, uncomment the following 52 | # lines, adjust them as necessary, and remove the curly braces after 'resources:'. 53 | # limits: 54 | # cpu: 100m 55 | # memory: 128Mi 56 | # requests: 57 | # cpu: 100m 58 | # memory: 128Mi 59 | 60 | autoscaling: 61 | enabled: false 62 | minReplicas: 1 63 | maxReplicas: 100 64 | targetCPUUtilizationPercentage: 80 65 | # targetMemoryUtilizationPercentage: 80 66 | 67 | nodeSelector: { } 68 | 69 | tolerations: [ ] 70 | 71 | affinity: { } 72 | 73 | podSpec: 74 | terminationGracePeriodSeconds: 5 75 | securityContext: { } 76 | podAnnotations: { } 77 | # capabilities: 78 | # drop: 79 | # - ALL 80 | # readOnlyRootFilesystem: true 81 | # runAsNonRoot: true 82 | # runAsUser: 1000 83 | # fsGroup: 2000 84 | annotations: { } 85 | initContainers: [ ] 86 | readinessProbe: 87 | failureThreshold: 20 88 | timeoutSeconds: 10 89 | periodSeconds: 5 90 | livenessProbe: 91 | failureThreshold: 40 92 | timeoutSeconds: 10 93 | periodSeconds: 5 94 | startupProbe: 95 | failureThreshold: 1000 96 | periodSeconds: 5 97 | initialDelaySeconds: 10 98 | 99 | chromadb: 100 | allowReset: false 101 | isPersistent: true 102 | persistDirectory: /data 103 | logConfigFileLocation: /chroma/log_config.yaml 104 | logConfigMap: null 105 | logging: 106 | root: "INFO" 107 | chromadb: "DEBUG" 108 | uvicorn: "INFO" 109 | anonymizedTelemetry: false 110 | corsAllowOrigins: [] # as of version 1.0.x * is not allowed 111 | serverHost: "0.0.0.0" 112 | serverHttpPort: 8000 113 | maxPayloadSizeBytes: "41943040" 114 | data: 115 | volumeSize: "1Gi" 116 | storageClass: null 117 | accessModes: [ "ReadWriteOnce" ] 118 | retentionPolicyOnDelete: "Delete" 119 | telemetry: 120 | enabled: false 121 | endpoint: "" 122 | serviceName: "chroma" 123 | maintenance: 124 | collection_cache_policy: null # possible values: null or "LRU" 125 | collection_cache_limit_bytes: 1000000000 # defaults to 1GB. TODO: this must also observe limits if defined 126 | auth: # not working in 1.0.x 127 | enabled: true 128 | type: "token" # possible values: basic, token 129 | existingSecret: "" 130 | basic: 131 | username: "chroma" 132 | password: null # The string used as the auth.basic password. Only used if value not null, otherwise a random string will be generated and used. 133 | token: 134 | headerType: "Authorization" #possible values Authorization, X-Chroma-Token 135 | value: null # The string used as the token (value). Only used if value not null, otherwise a random string will be generated and used. 136 | 137 | -------------------------------------------------------------------------------- /image/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG CHROMA_VERSION=0.5.5 2 | FROM ghcr.io/chroma-core/chroma:${CHROMA_VERSION} as base 3 | 4 | COPY ./image/docker_entrypoint.sh /docker_entrypoint.sh 5 | WORKDIR /chroma 6 | RUN find /chroma -mindepth 1 -maxdepth 1 ! \( -name 'chromadb' -o -name 'LICENSE' -o -name 'requirements.txt' \) -exec rm -rf {} \; && \ 7 | groupadd chroma && \ 8 | pip install virtualenv && \ 9 | useradd -g chroma -d /chroma chroma && \ 10 | python -m virtualenv /chroma/venv && \ 11 | . /chroma/venv/bin/activate && \ 12 | pip install --force-reinstall --no-cache-dir -r /chroma/requirements.txt && \ 13 | chown -R chroma:chroma /chroma && \ 14 | apt-get update -qq && apt-get install sqlite3 sudo -y && \ 15 | echo 'chroma ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers && \ 16 | chown -R chroma:chroma /docker_entrypoint.sh 17 | EXPOSE 8000 18 | USER chroma 19 | 20 | CMD ["/docker_entrypoint.sh"] 21 | -------------------------------------------------------------------------------- /image/docker_entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | export CHROMA_SERVER_HTTP_PORT=${CHROMA_SERVER_HTTP_PORT:-8000} 3 | export CHROMA_SERVER_LOG_CONFIG=${CHROMA_SERVER_LOG_CONFIG:-log_config.yaml} 4 | export CHROMA_SERVER_HOST=${CHROMA_SERVER_HOST:-"0.0.0.0"} 5 | 6 | sudo chown -R chroma:chroma ${PERSIST_DIRECTORY} 7 | 8 | . /chroma/venv/bin/activate 9 | #pip install --force-reinstall --no-cache-dir chroma-hnswlib 10 | uvicorn chromadb.app:app --workers 1 --host ${CHROMA_SERVER_HOST} --port ${CHROMA_SERVER_HTTP_PORT} --proxy-headers --log-config ${CHROMA_SERVER_LOG_CONFIG} 11 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | chromadb-client==0.4.3.dev0 2 | pytest==7.4.0 3 | openai 4 | python-dotenv 5 | sentence_transformers -------------------------------------------------------------------------------- /tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amikos-tech/chromadb-chart/e75846c536405f9873f056702e76a5d306debb91/tests/__init__.py -------------------------------------------------------------------------------- /tests/test_chroma.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import os 3 | import uuid 4 | 5 | import chromadb 6 | from chromadb.utils import embedding_functions 7 | from dotenv import load_dotenv 8 | 9 | load_dotenv() 10 | 11 | logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.DEBUG) 12 | logger = logging.getLogger(__name__) 13 | 14 | 15 | def get_embedding_function(): 16 | """ 17 | Get the embedding function 18 | 19 | :return: Embedding function 20 | """ 21 | 22 | openai_ef = embedding_functions.OpenAIEmbeddingFunction( 23 | model_name="text-embedding-ada-002", 24 | api_key=os.environ.get('OPENAI_API_KEY') 25 | ) 26 | return openai_ef 27 | 28 | 29 | sentence_transformer_ef = embedding_functions.SentenceTransformerEmbeddingFunction(model_name="all-MiniLM-L6-v2") 30 | 31 | 32 | def test_chroma(): 33 | client = chromadb.HttpClient() 34 | client.heartbeat() 35 | # client.reset() 36 | collection = client.get_or_create_collection("all1-my-documents", 37 | embedding_function=sentence_transformer_ef) 38 | transf = sentence_transformer_ef(["this is a test embedding"]) 39 | print(transf) 40 | # collection.add(documents=["this is a test embedding"], metadatas=[{"type": "page"}], ids=[str(uuid.uuid4())]) 41 | # assert len(collection.get()['ids']) == 1 42 | 43 | 44 | def test_reset(): 45 | client = chromadb.HttpClient(host="localhost", port=8000) 46 | client.heartbeat() 47 | client.reset() 48 | 49 | 50 | def test_auth(): 51 | client = chromadb.HttpClient(host="localhost", port="8000", headers={"Authorization": "Token test"}) 52 | client.heartbeat() 53 | 54 | 55 | if __name__ == '__main__': 56 | test_chroma() 57 | --------------------------------------------------------------------------------