fix(training): bundle reference content + use docker bridge gateway
All checks were successful
Build & Deploy / build-and-deploy (push) Successful in 9s
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:
@@ -1,5 +1,7 @@
|
|||||||
data/
|
data/
|
||||||
.claude/
|
.claude/
|
||||||
|
!.claude/agents/
|
||||||
|
!.claude/agents/hermes-curator.md
|
||||||
mcp-server/.venv/
|
mcp-server/.venv/
|
||||||
**/__pycache__/
|
**/__pycache__/
|
||||||
*.pyc
|
*.pyc
|
||||||
@@ -11,7 +13,11 @@ scripts/
|
|||||||
skills/
|
skills/
|
||||||
!skills/docx/
|
!skills/docx/
|
||||||
!skills/docx/decision_template.docx
|
!skills/docx/decision_template.docx
|
||||||
|
!skills/decision/
|
||||||
|
!skills/decision/SKILL.md
|
||||||
docs/
|
docs/
|
||||||
|
!docs/legal-decision-lessons.md
|
||||||
|
!docs/corpus-analysis.md
|
||||||
legacy/
|
legacy/
|
||||||
node_modules/
|
node_modules/
|
||||||
.next/
|
.next/
|
||||||
|
|||||||
12
Dockerfile
12
Dockerfile
@@ -61,6 +61,18 @@ COPY mcp-server/src/ ./mcp-server/src/
|
|||||||
# (Path(__file__).resolve().parents[4] / "skills/docx/decision_template.docx")
|
# (Path(__file__).resolve().parents[4] / "skills/docx/decision_template.docx")
|
||||||
COPY skills/docx/decision_template.docx ./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)
|
# Make mcp-server source available to web/app.py (it does sys.path.insert for legal_mcp)
|
||||||
ENV PYTHONPATH=/app/mcp-server/src
|
ENV PYTHONPATH=/app/mcp-server/src
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,13 @@ module.exports = {
|
|||||||
// Run the in-package server via the venv interpreter so all
|
// Run the in-package server via the venv interpreter so all
|
||||||
// imports (claude_session, etc) resolve.
|
// imports (claude_session, etc) resolve.
|
||||||
script: "/home/chaim/legal-ai/mcp-server/.venv/bin/python",
|
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
|
// claude CLI looks up credentials under HOME — make sure it
|
||||||
// sees Daphna's session, not an empty container HOME.
|
// sees Daphna's session, not an empty container HOME.
|
||||||
env: {
|
env: {
|
||||||
|
|||||||
@@ -33,13 +33,20 @@ from web import chat_system_prompt
|
|||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
# legal-chat-service lives on the host. In the container we reach it via
|
# legal-chat-service lives on the host (pm2-managed, bound to 0.0.0.0:8770).
|
||||||
# host.docker.internal — which requires ``extra_hosts: host.docker.internal:host-gateway``
|
# From inside the container we reach it via the docker bridge gateway —
|
||||||
# in the Coolify service definition. Set ``CHAT_SERVICE_URL`` to override
|
# 10.0.1.1 is the host on docker0 (the same address Paperclip uses for
|
||||||
# (handy for local dev outside Docker).
|
# 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 = os.environ.get(
|
||||||
"CHAT_SERVICE_URL",
|
"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"))
|
CHAT_SERVICE_TIMEOUT_S = float(os.environ.get("CHAT_SERVICE_TIMEOUT_S", "3600"))
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user