-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdocker-compose.yaml
More file actions
157 lines (153 loc) · 7.61 KB
/
Copy pathdocker-compose.yaml
File metadata and controls
157 lines (153 loc) · 7.61 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
# ── Interbox dev stack ───────────────────────────────────────────────────────
# Runs the whole product against THIS workspace checkout, with hot reload:
#
# interbox the all-in-one image (engine + API + dashboard). Mounts this repo
# at /workspace and runs it in local mode (file:///workspace), so
# edits to src/ hot-reload into the running pipeline.
# pg one stock Postgres 18 cluster, shared: Interbox and Aidbox each own
# a database in it (interbox, aidbox), created first-boot by compose/.
# aidbox the FHIR server the pipeline's sender targets.
#
# Everything here is a PULLED image — you do NOT need the engine source. The
# interbox image is published to Docker Hub; pg/aidbox are stock. Set the
# engine version with INTERBOX_VERSION in .env (the shipped .env.example pins a
# released version; `edge` = latest main build).
#
# Quick start:
# 1. cp .env.example .env and fill in the license (see that file).
# 2. docker compose up
# 3. open http://localhost:3001 → the dashboard.
# The image is LICENSED: the pipeline stays paused until you either set
# INTERBOX_LICENSE in .env or click through the dashboard's activation
# screen (portal OAuth). Until then the dashboard shows the activation gate.
# 4. send HL7v2 over MLLP to localhost:2575 and watch messages flow.
services:
pg:
# Single Postgres 18 cluster shared by Interbox and Aidbox — each owns its own
# database (interbox, aidbox). Both apps create their own database on first boot
# (Aidbox always; the engine since 1.4.0), so no init SQL is needed.
# Interbox needs only pg_trgm + btree_gist (bundled contrib); Aidbox wants
# pg_stat_statements, preloaded below.
image: postgres:18
# Postgres parallel query allocates DSM segments in /dev/shm; Docker's 64MB
# default overflows when the dashboard fans out parallel facet aggregates.
shm_size: "1g"
environment:
- POSTGRES_PASSWORD=postgres
command: >
postgres
-c max_wal_size=4GB
-c wal_compression=on
-c shared_preload_libraries=pg_stat_statements
ports:
- "5432:5432"
volumes:
- pg-data:/var/lib/postgresql/18/docker
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres -d postgres"]
interval: 2s
timeout: 3s
retries: 30
start_period: 5s
interbox:
# All-in-one engine + API + dashboard — published image (you don't need the
# engine source). INTERBOX_VERSION (.env) is the engine version knob; in the
# dev image the SDK rides along, so this one tag pins engine + SDK together.
# To update: bump INTERBOX_VERSION, then `docker compose pull interbox && up -d`.
image: ${INTERBOX_REGISTRY:-healthsamurai}/interbox:${INTERBOX_VERSION:-edge}
# The image runs as non-root (uid 1000). For local dev we mount this checkout at
# /workspace and keep node_modules in a named volume — both root-owned on the host
# side — so run the dev container as root to keep bun install / SDK-link writable.
# Production runs non-root via the Helm chart's securityContext; this override is
# dev-only convenience.
user: "0:0"
depends_on:
pg:
condition: service_healthy
ports:
- "3001:3001" # dashboard + API (same origin)
- "2575:2575" # MLLP ingest
environment:
DATABASE_URL: postgres://postgres:postgres@pg:5432/interbox
MLLP_HOST: 0.0.0.0
MLLP_PORT: "2575"
# Run THIS checkout in local mode — the bind mount below is the live tree.
INTERBOX_WORKSPACE_GIT_URL: file:///workspace
INTERBOX_WORKSPACE_POLL_MS: "2000" # snappy hot reload in dev
# Pipeline sender target.
AIDBOX_URL: http://aidbox:8080
# Client interbox authenticates as — id defaults to root; set a scoped one for least privilege.
AIDBOX_CLIENT_ID: ${AIDBOX_CLIENT_ID:-root}
AIDBOX_CLIENT_SECRET: ${AIDBOX_CLIENT_SECRET:-secret}
# License: env activation (or use the dashboard's activation screen instead).
INTERBOX_LICENSE: ${INTERBOX_LICENSE:-}
# Dashboard assistant (Claude Code over ACP) auth — pick ONE (all blank = the
# dashboard still works, the assistant just can't answer). The container has no
# ~/.claude of its own, so hand it credentials one of three ways:
# 1. CLAUDE_CODE_OAUTH_TOKEN — bills your Claude Code SUBSCRIPTION, not
# per-token API usage. On a host with Claude Code + a Pro/Max plan run
# `claude setup-token` and set it in .env. Works on every host OS.
# 2. ANTHROPIC_API_KEY — pay-per-token API billing instead of the subscription.
# 3. Reuse your host login — set CLAUDE_CONFIG_DIR in .env (see the volume below).
CLAUDE_CODE_OAUTH_TOKEN: ${CLAUDE_CODE_OAUTH_TOKEN:-}
ANTHROPIC_API_KEY: ${ANTHROPIC_API_KEY:-}
volumes:
- .:/workspace
# Keep the container's (linux) workspace deps in a volume so they don't
# clobber — or get clobbered by — the host's node_modules on the bind mount.
- workspace-node-modules:/workspace/node_modules
# Assistant auth option 3 (dev only, Linux/Windows hosts): reuse your host
# Claude Code login instead of minting a token. Point CLAUDE_CONFIG_DIR in .env
# at your host login dir (e.g. ${HOME}/.claude) and it's bind-mounted here — no
# docker-compose edit needed. Left unset it defaults to an empty managed volume,
# so nothing from the host is exposed and the assistant falls back to the token/
# key env above. Caveats: macOS keeps creds in the Keychain (not a dir), so this
# can't work there — run ./scripts/setup-claude-mac.sh to mint a token instead;
# and do NOT append `:ro` — Claude refreshes the token and must write it back.
- ${CLAUDE_CONFIG_DIR:-claude-login}:/root/.claude
aidbox:
image: healthsamurai/aidboxone:latest
depends_on:
pg:
condition: service_healthy
ports:
- "8080:8080"
# Strip a blank AIDBOX_LICENSE before Aidbox starts. Compose's `environment:`
# mapping always sets the var, even to "" when .env leaves it blank — and
# Aidbox's classic license check treats a present-but-empty value as a
# malformed JWT and refuses to boot instead of degrading into activation mode.
# Unsetting it when blank lets a fresh box boot unlicensed so the dashboard's
# activation flow can license it. $$ (not $) defers expansion to the container's
# shell so Compose doesn't bake the real JWT into the command args.
entrypoint:
- /bin/sh
- -c
- '[ -z "$$AIDBOX_LICENSE" ] && unset AIDBOX_LICENSE; exec /aidbox.sh'
environment:
AIDBOX_LICENSE: ${AIDBOX_LICENSE}
BOX_ADMIN_PASSWORD: admin
BOX_ROOT_CLIENT_SECRET: ${AIDBOX_CLIENT_SECRET:-secret}
BOX_BOOTSTRAP_FHIR_PACKAGES: hl7.fhir.r4.core#4.0.1
BOX_FHIR_SCHEMA_VALIDATION: "true"
BOX_FHIR_COMPLIANT_MODE: "true"
BOX_DB_DATABASE: aidbox
BOX_DB_HOST: pg
BOX_DB_PASSWORD: postgres
BOX_DB_PORT: "5432"
BOX_DB_USER: postgres
BOX_SECURITY_DEV_MODE: "true"
BOX_SETTINGS_MODE: read-write
BOX_WEB_BASE_URL: http://localhost:8080
BOX_WEB_PORT: 8080
healthcheck:
test: curl -f http://localhost:8080/health || exit 1
interval: 5s
timeout: 5s
retries: 90
start_period: 30s
volumes:
pg-data:
workspace-node-modules:
# Default target for the assistant's /root/.claude when CLAUDE_CONFIG_DIR is unset:
# an empty managed volume, so no host login is exposed unless you opt in via .env.
claude-login: