From cb2ae321e5f732a96a62778c04953855d6246810 Mon Sep 17 00:00:00 2001 From: Sakshar Dhawan Date: Thu, 9 Apr 2026 12:18:01 +0530 Subject: [PATCH 1/2] feat: add multi-stage Dockerfile and enhanced docker-compose deployment guide --- Dockerfile | 28 +++++++++++++++++++--------- README.md | 38 +++++++++++++++++++++++--------------- docker-compose.yml | 9 ++++++++- 3 files changed, 50 insertions(+), 25 deletions(-) diff --git a/Dockerfile b/Dockerfile index 1725842..de7c204 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,21 +1,31 @@ -FROM oven/bun:latest +# 1. Base stage +FROM oven/bun:1 AS base +WORKDIR /app + +# 2. Dependencies stage +FROM base AS install +RUN mkdir -p /temp/prod +COPY package.json bun.lock /temp/prod/ +RUN cd /temp/prod && bun install --frozen-lockfile --production +# 3. Final release stage +FROM base AS release RUN apt-get update -qq && apt-get install -y -qq cron wget && rm -rf /var/lib/apt/lists/* ENV TZ=UTC +ENV NODE_ENV=production -WORKDIR /app +# Copy production dependencies +COPY --from=install /temp/prod/node_modules node_modules -# Install deps -COPY package.json bun.lock ./ -RUN bun install --frozen-lockfile 2>/dev/null || bun install - -# Copy source +# Copy source code and config files COPY src/ ./src/ -COPY tsconfig.json ./ +COPY package.json tsconfig.json ./ # Data volume for SQLite -RUN mkdir -p /app/data +RUN mkdir -p /app/data && chown -R bun:bun /app/data + +USER bun ENV BRAINDB_PORT=3197 ENV BRAINDB_PATH=/app/data/memories.db diff --git a/README.md b/README.md index f292658..2f42f70 100644 --- a/README.md +++ b/README.md @@ -39,21 +39,29 @@ An open-source project. ### Docker (recommended) -```bash -# Clone the repo -git clone https://github.com/your-org/braindb.git -cd braindb - -# Configure -cp .env.example .env -# Edit .env with your settings (at minimum: MISTRAL_API_KEY for LLM features) - -# Start -docker compose up -d - -# Verify -curl http://localhost:3197/health -``` +1. **Clone and Configure**: + ```bash + git clone https://github.com/beckfexx/BrainDB.git + cd BrainDB + cp .env.example .env + # Edit .env to set your BRAINDB_API_KEY and LLM settings + ``` + +2. **Deploy with Docker Compose**: + ```bash + docker compose up -d + ``` + +**Persistence & Data**: +BrainDB uses a SQLite database. When running via Docker Compose, a named volume `braindb_data` is created to persist your memories across container restarts. By default, the database is stored at `/app/data/memories.db` inside the container. + +**Port Mapping**: +The server runs on port `3197` by default. You can change the host port by setting `BRAINDB_PORT` in your `.env` file. + +3. **Verify**: + ```bash + curl http://localhost:3197/health + ``` ### Bare Metal (Bun) diff --git a/docker-compose.yml b/docker-compose.yml index 14b9825..754cf89 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -7,10 +7,17 @@ services: - "${BRAINDB_PORT:-3197}:3197" volumes: - braindb_data:/app/data - env_file: .env + env_file: .env # Loads all variables from .env if present environment: + # These ensure the container knows where to look for data internally - BRAINDB_PORT=3197 - BRAINDB_PATH=/app/data/memories.db + - BRAINDB_BACKUP_DIR=/app/data/backups + + # You can override .env variables here if needed + # - MISTRAL_API_KEY=${MISTRAL_API_KEY} + # - OLLAMA_URL=${OLLAMA_URL} volumes: braindb_data: + driver: local From c52f501da226dc1229a2694e4e0af32095b7d30c Mon Sep 17 00:00:00 2001 From: Sakshar Dhawan Date: Thu, 9 Apr 2026 12:38:26 +0530 Subject: [PATCH 2/2] feat: add Helm chart for Kubernetes deployment with persistence and Ollama sidecar --- README.md | 27 +++++--- helm/braindb/Chart.yaml | 12 ++++ helm/braindb/templates/_helpers.tpl | 51 ++++++++++++++ helm/braindb/templates/deployment.yaml | 92 ++++++++++++++++++++++++++ helm/braindb/templates/pvc.yaml | 17 +++++ helm/braindb/templates/service.yaml | 15 +++++ helm/braindb/values.yaml | 62 +++++++++++++++++ 7 files changed, 266 insertions(+), 10 deletions(-) create mode 100644 helm/braindb/Chart.yaml create mode 100644 helm/braindb/templates/_helpers.tpl create mode 100644 helm/braindb/templates/deployment.yaml create mode 100644 helm/braindb/templates/pvc.yaml create mode 100644 helm/braindb/templates/service.yaml create mode 100644 helm/braindb/values.yaml diff --git a/README.md b/README.md index 2f42f70..75d0161 100644 --- a/README.md +++ b/README.md @@ -63,19 +63,26 @@ The server runs on port `3197` by default. You can change the host port by setti curl http://localhost:3197/health ``` -### Bare Metal (Bun) +### Kubernetes (Helm) -```bash -# Prerequisites: Bun >= 1.0 or Node.js >= 22 -bun install -cp .env.example .env +1. **Navigate to chart**: + ```bash + cd helm/braindb + ``` -# Start the API server -bun run start +2. **Configure values**: + Edit `values.yaml` to enable the Ollama sidecar or adjust persistence settings: + ```yaml + ollama: + enabled: true + persistence: + size: 10Gi + ``` -# Or run the MCP server (stdio) -bun run mcp -``` +3. **Install**: + ```bash + helm install braindb . + ``` ## Architecture diff --git a/helm/braindb/Chart.yaml b/helm/braindb/Chart.yaml new file mode 100644 index 0000000..84a7150 --- /dev/null +++ b/helm/braindb/Chart.yaml @@ -0,0 +1,12 @@ +apiVersion: v2 +name: braindb +description: A Helm chart for BrainDB - Persistent AI Memory System +type: application +version: 0.1.0 +appVersion: "2.0.0" +keywords: + - ai + - memory + - sqlite + - mcp + - agents diff --git a/helm/braindb/templates/_helpers.tpl b/helm/braindb/templates/_helpers.tpl new file mode 100644 index 0000000..cf9f344 --- /dev/null +++ b/helm/braindb/templates/_helpers.tpl @@ -0,0 +1,51 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "braindb.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "braindb.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "braindb.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "braindb.labels" -}} +helm.sh/chart: {{ include "braindb.chart" . }} +{{ include "braindb.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "braindb.selectorLabels" -}} +app.kubernetes.io/name: {{ include "braindb.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} diff --git a/helm/braindb/templates/deployment.yaml b/helm/braindb/templates/deployment.yaml new file mode 100644 index 0000000..74ce1c4 --- /dev/null +++ b/helm/braindb/templates/deployment.yaml @@ -0,0 +1,92 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "braindb.fullname" . }} + labels: + {{- include "braindb.labels" . | nindent 4 }} +spec: + replicas: {{ .Values.replicaCount }} + selector: + matchLabels: + {{- include "braindb.selectorLabels" . | nindent 6 }} + template: + metadata: + labels: + {{- include "braindb.selectorLabels" . | nindent 8 }} + spec: + containers: + # Main BrainDB Container + - name: {{ .Chart.Name }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + ports: + - name: http + containerPort: 3197 + protocol: TCP + livenessProbe: + httpGet: + path: /health + port: http + readinessProbe: + httpGet: + path: /health + port: http + env: + - name: BRAINDB_PORT + value: "3197" + - name: BRAINDB_PATH + value: "{{ .Values.persistence.mountPath }}/memories.db" + - name: BRAINDB_API_KEY + value: {{ .Values.config.api_key | quote }} + - name: MISTRAL_API_KEY + value: {{ .Values.config.mistral_api_key | quote }} + - name: OLLAMA_URL + value: {{ .Values.config.ollama_url | quote }} + - name: SEARXNG_URL + value: {{ .Values.config.searxng_url | quote }} + resources: + {{- toYaml .Values.resources | nindent 12 }} + volumeMounts: + - name: data + mountPath: {{ .Values.persistence.mountPath }} + + # Optional Ollama Sidecar + {{- if .Values.ollama.enabled }} + - name: ollama + image: "{{ .Values.ollama.image.repository }}:{{ .Values.ollama.image.tag }}" + ports: + - name: ollama + containerPort: 11434 + protocol: TCP + resources: + {{- toYaml .Values.ollama.resources | nindent 12 }} + volumeMounts: + - name: ollama-data + mountPath: /root/.ollama + {{- end }} + + volumes: + - name: data + {{- if .Values.persistence.enabled }} + persistentVolumeClaim: + claimName: {{ include "braindb.fullname" . }} + {{- else }} + emptyDir: {} + {{- end }} + {{- if .Values.ollama.enabled }} + - name: ollama-data + emptyDir: {} + {{- end }} + + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} diff --git a/helm/braindb/templates/pvc.yaml b/helm/braindb/templates/pvc.yaml new file mode 100644 index 0000000..56124e7 --- /dev/null +++ b/helm/braindb/templates/pvc.yaml @@ -0,0 +1,17 @@ +{{- if .Values.persistence.enabled -}} +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: {{ include "braindb.fullname" . }} + labels: + {{- include "braindb.labels" . | nindent 4 }} +spec: + accessModes: + - {{ .Values.persistence.accessMode | quote }} + resources: + requests: + storage: {{ .Values.persistence.size | quote }} + {{- if .Values.persistence.storageClass }} + storageClassName: {{ .Values.persistence.storageClass | quote }} + {{- end }} +{{- end }} diff --git a/helm/braindb/templates/service.yaml b/helm/braindb/templates/service.yaml new file mode 100644 index 0000000..adb5dfe --- /dev/null +++ b/helm/braindb/templates/service.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "braindb.fullname" . }} + labels: + {{- include "braindb.labels" . | nindent 4 }} +spec: + type: {{ .Values.service.type }} + ports: + - port: {{ .Values.service.port }} + targetPort: 3197 + protocol: TCP + name: http + selector: + {{- include "braindb.selectorLabels" . | nindent 4 }} diff --git a/helm/braindb/values.yaml b/helm/braindb/values.yaml new file mode 100644 index 0000000..1d75854 --- /dev/null +++ b/helm/braindb/values.yaml @@ -0,0 +1,62 @@ +# Default values for braindb. +# This is a YAML-formatted file. + +replicaCount: 1 + +image: + repository: sakshar2303/braindb + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: "" + +nameOverride: "" +fullnameOverride: "" + +service: + type: ClusterIP + port: 3197 + +# BrainDB Configuration +config: + # Refer to .env.example for all available variables + api_key: "" + mistral_api_key: "" + ollama_url: "http://localhost:11434" # Default for sidecar + searxng_url: "http://searxng.searxng.svc.cluster.local:8080" + +# persistence for SQLite database +persistence: + enabled: true + storageClass: "standard" + accessMode: ReadWriteOnce + size: 10Gi + mountPath: /app/data + +# Ollama Sidecar (Optional) +ollama: + enabled: false + image: + repository: ollama/ollama + tag: latest + resources: + limits: + cpu: 2 + memory: 4Gi + # nvidia.com/gpu: 1 # Uncomment if you have GPU nodes + requests: + cpu: 1 + memory: 2Gi + +resources: + limits: + cpu: 500m + memory: 512Mi + requests: + cpu: 200m + memory: 256Mi + +nodeSelector: {} + +tolerations: [] + +affinity: {}