# Jarca Ledger Docker Network MCP 배포 Runbook ## 목적 `jarca-ledger`를 `genichin-agent` 생명주기와 분리된 독립 Docker 서비스로 배포하고, stdio `docker exec`가 아니라 HTTP 기반 Streamable MCP endpoint를 직접 제공한다. 같은 이미지에서 별도 Streamlit 컨테이너(`jarca-ledger-dashboard`)를 실행해 운영 프론트엔드도 함께 서비스한다. ## 운영 고정값 | 항목 | 값 | |---|---| | 컨테이너 이름 | `jarca-ledger` | | Streamlit 컨테이너 이름 | `jarca-ledger-dashboard` | | 이미지 | `jarca-ledger:latest` | | Host data path | `/volume1/docker/jarca-ledger/data` | | Container data path | `/data` | | SQLite DB | `/data/ledger.sqlite3` | | MCP transport | `streamable-http` | | MCP listen | `0.0.0.0:8000` | | MCP path | `/mcp` | | Streamlit host port | `40059 -> 8501` | ## 배포 ```bash cd /home/ubuntu/workspaces/jarca-ledger-mcp docker compose up -d --build ``` ## 검증 ```bash docker ps --filter name=jarca-ledger docker inspect jarca-ledger --format='MOUNTS: see HostConfig.Binds and Mounts in docker inspect output' docker inspect jarca-ledger-dashboard --format='{{.State.Status}} {{if .State.Health}}{{.State.Health.Status}}{{else}}none{{end}}' docker inspect jarca-ledger | python3 -c "import json,sys; data=json.load(sys.stdin)[0]; [print(f'{m.get(\"Source\")} -> {m.get(\"Destination\")} ({m.get(\"Type\")})') for m in data.get('Mounts', [])]" docker logs --tail 80 jarca-ledger docker logs --tail 80 jarca-ledger-dashboard ``` Python MCP client smoke: ```bash python - <<'PY' import anyio from mcp import ClientSession from mcp.client.streamable_http import streamablehttp_client async def main(): async with streamablehttp_client('http://127.0.0.1:8000/mcp') as (read, write, _): async with ClientSession(read, write) as session: await session.initialize() tools = await session.list_tools() print('tool_count', len(tools.tools)) result = await session.call_tool('ledger_health_check', {}) print(result.content[0].text) anyio.run(main) PY ``` Streamlit HTTP smoke: ```bash python - <<'PY' import urllib.request for url in [ 'http://127.0.0.1:40059/_stcore/health', 'http://127.0.0.1:40059/?page=%EC%9A%94%EC%95%BD', ]: with urllib.request.urlopen(url, timeout=10) as response: print(url, response.status) PY ``` ## 운영 원칙 - `jarca-ledger` 컨테이너는 Docker daemon의 `restart: unless-stopped` 정책으로 독립 실행된다. - `jarca-ledger-dashboard` 컨테이너는 같은 image와 `/data` volume을 사용하며, Streamlit UI를 `http://:40059`로 제공한다. - `genichin-agent`는 이 서비스를 배포하거나 실행시키는 필수 구성요소가 아니다. - 재무관리 에이전트는 `http://:8000/mcp` 또는 같은 Docker network에서 `http://jarca-ledger:8000/mcp`로 접속한다. - 운영 DB와 import 원본/민감자료는 이미지에 포함하지 않고 `/volume1/docker/jarca-ledger/data`에만 둔다.