Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# MemOS Production Dockerfile
# Multi-stage build with optimizations

# Stage 1: Install dependencies
FROM python:3.11-slim AS builder

RUN apt-get update && apt-get install -y \
gcc \
g++ \
build-essential \
libffi-dev \
python3-dev \
curl \
&& rm -rf /var/lib/apt/lists/*

WORKDIR /build

COPY docker/requirements.txt .
RUN pip install --upgrade pip && \
pip install --prefix=/install --no-cache-dir -r requirements.txt

# Stage 2: Runtime image
FROM python:3.11-slim

RUN apt-get update && apt-get install -y \
curl \
&& rm -rf /var/lib/apt/lists/* \
&& useradd -m -u 1000 memos

WORKDIR /app

ENV HF_ENDPOINT=https://hf-mirror.com
ENV PYTHONPATH=/app/src
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1

COPY --from=builder /install /usr/local
COPY src/ ./src
COPY docker/ ./docker

RUN chown -R memos:memos /app

USER memos

EXPOSE 8000

HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
CMD curl -f http://localhost:8000/health || exit 1

CMD ["uvicorn", "memos.api.server_api:app", "--host", "0.0.0.0", "--port", "8000"]
19 changes: 19 additions & 0 deletions deploy/helm/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
apiVersion: v2
name: memos
description: MemOS - AI Memory Operating System for LLM and Agent systems
type: application
version: 1.0.0
appVersion: "2.0.9"
keywords:
- memory
- llm
- agent
- ai
- vector-database
- graph-database
home: https://memos.openmem.net
sources:
- https://github.com/MemTensor/MemOS
maintainers:
- name: MemTensor
url: https://github.com/MemTensor
154 changes: 154 additions & 0 deletions deploy/helm/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
# MemOS Helm Chart

MemOS - AI Memory Operating System for LLM and Agent systems.

## Prerequisites

- Kubernetes 1.20+
- Helm 3.0+
- PV provisioner support in the underlying infrastructure

## Components

| Component | Description | Port |
|-----------|-------------|------|
| memos-api | Main API service | 8000 |
| neo4j | Graph database | 7474 (HTTP), 7687 (Bolt) |
| qdrant | Vector database | 6333 (HTTP), 6334 (gRPC) |

## Quick Start

### 1. Build Docker Image

```bash
# From repo root
docker build -t memos:2.0.9 .
```

### 2. Push to Registry

```bash
docker tag memos:2.0.9 your-registry/memos:2.0.9
docker push your-registry/memos:2.0.9
```

### 3. Configure Values

```bash
cp deploy/helm/values-example.yaml my-values.yaml

# Edit my-values.yaml with your settings:
# - OPENAI_API_KEY
# - MEMRADER_API_KEY
# - image.repository (your registry)
```

### 4. Install

```bash
helm install memos deploy/helm -f my-values.yaml -n memos --create-namespace
```

## Configuration

### Required Settings

```yaml
memos:
image:
repository: your-registry/memos
tag: "2.0.9"
env:
OPENAI_API_KEY: "sk-your-key"
MEMRADER_API_KEY: "sk-your-key"
```

### Enable Ingress

```yaml
ingress:
enabled: true
className: nginx
hosts:
- host: memos.yourdomain.com
paths:
- path: /
pathType: Prefix
```

### Use External Neo4j/Qdrant

```yaml
neo4j:
enabled: false

qdrant:
enabled: false

memos:
env:
NEO4J_URI: "bolt://external-neo4j:7687"
NEO4J_USER: "neo4j"
NEO4J_PASSWORD: "password"
QDRANT_HOST: "external-qdrant"
QDRANT_PORT: "6333"
```

## Values Reference

| Key | Default | Description |
|-----|---------|-------------|
| `memos.replicaCount` | `1` | API replicas |
| `memos.image.repository` | `memos/memos` | Image repository |
| `memos.image.tag` | `2.0.9` | Image tag |
| `memos.service.type` | `ClusterIP` | Service type |
| `memos.service.port` | `8000` | Service port |
| `neo4j.enabled` | `true` | Enable Neo4j |
| `neo4j.auth.password` | `memos123456` | Neo4j password |
| `neo4j.persistence.size` | `10Gi` | Neo4j data size |
| `qdrant.enabled` | `true` | Enable Qdrant |
| `qdrant.persistence.size` | `10Gi` | Qdrant data size |
| `ingress.enabled` | `false` | Enable Ingress |

## API Endpoints

```bash
# Add memory
curl -X POST http://memos-api:8000/product/add \
-H "Content-Type: application/json" \
-d '{
"user_id": "test-user",
"mem_cube_id": "test-cube",
"messages": [{"role": "user", "content": "I like strawberry"}],
"async_mode": "sync"
}'

# Search memory
curl -X POST http://memos-api:8000/product/search \
-H "Content-Type: application/json" \
-d '{
"query": "What do I like",
"user_id": "test-user",
"mem_cube_id": "test-cube"
}'
```

## Uninstall

```bash
helm uninstall memos -n memos
kubectl delete namespace memos
```

## Troubleshooting

```bash
# Check logs
kubectl logs -n memos -l app.kubernetes.io/component=api

# Check Neo4j
kubectl exec -n memos -it deployment/memos-neo4j -- cypher-shell -u neo4j -p memos123456

# Check Qdrant
kubectl exec -n memos -it deployment/memos-qdrant -- curl localhost:6333
```
29 changes: 29 additions & 0 deletions deploy/helm/templates/_helpers.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{{- define "memos.name" -}}
memos
{{- end }}

{{- define "memos.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}

{{- define "memos.labels" -}}
app.kubernetes.io/name: {{ include "memos.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/version: {{ .Chart.AppVersion }}
{{- end }}

{{- define "memos.neo4j.fullname" -}}
{{- printf "%s-neo4j" (include "memos.fullname" .) }}
{{- end }}

{{- define "memos.qdrant.fullname" -}}
{{- printf "%s-qdrant" (include "memos.fullname" .) }}
{{- end }}

{{- define "memos.memos.fullname" -}}
{{- printf "%s-api" (include "memos.fullname" .) }}
{{- end }}
48 changes: 48 additions & 0 deletions deploy/helm/templates/configmap.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ include "memos.memos.fullname" . }}
labels:
{{- include "memos.labels" . | nindent 4 }}
data:
TZ: {{ .Values.memos.env.TZ | quote }}
MOS_CUBE_PATH: {{ .Values.memos.env.MOS_CUBE_PATH | quote }}
MEMOS_BASE_PATH: {{ .Values.memos.env.MEMOS_BASE_PATH | quote }}
MOS_ENABLE_DEFAULT_CUBE_CONFIG: {{ .Values.memos.env.MOS_ENABLE_DEFAULT_CUBE_CONFIG | quote }}
MOS_ENABLE_REORGANIZE: {{ .Values.memos.env.MOS_ENABLE_REORGANIZE | quote }}
MOS_TEXT_MEM_TYPE: {{ .Values.memos.env.MOS_TEXT_MEM_TYPE | quote }}
ASYNC_MODE: {{ .Values.memos.env.ASYNC_MODE | quote }}
MOS_TOP_K: {{ .Values.memos.env.MOS_TOP_K | quote }}
MOS_CHAT_MODEL: {{ .Values.memos.env.MOS_CHAT_MODEL | quote }}
MOS_CHAT_TEMPERATURE: {{ .Values.memos.env.MOS_CHAT_TEMPERATURE | quote }}
MOS_MAX_TOKENS: {{ .Values.memos.env.MOS_MAX_TOKENS | quote }}
MOS_TOP_P: {{ .Values.memos.env.MOS_TOP_P | quote }}
MOS_CHAT_MODEL_PROVIDER: {{ .Values.memos.env.MOS_CHAT_MODEL_PROVIDER | quote }}
OPENAI_API_BASE: {{ .Values.memos.env.OPENAI_API_BASE | quote }}
MEMRADER_MODEL: {{ .Values.memos.env.MEMRADER_MODEL | quote }}
MEMRADER_API_BASE: {{ .Values.memos.env.MEMRADER_API_BASE | quote }}
MEMRADER_MAX_TOKENS: {{ .Values.memos.env.MEMRADER_MAX_TOKENS | quote }}
EMBEDDING_DIMENSION: {{ .Values.memos.env.EMBEDDING_DIMENSION | quote }}
MOS_EMBEDDER_BACKEND: {{ .Values.memos.env.MOS_EMBEDDER_BACKEND | quote }}
MOS_EMBEDDER_PROVIDER: {{ .Values.memos.env.MOS_EMBEDDER_PROVIDER | quote }}
MOS_EMBEDDER_MODEL: {{ .Values.memos.env.MOS_EMBEDDER_MODEL | quote }}
MOS_EMBEDDER_API_BASE: {{ .Values.memos.env.MOS_EMBEDDER_API_BASE | quote }}
MOS_EMBEDDER_API_KEY: {{ .Values.memos.env.MOS_EMBEDDER_API_KEY | quote }}
MOS_RERANKER_BACKEND: {{ .Values.memos.env.MOS_RERANKER_BACKEND | quote }}
MOS_RERANKER_URL: {{ .Values.memos.env.MOS_RERANKER_URL | quote }}
MOS_RERANKER_MODEL: {{ .Values.memos.env.MOS_RERANKER_MODEL | quote }}
MOS_RERANKER_STRATEGY: {{ .Values.memos.env.MOS_RERANKER_STRATEGY | quote }}
ENABLE_INTERNET: {{ .Values.memos.env.ENABLE_INTERNET | quote }}
ENABLE_PREFERENCE_MEMORY: {{ .Values.memos.env.ENABLE_PREFERENCE_MEMORY | quote }}
PREFERENCE_ADDER_MODE: {{ .Values.memos.env.PREFERENCE_ADDER_MODE | quote }}
MOS_ENABLE_SCHEDULER: {{ .Values.memos.env.MOS_ENABLE_SCHEDULER | quote }}
MOS_SCHEDULER_TOP_K: {{ .Values.memos.env.MOS_SCHEDULER_TOP_K | quote }}
NEO4J_BACKEND: {{ .Values.memos.env.NEO4J_BACKEND | quote }}
NEO4J_URI: "bolt://{{ include "memos.neo4j.fullname" . }}:7687"
NEO4J_USER: {{ .Values.neo4j.auth.user | quote }}
NEO4J_PASSWORD: {{ .Values.neo4j.auth.password | quote }}
NEO4J_DB_NAME: {{ .Values.memos.env.NEO4J_DB_NAME | quote }}
MOS_NEO4J_SHARED_DB: {{ .Values.memos.env.MOS_NEO4J_SHARED_DB | quote }}
QDRANT_HOST: {{ include "memos.qdrant.fullname" . }}
QDRANT_PORT: "6333"
PYTHONPATH: "/app/src"
41 changes: 41 additions & 0 deletions deploy/helm/templates/ingress.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{{- if .Values.ingress.enabled }}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ include "memos.memos.fullname" . }}
labels:
{{- include "memos.labels" . | nindent 4 }}
{{- with .Values.ingress.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{- if .Values.ingress.className }}
ingressClassName: {{ .Values.ingress.className }}
{{- end }}
{{- if .Values.ingress.tls }}
tls:
{{- range .Values.ingress.tls }}
- hosts:
{{- range .hosts }}
- {{ . | quote }}
{{- end }}
secretName: {{ .secretName }}
{{- end }}
{{- end }}
rules:
{{- range .Values.ingress.hosts }}
- host: {{ .host | quote }}
http:
paths:
{{- range .paths }}
- path: {{ .path }}
pathType: {{ .pathType }}
backend:
service:
name: {{ include "memos.memos.fullname" $ }}
port:
number: {{ $.Values.memos.service.port }}
{{- end }}
{{- end }}
{{- end }}
Loading
Loading