Mnemosyne MCP Server: Deployment Detail
Level 3 (Detail) — Build pipeline, Docker image, environment, and cluster deployment.
Concept
Mnemosyne is built as a multi-stage Docker image, published to Docker Hub via GitHub Actions, and deployed to the Kubernetes cluster via Flux GitOps with image automation.
Build Pipeline
Dockerfile (Dockerfile)
Multi-stage build:
| Stage | Base Image | Purpose |
|---|---|---|
builder | golang:1.23-bookworm | Compile static binary with CGO_ENABLED=0 |
| final | gcr.io/distroless/static-debian12 | Minimal runtime — no shell, no package manager |
Build command:
RUN CGO_ENABLED=0 GOOS=linux go build -o mnemosyne-mcp cmd/mnemosyne-mcp/main.go
Entrypoint: /mnemosyne-mcp
Default env vars set in Dockerfile:
DB_PORT=5432DB_USER=mnemosyne
GitHub Actions (publish.yml)
Trigger: push to main branch
Steps:
- Checkout code
- Login to Docker Hub (
roberto.tazzoli@gmail.com/DOCKER_PASSWORDsecret) - Build and push with two tags:
tazzo/mnemosyne-mcp:latesttazzo/mnemosyne-mcp:mcp-<run_number>-<sha>
Required Environment Variables
| Variable | Source | Description |
|---|---|---|
DB_HOST | tazlab-db-pguser-mnemosyne secret | PostgreSQL host |
DB_PORT | Dockerfile default (5432) | PostgreSQL port |
DB_USER | tazlab-db-pguser-mnemosyne secret | PostgreSQL user |
DB_PASS | tazlab-db-pguser-mnemosyne secret | PostgreSQL password |
DB_NAME | tazlab-db-pguser-mnemosyne secret | Database name |
GEMINI_API_KEY | mnemosyne-mcp-secrets ExternalSecret | Gemini embedding API key |
Optional Environment Variables
| Variable | Default | Description |
|---|---|---|
MCP_TRANSPORT | stdio | Transport mode: "" for stdio, "http" for HTTP (SSE streaming disabled to avoid client hangs) |
PORT | 8080 | HTTP port (only used when MCP_TRANSPORT=http) |
LOG_FORMAT | text | Log format: "text" for human-readable, "json" for structured |
Image Automation (Flux)
File: tazlab-k8s/infrastructure/automation/mnemosyne-mcp/automation.yaml
- ImageRepository:
tazzo/mnemosyne-mcp, polled every 1m - ImagePolicy:
numerical: order: ascon tag patternmcp-(<N>)-... - ImageUpdateAutomation: updates deployment in
apps/base/mnemosyne-mcponmasterbranch
Tag contract: mcp-<run_number>-<sha> — immutable, ascending by run number.
Cluster Deployment
Kubernetes Manifests (tazlab-k8s/apps/base/mnemosyne-mcp/)
| File | Purpose |
|---|---|
deployment.yaml | Main deployment in namespace tazlab-db |
service.yaml | LoadBalancer service on port 8004 → 8080, IP 192.168.1.240 |
rbac.yaml | ServiceAccount + Role for secret reading |
external-secret.yaml | Fetches GEMINI_API_KEY from tazlab-secrets ClusterSecretStore |
kustomization.yaml | Kustomize root, applies wait-for-db-patch |
Deployment spec:
- Image:
tazzo/mnemosyne-mcp:mcp-<N>-<sha>(set by image automation marker) - Replicas: 1
- ServiceAccount:
mnemosyne-mcp-sa - Resources: requests 50m CPU / 128Mi, limits 200m CPU / 256Mi
- Transport:
MCP_TRANSPORT=http(HTTP mode for cluster) - Reloader annotation: reloads on
tazlab-db-pguser-mnemosyneormnemosyne-mcp-secretschanges
Network
- Service type: LoadBalancer (MetalLB)
- Port mapping:
8004(external) →8080(container) - Shared IP pool:
tazlab-internal-dashboard - Allowed on IP:
192.168.1.240
Database Dependency
The deployment applies wait-for-db-patch.yaml — an init container that blocks until the PostgreSQL database is reachable. This prevents the server from starting before the database is ready.
Deployment Architecture
GitHub Push (main)
│
▼
GitHub Actions → Docker Hub (tazzo/mnemosyne-mcp:mcp-<N>-<sha>)
│
▼
Flux ImageAutomation (polls every 1m)
│
▼
deployment.yaml updated → Flux reconciliation
│
▼
Pod in namespace tazlab-db
│
▼
Service LoadBalancer :8004 → :8080/mcp
See Also
- Parent topic: Architecture
- Sibling details: Ingest Memory Detail, Retrieve Memories Detail, Python Tools Detail
- Sibling entity: tazlab-k8s