fix(training): bundle reference content + use docker bridge gateway
All checks were successful
Build & Deploy / build-and-deploy (push) Successful in 9s

The Style Studio's curator-prompt + chat features read reference docs
from disk at runtime. Two issues from the initial production run:

1. Dockerfile + .dockerignore excluded .claude/, docs/, and most of
   skills/. Now COPY the four specific files the new endpoints need:
     - .claude/agents/hermes-curator.md
     - skills/decision/SKILL.md
     - docs/legal-decision-lessons.md
     - docs/corpus-analysis.md
   .dockerignore opens whitelists for just those files.

2. Coolify's custom_docker_run_options=--add-host=host.docker.internal:host-gateway
   is not honored on dockerimage build_pack apps (ExtraHosts stayed []).
   Switch chat_proxy.py default to http://10.0.1.1:8770 — the docker0
   bridge gateway, same pattern Paperclip uses for 3100. Bind the host
   pm2 service to 0.0.0.0:8770 so the container can reach it via the
   bridge IP. Oracle Cloud's security list keeps the port unreachable
   from the public internet.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-27 10:15:27 +00:00
parent bb0cd7c6a2
commit a3454bcb57
4 changed files with 37 additions and 6 deletions

View File

@@ -1,5 +1,7 @@
data/
.claude/
!.claude/agents/
!.claude/agents/hermes-curator.md
mcp-server/.venv/
**/__pycache__/
*.pyc
@@ -11,7 +13,11 @@ scripts/
skills/
!skills/docx/
!skills/docx/decision_template.docx
!skills/decision/
!skills/decision/SKILL.md
docs/
!docs/legal-decision-lessons.md
!docs/corpus-analysis.md
legacy/
node_modules/
.next/

View File

@@ -61,6 +61,18 @@ COPY mcp-server/src/ ./mcp-server/src/
# (Path(__file__).resolve().parents[4] / "skills/docx/decision_template.docx")
COPY skills/docx/decision_template.docx ./skills/docx/decision_template.docx
# Reference content the /training tab reads at runtime:
# - .claude/agents/hermes-curator.md → GET /api/training/curator/prompt
# - skills/decision/SKILL.md → system prompt for the chat
# - docs/legal-decision-lessons.md → system prompt for the chat
# - docs/corpus-analysis.md → system prompt for the chat
#
# These are read-only at runtime; chair edits go through git, not the container.
COPY .claude/agents/hermes-curator.md ./.claude/agents/hermes-curator.md
COPY skills/decision/SKILL.md ./skills/decision/SKILL.md
COPY docs/legal-decision-lessons.md ./docs/legal-decision-lessons.md
COPY docs/corpus-analysis.md ./docs/corpus-analysis.md
# Make mcp-server source available to web/app.py (it does sys.path.insert for legal_mcp)
ENV PYTHONPATH=/app/mcp-server/src

View File

@@ -31,7 +31,13 @@ module.exports = {
// Run the in-package server via the venv interpreter so all
// imports (claude_session, etc) resolve.
script: "/home/chaim/legal-ai/mcp-server/.venv/bin/python",
args: "-m legal_mcp.chat_service.server --port 8770",
// Bind to 0.0.0.0 so the legal-ai container can reach the service
// via the docker bridge gateway (10.0.1.1:8770). Oracle Cloud's
// security list keeps port 8770 closed to the public internet;
// ufw is inactive but iptables INPUT default ACCEPT is fine here
// because the cloud-level firewall is the actual perimeter (same
// pattern paperclip uses for its 0.0.0.0:3100 binding).
args: "-m legal_mcp.chat_service.server --port 8770 --host 0.0.0.0",
// claude CLI looks up credentials under HOME — make sure it
// sees Daphna's session, not an empty container HOME.
env: {

View File

@@ -33,13 +33,20 @@ from web import chat_system_prompt
logger = logging.getLogger(__name__)
# legal-chat-service lives on the host. In the container we reach it via
# host.docker.internal — which requires ``extra_hosts: host.docker.internal:host-gateway``
# in the Coolify service definition. Set ``CHAT_SERVICE_URL`` to override
# (handy for local dev outside Docker).
# legal-chat-service lives on the host (pm2-managed, bound to 0.0.0.0:8770).
# From inside the container we reach it via the docker bridge gateway
# 10.0.1.1 is the host on docker0 (the same address Paperclip uses for
# its 3100 bridge). Override with CHAT_SERVICE_URL if running outside
# Docker (local dev).
#
# Coolify's `custom_docker_run_options: --add-host=host.docker.internal:host-gateway`
# turned out NOT to apply to dockerimage-built apps as of Coolify 4.0.0,
# so the explicit IP is the reliable path. The cloud-level firewall
# (Oracle security list) keeps port 8770 unreachable from the public
# internet, matching the security posture of Paperclip's 3100.
CHAT_SERVICE_URL = os.environ.get(
"CHAT_SERVICE_URL",
"http://host.docker.internal:8770",
"http://10.0.1.1:8770",
)
CHAT_SERVICE_TIMEOUT_S = float(os.environ.get("CHAT_SERVICE_TIMEOUT_S", "3600"))