forked from spences10/mcp-memory-libsql
-
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMakefile
More file actions
333 lines (287 loc) · 11.4 KB
/
Makefile
File metadata and controls
333 lines (287 loc) · 11.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
# Makefile for mcp-memory-libsql-go
SHELL := /bin/sh
# Variables
BINARY_NAME=mcp-memory-libsql-go
MAIN_PACKAGE=./cmd/${BINARY_NAME}
BINARY_LOCATION=$(shell pwd)/bin/$(BINARY_NAME)
INTEGRATION_TESTER=./cmd/integration-tester
INTEGRATION_TESTER_BINARY=$(shell pwd)/bin/integration-tester
VERSION ?= $(shell git describe --tags --always --dirty)
REVISION ?= $(shell git rev-parse HEAD)
BUILD_DATE = $(shell date -u +'%Y-%m-%dT%H:%M:%SZ')
LDFLAGS = -ldflags "-X github.com/ZanzyTHEbar/${BINARY_NAME}/internal/buildinfo.Version=$(VERSION) -X github.com/ZanzyTHEbar/${BINARY_NAME}/internal/buildinfo.Revision=$(REVISION) -X github.com/ZanzyTHEbar/${BINARY_NAME}/internal/buildinfo.BuildDate=$(BUILD_DATE)"
# Docker config
IMAGE ?= $(BINARY_NAME)
TAG ?= local
DOCKER_IMAGE := $(IMAGE):$(TAG)
ENV_FILE ?=
ENV_FILE_ARG := $(if $(ENV_FILE),--env-file $(ENV_FILE),)
PORT_SSE ?= 8080
PORT_METRICS ?= 9090
PROFILES ?= memory
PROFILE_FLAGS := $(foreach p,$(PROFILES),--profile $(p))
# Allow skipping host permission operations when creating data directories
# Useful when running make as non-root or when mounted files should keep
# host ownership. Set SKIP_CHOWN=1 to avoid chmod/chown operations.
HOST_UID ?= $(shell id -u)
HOST_GID ?= $(shell id -g)
# Default PROJECTS ownership to the runner's UID/GID unless overridden
PROJECTS_UID ?= $(HOST_UID)
PROJECTS_GID ?= $(HOST_GID)
# Default SKIP_CHOWN to 0 when running as root, otherwise 1; allow override
SKIP_CHOWN_DEFAULT := $(if $(filter 0,$(HOST_UID)),0,1)
SKIP_CHOWN ?= $(SKIP_CHOWN_DEFAULT)
# Default target
.PHONY: all
all: build
# Build the binary
.PHONY: build
build:
CGO_ENABLED=1 go build $(LDFLAGS) -o $(BINARY_LOCATION) $(MAIN_PACKAGE)
# Build the integration tester into bin/
.PHONY: build-integration
build-integration:
mkdir -p $(shell pwd)/bin
CGO_ENABLED=1 go build $(LDFLAGS) -o $(INTEGRATION_TESTER_BINARY) $(INTEGRATION_TESTER)
# Install dependencies
.PHONY: deps
deps:
go mod tidy
# Run tests
.PHONY: test
test:
go test ./...
# Run the server
.PHONY: run
run: build
$(BINARY_LOCATION)
# Build the docker image
.PHONY: docker docker-build
docker: docker-build
docker-build:
docker build \
--build-arg VERSION=$(VERSION) \
--build-arg REVISION=$(REVISION) \
--build-arg BUILD_DATE=$(BUILD_DATE) \
-t $(DOCKER_IMAGE) -f docker/Dockerfile .
.PHONY: docker-rebuild
docker-rebuild:
docker build --no-cache \
--build-arg VERSION=$(VERSION) \
--build-arg REVISION=$(REVISION) \
--build-arg BUILD_DATE=$(BUILD_DATE) \
-t $(DOCKER_IMAGE) .
# Ensure local data directory exists
.PHONY: data
data:
mkdir -p ./data ./data/projects ./ollama_models
# Only perform chmod when explicitly allowed and when running as root.
# If SKIP_CHOWN=1 or we're not root, skip to avoid "Operation not permitted".
if [ "$${SKIP_CHOWN}" = "1" ]; then \
echo "Makefile: SKIP_CHOWN=1 set, skipping chmod/chown on ./data and ./ollama_models"; \
elif [ "$(shell id -u)" != "0" ]; then \
echo "Makefile: not running as root, skipping chmod/chown on ./data and ./ollama_models"; \
else \
chmod -R 777 ./data ./ollama_models || true; \
fi
# Run the docker image (SSE default)
.PHONY: docker-run
docker-run: docker-run-sse
# Run the docker image with sse transport
.PHONY: docker-run-sse
docker-run-sse: data
docker run --rm $(ENV_FILE_ARG) \
-p $(PORT_SSE):$(PORT_SSE) -p $(PORT_METRICS):$(PORT_METRICS) \
-v $(shell pwd)/data:/data \
-e MODE=$(MODE) \
-e PORT=$(PORT_SSE) \
-e METRICS_PORT=$(PORT_METRICS) \
-e SKIP_CHOWN=$(SKIP_CHOWN) \
$(DOCKER_IMAGE) -transport sse -addr :$(PORT_SSE) -sse-endpoint /sse
# Run the docker image with stdio transport
.PHONY: docker-run-stdio
docker-run-stdio: data
docker run --rm $(ENV_FILE_ARG) \
-v $(shell pwd)/data:/data \
-e SKIP_CHOWN=$(SKIP_CHOWN) \
$(DOCKER_IMAGE) -transport stdio
# Run the docker image with multi-project mode (SSE)
.PHONY: docker-run-multi
docker-run-multi: data
docker run --rm $(ENV_FILE_ARG) \
-p $(PORT_SSE):$(PORT_SSE) -p $(PORT_METRICS):$(PORT_METRICS) \
-v $(shell pwd)/data:/data \
-e MODE=multi \
-e PORT=$(PORT_SSE) \
-e METRICS_PORT=$(PORT_METRICS) \
-e SKIP_CHOWN=$(SKIP_CHOWN) \
$(DOCKER_IMAGE) -transport sse -addr :$(PORT_SSE) -sse-endpoint /sse -projects-dir /data/projects
# End-to-end docker test workflow
## Silence command echoing for docker-test target while still printing our own echoes
.SILENT: docker-test
.PHONY: docker-test
docker-test: data
echo "Checking for existing image $(DOCKER_IMAGE)..."; \
exec ./scripts/ci-docker-test.sh $(ENV_FILE)
# Compose helpers
.PHONY: compose-up compose-down compose-logs compose-ps
compose-up:
docker compose $(PROFILE_FLAGS) up --build -d
compose-down:
docker compose down $(if $(WITH_VOLUMES),-v,)
compose-logs:
docker compose logs -f --tail=200 $(if $(SERVICE),$(SERVICE),)
compose-ps:
docker compose ps
# Ensure .env.ci exists with safe defaults for CI
.PHONY: ensure-env-ci
ensure-env-ci:
if [ -n "$(ENV_FILE)" ]; then env_target="$(ENV_FILE)"; else env_target=".env.ci"; fi; \
if [ -s "$$env_target" ]; then echo "Using existing $$env_target"; exit 0; fi; \
mode_value="$${MODE:-multi}"; \
if [ "$$mode_value" = "multi" ]; then \
printf '%s\n' "MODE=multi" "LIBSQL_URL=file:/data/libsql.db" "LIBSQL_AUTH_TOKEN=" "EMBEDDING_DIMS=4" "EMBEDDINGS_PROVIDER=" "EMBEDDINGS_ADAPT_MODE=" "DB_MAX_OPEN_CONNS=16" "DB_MAX_IDLE_CONNS=8" "DB_CONN_MAX_IDLE_SEC=30" "DB_CONN_MAX_LIFETIME_SEC=60" "HYBRID_SEARCH=true" "HYBRID_TEXT_WEIGHT=0.4" "HYBRID_VECTOR_WEIGHT=0.6" "HYBRID_RRF_K=60" "METRICS_PROMETHEUS=true" "METRICS_PORT=9090" "TRANSPORT=sse" "PROJECTS_DIR=/data/projects" "PORT=8090" "SSE_ENDPOINT=/sse" "MULTI_PROJECT_AUTH_REQUIRED=false" "MULTI_PROJECT_AUTO_INIT_TOKEN=true" "MULTI_PROJECT_DEFAULT_TOKEN=ci-token" "SKIP_CHOWN=0" "BUILD_DATE=${BUILD_DATE:-ci}" > "$$env_target"; \
else \
printf '%s\n' "MODE=single" "LIBSQL_URL=file:/data/libsql.db" "LIBSQL_AUTH_TOKEN=" "EMBEDDING_DIMS=4" "PROJECTS_DIR=/data/projects" "PORT=8090" "METRICS_PORT=9090" "SSE_ENDPOINT=/sse" "SKIP_CHOWN=0" "BUILD_DATE=${BUILD_DATE:-ci}" > "$$env_target"; \
fi; \
echo "Wrote $$env_target";
# Coolify production-style targets: separate build and run commands
.PHONY: coolify-prod-build coolify-prod-run coolify-prod-down coolify-prod-logs coolify-prod-ps
# Build the docker image and prepare data (no run)
coolify-prod-build: docker-build data
@echo "Coolify: building image for production-style (multi-project, SSE, auth off, ollama)"
# Run using existing image (separate from build)
# Rely on environment variables provided by Coolify's UI or the shell. Do NOT inline-set ENVs here.
# Use COOLIFY_PROFILES (defaults to 'memory ollama') so both services are started by default
coolify-prod-run:
@echo "Coolify: starting production-style (multi-project, SSE, auth off, ollama) (envs must be provided by environment/Coolify UI)"
docker compose up -d
coolify-prod-down:
@echo "Coolify: stopping production-style services"
docker compose down $(if $(WITH_VOLUMES),-v,)
coolify-prod-logs:
docker compose logs -f --tail=200 memory
coolify-prod-ps:
docker compose ps
# Legacy docker-compose aliases (optional)
.PHONY: docker-compose
docker-compose: compose-up
# Production run profile (Ollama, SSE, multi-project, hybrid, pooling, metrics)
.PHONY: env-prod prod prod-down prod-logs prod-ps
# Generate a production env file used by compose
env-prod:
@echo "Writing .env.prod..."
@{ \
echo "EMBEDDINGS_PROVIDER=ollama"; \
echo "OLLAMA_HOST=http://ollama:11434"; \
echo "OLLAMA_EMBEDDINGS_MODEL=nomic-embed-text"; \
echo "EMBEDDING_DIMS=768"; \
echo "EMBEDDINGS_ADAPT_MODE=pad_or_truncate"; \
echo; \
echo "HYBRID_SEARCH=true"; \
echo "HYBRID_TEXT_WEIGHT=0.4"; \
echo "HYBRID_VECTOR_WEIGHT=0.6"; \
echo "HYBRID_RRF_K=60"; \
echo; \
echo "DB_MAX_OPEN_CONNS=16"; \
echo "DB_MAX_IDLE_CONNS=8"; \
echo "DB_CONN_MAX_IDLE_SEC=60"; \
echo "DB_CONN_MAX_LIFETIME_SEC=300"; \
echo; \
echo "METRICS_PROMETHEUS=true"; \
echo "METRICS_PORT=9090"; \
echo; \
echo "TRANSPORT=sse"; \
echo "PORT=8090"; \
echo "SSE_ENDPOINT=/sse"; \
echo; \
echo "# Multi-project auth toggles"; \
echo "MULTI_PROJECT_AUTH_REQUIRED=false"; \
echo "MULTI_PROJECT_AUTO_INIT_TOKEN=true"; \
echo "MULTI_PROJECT_DEFAULT_TOKEN=dev-token"; \
echo; \
echo "# Optional remote DB settings (leave blank for local files)"; \
echo "LIBSQL_URL="; \
echo "LIBSQL_AUTH_TOKEN="; \
} > .env.prod
ollama-local: docker-build data env-ollama
# Ollama local: multi-project SSE, auth off, embeddings=ollama (local env)
docker compose -f docker/docker-compose.ollama.yml --env-file .env.ollama up --build -d
ollama-local-down: env-ollama
docker compose -f docker/docker-compose.ollama.yml --env-file .env.ollama down $(if $(WITH_VOLUMES),-v,)
.PHONY: env-ollama
env-ollama:
@echo "Writing .env.ollama..."
@{ \
echo "MODE=multi"; \
echo "LIBSQL_URL="; \
echo "LIBSQL_AUTH_TOKEN="; \
echo "EMBEDDINGS_PROVIDER=ollama"; \
echo "OLLAMA_HOST=http://ollama:11434"; \
echo "OLLAMA_EMBEDDINGS_MODEL=nomic-embed-text"; \
echo "EMBEDDING_DIMS=768"; \
echo "EMBEDDINGS_ADAPT_MODE=pad_or_truncate"; \
echo "SKIP_CHOWN=0"; \
} > .env.ollama
prod: docker-build data env-prod
# Default prod: multi-project SSE, auth off, embeddings=ollama
docker compose --env-file .env.prod up --build -d
prod-down: env-prod
docker compose --env-file .env.prod down $(if $(WITH_VOLUMES),-v,)
prod-logs: env-prod
docker compose --env-file .env.prod logs -f --tail=200 memory-multi
prod-ps: env-prod
docker compose --env-file .env.prod ps
# VoyageAI profile env file
.PHONY: env-voyage voyage-up voyage-down
env-voyage:
@echo "Writing .env.voyage..."
@{ \
echo "EMBEDDINGS_PROVIDER=voyageai"; \
echo "VOYAGEAI_EMBEDDINGS_MODEL=voyage-3-lite"; \
echo "EMBEDDING_DIMS=1024"; \
echo "EMBEDDINGS_ADAPT_MODE=pad_or_truncate"; \
echo "TRANSPORT=sse"; \
echo "PORT=8080"; \
echo "SSE_ENDPOINT=/sse"; \
echo "METRICS_PROMETHEUS=true"; \
echo "METRICS_PORT=9090"; \
echo "HYBRID_SEARCH=true"; \
} > .env.voyage
voyage-up: docker-build data env-voyage
docker compose --env-file .env.voyage --profile voyageai up --build -d
voyage-down: env-voyage
docker compose --env-file .env.voyage --profile voyageai down $(if $(WITH_VOLUMES),-v,)
# Clean build artifacts
.PHONY: clean
clean:
rm -f $(BINARY_LOCATION)
# Install the binary globally
.PHONY: install
install:
@echo "Installing $(BINARY_NAME) globally..."
@chmod +x install.sh
./install.sh $(BINARY_LOCATION)
# Help
.PHONY: help
help:
@echo "Available targets:"
@echo " all - Build the project (default)"
@echo " build - Build the binary"
@echo " deps - Install dependencies"
@echo " test - Run tests"
@echo " run - Build and run the server"
@echo " clean - Clean build artifacts"
@echo " docker - Build the docker image (alias of docker-build)"
@echo " docker-build - Build the docker image"
@echo " docker-rebuild - Build the docker image with --no-cache"
@echo " docker-run - Run container (SSE, mounts ./data)"
@echo " docker-run-stdio - Run container (stdio)"
@echo " docker-run-multi - Run container (SSE, multi-project mode)"
@echo " docker-test - Run end-to-end docker test workflow"
@echo " compose-up - docker compose up (use PROFILES=single|multi|ollama|localai)"
@echo " compose-down - docker compose down (WITH_VOLUMES=1 to remove volumes)"
@echo " compose-logs - docker compose logs (SERVICE=memory)"
@echo " compose-ps - docker compose ps"
@echo " install - Install the binary globally"
@echo " help - Show this help message"