Files
rohitg00--agentmemory/docker-compose.yml
Rohit Ghumare 5ea01c162c fix(deploy): distroless volume perms + viewer proxy + budget loop (#299, #301) (#304)
@flamerged reported three issues on a real production deployment:

1. (#301) v0.9.7's working-directory fix moved iii-config paths from
   ./data/... to /data/... so the named volume mount is actually
   reached. But iiidev/iii is distroless and runs as UID 65532, while
   `docker volume create` initializes the named volume mountpoint as
   root:root mode 755. Engine writes fail Permission denied (os error
   13), the API silently buffers in RAM, every API call returns
   success, and state evaporates on every container restart — exactly
   what 0.9.7 set out to fix.

   Fix: ship a one-shot iii-init service in docker-compose.yml
   (busybox:1.36, ~4MB, exits in <100ms) that chowns /data to
   65532:65532. iii-engine now has user: "65532:65532" and
   depends_on.iii-init.condition: service_completed_successfully.
   Verified live: pre-fix volume stayed 4.0K after API writes; post-
   fix volume grows to 44K with state_store.db/mem%3A*.bin files
   written through the named volume.

2. (#299) src/viewer/index.html ports detection hardcoded ':3113' as
   the fallback when window.location.port is empty (page served on
   80/443 behind a reverse proxy). Every browser-side /agentmemory/*
   fetch went to <host>:3113, which is typically loopback-only on the
   self-hosted shape — the dashboard rendered cleanly but every
   panel showed the empty "first run" state.

   Fix: when neither ?port=N nor window.location.port is set, use
   window.location.origin as the REST base and window.location.host
   for the WebSocket URL — same-origin path works for both REST and
   live updates. Explicit ?port=N / non-default window.location.port
   paths unchanged.

3. (bundled) mem::context budget loop used `break` on first oversized
   block. With #288's new pinned-slot injection sorting first via
   recency: Date.now(), one fat pinned slot could starve every
   smaller block downstream that would have fit. Switched to
   `continue` so smaller blocks still slip into remaining budget.
   Total tokens still bounded by tokenBudget; only composition under
   contention changes.

Bumping 0.9.9 -> 0.9.10 across the 8 standard files (package.json,
packages/mcp/package.json, plugin/.claude-plugin/plugin.json,
src/version.ts, src/types.ts ExportData literal,
src/functions/export-import.ts supportedVersions, the export
round-trip test expectation, and CHANGELOG.md).

868 / 868 tests pass. Build clean. Volume + viewer fixes verified
end-to-end live.
2026-05-12 16:19:13 +01:00

48 lines
1.6 KiB
YAML

services:
# One-shot init container: docker creates named volumes root:root mode
# 755, but the iii-engine image is distroless and runs as UID 65532
# with no `chown` of its own. Without this, /data is unwritable, the
# engine silently buffers in RAM, and state evaporates on every
# restart — the exact symptom v0.9.7's working-directory fix set out
# to solve. Runs once at compose-up and exits.
iii-init:
image: busybox:1.36
user: "0:0"
volumes:
- iii-data:/data
entrypoint: ["sh", "-c", "chown -R 65532:65532 /data && chmod 755 /data"]
restart: "no"
iii-engine:
# Pinned to v0.11.2 — the last engine that runs agentmemory's current
# worker model cleanly. v0.11.6 introduces a new sandbox-everything-
# via-`iii worker add` model that agentmemory hasn't been refactored
# for yet; the architectural mismatch surfaces as EPIPE reconnect
# loops and empty search after save. Bump only after agentmemory is
# refactored to register as a sandboxed worker.
#
# Override per-shell or via .env file:
# AGENTMEMORY_III_VERSION=0.11.7 docker compose up
image: iiidev/iii:${AGENTMEMORY_III_VERSION:-0.11.2}
user: "65532:65532"
depends_on:
iii-init:
condition: service_completed_successfully
ports:
- "127.0.0.1:49134:49134"
- "127.0.0.1:3111:3111"
- "127.0.0.1:3112:3112"
- "127.0.0.1:9464:9464"
volumes:
- iii-data:/data
- ./iii-config.docker.yaml:/app/config.yaml:ro
restart: unless-stopped
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"
volumes:
iii-data: