Files
ai-memory/docker/docker-compose.prod.yml.example
AkitaOnRailsandClaude Opus 4.7 658a0bfae4 M15: homelab deploy pattern + Kimi 2.6 via OpenRouter + config robustness
Adds the deploy plumbing modelled on ~/Projects/frank_mega's bin/deploy
pattern: a single shell script that builds the image, pushes to a
registry, ssh's the homelab, and `docker compose pull/down/up`s.
Lab-specific values (server, deploy dir, image tag, API keys) live in
.gitignored local files; the repo ships only `.example` templates.

Files added (templates, committed):
- bin/deploy — build/push/restart script; sources bin/deploy.env
- bin/deploy.env.example — SERVER / DEPLOY_DIR / IMAGE template
- docker/docker-compose.prod.yml.example — LAN-binding compose with
  `security_opt: label:disable` (required on SELinux-enforcing hosts:
  openSUSE MicroOS, Fedora, RHEL) and env_file for secrets
- docker/.env.production.example — API key + provider env template
- docs/deploy.md — first-time setup walkthrough + routine ops

Files added to .gitignore (live copies stay local):
- /bin/deploy.env
- /docker/docker-compose.prod.yml
- /docker/.env.production

Supporting changes surfaced while deploying:

- Default LLM model per provider now lands in factory.rs
  (anthropic=claude-sonnet-4-6, openai=gpt-4o-mini; openai-compat
  still requires explicit AI_MEMORY_LLM_MODEL). M11 referenced this
  in its commit message but the actual code change never made it
  into factory.rs; this fixes that gap.

- Stale `claude-sonnet-4-7` references swept to `claude-sonnet-4-6`
  across cli.rs / payload.rs / README.md / ARCHITECTURE.md.
  Anthropic's API returns 404 for `claude-sonnet-4-7`; the current
  Sonnet generation is 4.6.

- Dockerfile was the lone file the earlier port-rename sed missed
  (no extension matched my `--include`). EXPOSE + CMD now both use
  49374; the container was binding to 7777 silently.

- max_tokens bumped 1500→4000 (single-page consolidator) and
  2000→4000 (lint contradiction pass) to accommodate reasoning
  models. Kimi 2.6 burns ~2k tokens on hidden reasoning before any
  visible JSON, which truncated both paths at the old limits. Non-
  reasoning models stop early and don't pay extra for the higher cap.

- Removed `#[serde(deny_unknown_fields)]` from Config. Figment's
  Env::prefixed("AI_MEMORY_") provider pulls every AI_MEMORY_-
  prefixed var into the struct deserializer, including
  AI_MEMORY_LLM_*, AI_MEMORY_EMBEDDING_*, etc. — which are read
  directly by factory.rs. Strict rejection crashed every deploy
  that configured an LLM via env vars.

End state: container running on the homelab at
http://<homelab>:49374/mcp, healthy, configured for Kimi 2.6 (via
OpenRouter / openai-compat) + text-embedding-3-small hybrid retrieval.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-22 11:31:30 -03:00

48 lines
1.9 KiB
Plaintext

# Production docker-compose template for ai-memory on a homelab host.
#
# Copy to docker/docker-compose.prod.yml, adjust if you want, then
# scp it to your homelab as docker-compose.yml in the deploy dir.
# The .example variant is committed; the live copy is gitignored.
#
# Differences from docker/docker-compose.yml (the local-dev compose):
# - References an image from a registry instead of building inline.
# - Binds to 0.0.0.0 so the LAN can reach the MCP endpoint.
# - Reads secrets from .env.production rather than inlining them.
# - Volume mounts a host path (under /var/opt/docker/...) so backups
# can rsync the wiki + db without going through Docker volume APIs.
name: ai-memory
services:
ai-memory:
image: akitaonrails/ai-memory:latest
container_name: ai-memory
restart: unless-stopped
user: "1000:1000"
# openSUSE MicroOS / Fedora / RHEL etc. enforce SELinux on bind
# mounts by default; without this the container can't read its
# own /data dir. Safe on hosts that don't enforce SELinux (it's
# a no-op there).
security_opt:
- label:disable
ports:
# LAN-accessible. Behind your home firewall, this is fine. If
# you want loopback-only (server-local clients only), change to
# "127.0.0.1:49374:49374".
- "0.0.0.0:49374:49374"
volumes:
# Data lives on the host. Back up with: rsync, btrfs snapshots,
# restic — anything that can read this directory.
- /var/opt/docker/utils/ai-memory/data:/data
env_file:
- .env.production
environment:
# Tracing filter; promote modules to debug here without rebuilding.
- RUST_LOG=ai_memory=info,ai_memory_store=info,ai_memory_wiki=info,ai_memory_mcp=info,tracing_appender=warn
healthcheck:
test: ["CMD", "/usr/local/bin/ai-memory", "status"]
interval: 30s
timeout: 5s
retries: 3
start_period: 5s