Skip to content

Commit cc1f4d5

Browse files
committed
feat: add Dockerfile and Helm chart for Kubernetes deployment
- Add production-ready Dockerfile with multi-stage build - Add Helm chart with support for: - MemOS API service - Neo4j graph database - Qdrant vector database - Ingress configuration - Add example values file with common configurations
1 parent 05dc915 commit cc1f4d5

File tree

11 files changed

+840
-0
lines changed

11 files changed

+840
-0
lines changed

Dockerfile

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# MemOS Production Dockerfile
2+
# Multi-stage build with optimizations
3+
4+
# Stage 1: Install dependencies
5+
FROM python:3.11-slim AS builder
6+
7+
RUN apt-get update && apt-get install -y \
8+
gcc \
9+
g++ \
10+
build-essential \
11+
libffi-dev \
12+
python3-dev \
13+
curl \
14+
&& rm -rf /var/lib/apt/lists/*
15+
16+
WORKDIR /build
17+
18+
COPY docker/requirements.txt .
19+
RUN pip install --upgrade pip && \
20+
pip install --prefix=/install --no-cache-dir -r requirements.txt
21+
22+
# Stage 2: Runtime image
23+
FROM python:3.11-slim
24+
25+
RUN apt-get update && apt-get install -y \
26+
curl \
27+
&& rm -rf /var/lib/apt/lists/* \
28+
&& useradd -m -u 1000 memos
29+
30+
WORKDIR /app
31+
32+
ENV HF_ENDPOINT=https://hf-mirror.com
33+
ENV PYTHONPATH=/app/src
34+
ENV PYTHONDONTWRITEBYTECODE=1
35+
ENV PYTHONUNBUFFERED=1
36+
37+
COPY --from=builder /install /usr/local
38+
COPY src/ ./src
39+
COPY docker/ ./docker
40+
41+
RUN chown -R memos:memos /app
42+
43+
USER memos
44+
45+
EXPOSE 8000
46+
47+
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
48+
CMD curl -f http://localhost:8000/health || exit 1
49+
50+
CMD ["uvicorn", "memos.api.server_api:app", "--host", "0.0.0.0", "--port", "8000"]

deploy/helm/Chart.yaml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
apiVersion: v2
2+
name: memos
3+
description: MemOS - AI Memory Operating System for LLM and Agent systems
4+
type: application
5+
version: 1.0.0
6+
appVersion: "2.0.9"
7+
keywords:
8+
- memory
9+
- llm
10+
- agent
11+
- ai
12+
- vector-database
13+
- graph-database
14+
home: https://memos.openmem.net
15+
sources:
16+
- https://github.com/MemTensor/MemOS
17+
maintainers:
18+
- name: MemTensor
19+
url: https://github.com/MemTensor

deploy/helm/README.md

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
# MemOS Helm Chart
2+
3+
MemOS - AI Memory Operating System for LLM and Agent systems.
4+
5+
## Prerequisites
6+
7+
- Kubernetes 1.20+
8+
- Helm 3.0+
9+
- PV provisioner support in the underlying infrastructure
10+
11+
## Components
12+
13+
| Component | Description | Port |
14+
|-----------|-------------|------|
15+
| memos-api | Main API service | 8000 |
16+
| neo4j | Graph database | 7474 (HTTP), 7687 (Bolt) |
17+
| qdrant | Vector database | 6333 (HTTP), 6334 (gRPC) |
18+
19+
## Quick Start
20+
21+
### 1. Build Docker Image
22+
23+
```bash
24+
# From repo root
25+
docker build -t memos:2.0.9 .
26+
```
27+
28+
### 2. Push to Registry
29+
30+
```bash
31+
docker tag memos:2.0.9 your-registry/memos:2.0.9
32+
docker push your-registry/memos:2.0.9
33+
```
34+
35+
### 3. Configure Values
36+
37+
```bash
38+
cp deploy/helm/values-example.yaml my-values.yaml
39+
40+
# Edit my-values.yaml with your settings:
41+
# - OPENAI_API_KEY
42+
# - MEMRADER_API_KEY
43+
# - image.repository (your registry)
44+
```
45+
46+
### 4. Install
47+
48+
```bash
49+
helm install memos deploy/helm -f my-values.yaml -n memos --create-namespace
50+
```
51+
52+
## Configuration
53+
54+
### Required Settings
55+
56+
```yaml
57+
memos:
58+
image:
59+
repository: your-registry/memos
60+
tag: "2.0.9"
61+
env:
62+
OPENAI_API_KEY: "sk-your-key"
63+
MEMRADER_API_KEY: "sk-your-key"
64+
```
65+
66+
### Enable Ingress
67+
68+
```yaml
69+
ingress:
70+
enabled: true
71+
className: nginx
72+
hosts:
73+
- host: memos.yourdomain.com
74+
paths:
75+
- path: /
76+
pathType: Prefix
77+
```
78+
79+
### Use External Neo4j/Qdrant
80+
81+
```yaml
82+
neo4j:
83+
enabled: false
84+
85+
qdrant:
86+
enabled: false
87+
88+
memos:
89+
env:
90+
NEO4J_URI: "bolt://external-neo4j:7687"
91+
NEO4J_USER: "neo4j"
92+
NEO4J_PASSWORD: "password"
93+
QDRANT_HOST: "external-qdrant"
94+
QDRANT_PORT: "6333"
95+
```
96+
97+
## Values Reference
98+
99+
| Key | Default | Description |
100+
|-----|---------|-------------|
101+
| `memos.replicaCount` | `1` | API replicas |
102+
| `memos.image.repository` | `memos/memos` | Image repository |
103+
| `memos.image.tag` | `2.0.9` | Image tag |
104+
| `memos.service.type` | `ClusterIP` | Service type |
105+
| `memos.service.port` | `8000` | Service port |
106+
| `neo4j.enabled` | `true` | Enable Neo4j |
107+
| `neo4j.auth.password` | `memos123456` | Neo4j password |
108+
| `neo4j.persistence.size` | `10Gi` | Neo4j data size |
109+
| `qdrant.enabled` | `true` | Enable Qdrant |
110+
| `qdrant.persistence.size` | `10Gi` | Qdrant data size |
111+
| `ingress.enabled` | `false` | Enable Ingress |
112+
113+
## API Endpoints
114+
115+
```bash
116+
# Add memory
117+
curl -X POST http://memos-api:8000/product/add \
118+
-H "Content-Type: application/json" \
119+
-d '{
120+
"user_id": "test-user",
121+
"mem_cube_id": "test-cube",
122+
"messages": [{"role": "user", "content": "I like strawberry"}],
123+
"async_mode": "sync"
124+
}'
125+
126+
# Search memory
127+
curl -X POST http://memos-api:8000/product/search \
128+
-H "Content-Type: application/json" \
129+
-d '{
130+
"query": "What do I like",
131+
"user_id": "test-user",
132+
"mem_cube_id": "test-cube"
133+
}'
134+
```
135+
136+
## Uninstall
137+
138+
```bash
139+
helm uninstall memos -n memos
140+
kubectl delete namespace memos
141+
```
142+
143+
## Troubleshooting
144+
145+
```bash
146+
# Check logs
147+
kubectl logs -n memos -l app.kubernetes.io/component=api
148+
149+
# Check Neo4j
150+
kubectl exec -n memos -it deployment/memos-neo4j -- cypher-shell -u neo4j -p memos123456
151+
152+
# Check Qdrant
153+
kubectl exec -n memos -it deployment/memos-qdrant -- curl localhost:6333
154+
```

deploy/helm/templates/_helpers.tpl

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
{{- define "memos.name" -}}
2+
memos
3+
{{- end }}
4+
5+
{{- define "memos.fullname" -}}
6+
{{- if .Values.fullnameOverride }}
7+
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
8+
{{- else }}
9+
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
10+
{{- end }}
11+
{{- end }}
12+
13+
{{- define "memos.labels" -}}
14+
app.kubernetes.io/name: {{ include "memos.name" . }}
15+
app.kubernetes.io/instance: {{ .Release.Name }}
16+
app.kubernetes.io/version: {{ .Chart.AppVersion }}
17+
{{- end }}
18+
19+
{{- define "memos.neo4j.fullname" -}}
20+
{{- printf "%s-neo4j" (include "memos.fullname" .) }}
21+
{{- end }}
22+
23+
{{- define "memos.qdrant.fullname" -}}
24+
{{- printf "%s-qdrant" (include "memos.fullname" .) }}
25+
{{- end }}
26+
27+
{{- define "memos.memos.fullname" -}}
28+
{{- printf "%s-api" (include "memos.fullname" .) }}
29+
{{- end }}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
apiVersion: v1
2+
kind: ConfigMap
3+
metadata:
4+
name: {{ include "memos.memos.fullname" . }}
5+
labels:
6+
{{- include "memos.labels" . | nindent 4 }}
7+
data:
8+
TZ: {{ .Values.memos.env.TZ | quote }}
9+
MOS_CUBE_PATH: {{ .Values.memos.env.MOS_CUBE_PATH | quote }}
10+
MEMOS_BASE_PATH: {{ .Values.memos.env.MEMOS_BASE_PATH | quote }}
11+
MOS_ENABLE_DEFAULT_CUBE_CONFIG: {{ .Values.memos.env.MOS_ENABLE_DEFAULT_CUBE_CONFIG | quote }}
12+
MOS_ENABLE_REORGANIZE: {{ .Values.memos.env.MOS_ENABLE_REORGANIZE | quote }}
13+
MOS_TEXT_MEM_TYPE: {{ .Values.memos.env.MOS_TEXT_MEM_TYPE | quote }}
14+
ASYNC_MODE: {{ .Values.memos.env.ASYNC_MODE | quote }}
15+
MOS_TOP_K: {{ .Values.memos.env.MOS_TOP_K | quote }}
16+
MOS_CHAT_MODEL: {{ .Values.memos.env.MOS_CHAT_MODEL | quote }}
17+
MOS_CHAT_TEMPERATURE: {{ .Values.memos.env.MOS_CHAT_TEMPERATURE | quote }}
18+
MOS_MAX_TOKENS: {{ .Values.memos.env.MOS_MAX_TOKENS | quote }}
19+
MOS_TOP_P: {{ .Values.memos.env.MOS_TOP_P | quote }}
20+
MOS_CHAT_MODEL_PROVIDER: {{ .Values.memos.env.MOS_CHAT_MODEL_PROVIDER | quote }}
21+
OPENAI_API_BASE: {{ .Values.memos.env.OPENAI_API_BASE | quote }}
22+
MEMRADER_MODEL: {{ .Values.memos.env.MEMRADER_MODEL | quote }}
23+
MEMRADER_API_BASE: {{ .Values.memos.env.MEMRADER_API_BASE | quote }}
24+
MEMRADER_MAX_TOKENS: {{ .Values.memos.env.MEMRADER_MAX_TOKENS | quote }}
25+
EMBEDDING_DIMENSION: {{ .Values.memos.env.EMBEDDING_DIMENSION | quote }}
26+
MOS_EMBEDDER_BACKEND: {{ .Values.memos.env.MOS_EMBEDDER_BACKEND | quote }}
27+
MOS_EMBEDDER_PROVIDER: {{ .Values.memos.env.MOS_EMBEDDER_PROVIDER | quote }}
28+
MOS_EMBEDDER_MODEL: {{ .Values.memos.env.MOS_EMBEDDER_MODEL | quote }}
29+
MOS_EMBEDDER_API_BASE: {{ .Values.memos.env.MOS_EMBEDDER_API_BASE | quote }}
30+
MOS_EMBEDDER_API_KEY: {{ .Values.memos.env.MOS_EMBEDDER_API_KEY | quote }}
31+
MOS_RERANKER_BACKEND: {{ .Values.memos.env.MOS_RERANKER_BACKEND | quote }}
32+
MOS_RERANKER_URL: {{ .Values.memos.env.MOS_RERANKER_URL | quote }}
33+
MOS_RERANKER_MODEL: {{ .Values.memos.env.MOS_RERANKER_MODEL | quote }}
34+
MOS_RERANKER_STRATEGY: {{ .Values.memos.env.MOS_RERANKER_STRATEGY | quote }}
35+
ENABLE_INTERNET: {{ .Values.memos.env.ENABLE_INTERNET | quote }}
36+
ENABLE_PREFERENCE_MEMORY: {{ .Values.memos.env.ENABLE_PREFERENCE_MEMORY | quote }}
37+
PREFERENCE_ADDER_MODE: {{ .Values.memos.env.PREFERENCE_ADDER_MODE | quote }}
38+
MOS_ENABLE_SCHEDULER: {{ .Values.memos.env.MOS_ENABLE_SCHEDULER | quote }}
39+
MOS_SCHEDULER_TOP_K: {{ .Values.memos.env.MOS_SCHEDULER_TOP_K | quote }}
40+
NEO4J_BACKEND: {{ .Values.memos.env.NEO4J_BACKEND | quote }}
41+
NEO4J_URI: "bolt://{{ include "memos.neo4j.fullname" . }}:7687"
42+
NEO4J_USER: {{ .Values.neo4j.auth.user | quote }}
43+
NEO4J_PASSWORD: {{ .Values.neo4j.auth.password | quote }}
44+
NEO4J_DB_NAME: {{ .Values.memos.env.NEO4J_DB_NAME | quote }}
45+
MOS_NEO4J_SHARED_DB: {{ .Values.memos.env.MOS_NEO4J_SHARED_DB | quote }}
46+
QDRANT_HOST: {{ include "memos.qdrant.fullname" . }}
47+
QDRANT_PORT: "6333"
48+
PYTHONPATH: "/app/src"

deploy/helm/templates/ingress.yaml

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
{{- if .Values.ingress.enabled }}
2+
apiVersion: networking.k8s.io/v1
3+
kind: Ingress
4+
metadata:
5+
name: {{ include "memos.memos.fullname" . }}
6+
labels:
7+
{{- include "memos.labels" . | nindent 4 }}
8+
{{- with .Values.ingress.annotations }}
9+
annotations:
10+
{{- toYaml . | nindent 4 }}
11+
{{- end }}
12+
spec:
13+
{{- if .Values.ingress.className }}
14+
ingressClassName: {{ .Values.ingress.className }}
15+
{{- end }}
16+
{{- if .Values.ingress.tls }}
17+
tls:
18+
{{- range .Values.ingress.tls }}
19+
- hosts:
20+
{{- range .hosts }}
21+
- {{ . | quote }}
22+
{{- end }}
23+
secretName: {{ .secretName }}
24+
{{- end }}
25+
{{- end }}
26+
rules:
27+
{{- range .Values.ingress.hosts }}
28+
- host: {{ .host | quote }}
29+
http:
30+
paths:
31+
{{- range .paths }}
32+
- path: {{ .path }}
33+
pathType: {{ .pathType }}
34+
backend:
35+
service:
36+
name: {{ include "memos.memos.fullname" $ }}
37+
port:
38+
number: {{ $.Values.memos.service.port }}
39+
{{- end }}
40+
{{- end }}
41+
{{- end }}

0 commit comments

Comments
 (0)