Junjo AI Studio Docker configuration reference
Use this reference when configuring a Studio deployment. For the initial setup and the first application/coding-agent connection, start with Deployment.
Docker Images
Section titled “Docker Images”Use the two image versions selected together by the supported distribution. Keep the corresponding SDK and Studio telemetry contract compatible when using native graph, Agent, and Store views. See the selected release’s notes before changing versions.
Application Service
Section titled “Application Service”Image: mdrideout/junjo-ai-studio-app
The application service runs the Studio backend. It serves the web UI and the
HTTP API on one origin, container port 26154, for the browser, coding-agent
CLI, and SDK. It manages authentication, canonical evaluation records, and
evidence queries:
junjo.dbholds accounts, credentials, datasets, cases, runs, and attempts.metadata.dbis the telemetry file index, separate from canonical product data.- DataFusion queries received spans in Parquet and the shared hot snapshot.
- Private RPCs coordinate recent evidence reads with ingestion.
The web UI provides dataset/run comparisons, trace exploration, and native
Junjo execution and state views. Port 26151 is the source repository’s
development server and is not a port of this image.
Ingestion Service
Section titled “Ingestion Service”Image: mdrideout/junjo-ai-studio-ingestion
Ingestion receives authenticated OTLP/gRPC traces. It writes segmented Arrow IPC WAL data and flushes it to Parquet. It makes recent evidence available to the backend through shared files and a private RPC service.
Ingestion authorization uses application telemetry API keys. Successful
validation can be reused for the configured short cache interval; invalid keys
and backend failures are not cached. The distribution’s .env.example owns
the cache, buffering, backpressure, and flush settings.
Complete Docker Compose Configuration
Section titled “Complete Docker Compose Configuration”Minimal Build Configuration
Section titled “Minimal Build Configuration”The minimal distribution’s Compose file and .env.example are the configuration source for the released stack. The canonical monorepo directory owns changes to that distribution.
The Compose configuration supplies versioned images, prefixed service names, a project-scoped network, persistent mounts, small-host settings, and service-specific environment overrides. Preserve those relationships when incorporating it into your own Compose project. This reference intentionally links to the maintained file instead of carrying a separate Compose copy.
Production Deployment
Section titled “Production Deployment”For a VM with HTTPS, use the VM/Caddy distribution. It keeps the proxy routing and Studio configuration together. Its canonical source is apps/studio/deployments/vm-caddy.
Reverse Proxy Setup
Section titled “Reverse Proxy Setup”Expose two public origins: one hostname for Studio, routed to the application
service on port 26154, and one for the OTLP/gRPC endpoint, routed to
ingestion on port 26155. The Studio hostname carries both the web UI and the
HTTP API, so route the whole hostname to the application service. If you add
path rules, the API prefix is /api/ with the trailing slash: /api-keys is
a web UI page. The ingestion route requires a proxy that supports gRPC;
forwarding it as ordinary HTTP/1 traffic does not provide an OTLP/gRPC
connection. Keep the private service RPC ports inside the Studio network.
Use the distribution’s Caddyfile and image together, including its required DNS integration when using that setup. Studio’s browser session cookie is scoped to the one Studio hostname, so no second hostname has to share its domain.
Environment Variables Reference
Section titled “Environment Variables Reference”The distribution’s .env.example is the complete, release-specific list of
settings and defaults. The following groups explain the settings most often
needed during adoption. A production deployment requires three of them:
JUNJO_ENV=production, JUNJO_INTERNAL_GRPC_TOKEN, and
JUNJO_PROD_INGESTION_URL.
Common Configuration
Section titled “Common Configuration”| Setting | Purpose |
|---|---|
JUNJO_ENV |
Set development for the local endpoint configuration or production for a deployment behind public origins. Production marks the session cookie Secure and requires JUNJO_PROD_INGESTION_URL. |
Do not add generic PORT or GRPC_PORT values to the shared .env. The
application and ingestion services have different listener roles; the Compose
file pins each service’s listener ports.
Security (Backend and Ingestion)
Section titled “Security (Backend and Ingestion)”| Setting | Purpose |
|---|---|
JUNJO_INTERNAL_GRPC_TOKEN |
Required backend/ingestion workload credential with at least 32 characters. |
The setup wizard generates this token. Manual setup instructions in the
distribution describe generating it. Keep the internal RPC token out of
containers that do not need it; the VM/Caddy distribution explicitly clears it
for its reverse-proxy and example application services even though they load
the shared .env.
Application telemetry and developer access credentials are issued in Studio:
| Credential | Consumer | Authorized destination |
|---|---|---|
JUNJO_AI_STUDIO_API_KEY |
Application OTLP exporter | Ingestion, using x-junjo-api-key |
JUNJO_AI_STUDIO_CLI_TOKEN |
Coding-agent CLI or SDK | Backend evaluation/evidence API, using its granted scopes |
Neither credential substitutes for the other or for the internal RPC token. The connection guide covers creation and verification.
Database Storage
Section titled “Database Storage”JUNJO_HOST_DB_DATA_PATH selects the host data directory mounted by the
application and ingestion services. The minimal distribution defaults to
./.dbdata. For a persistent mounted volume, point it to the volume’s
existing mount directory. Keep the matching container paths from the
distribution.
Logging
Section titled “Logging”JUNJO_LOG_LEVEL selects the log verbosity. JUNJO_LOG_FORMAT selects the
backend’s json or text output. Follow the distribution’s current example
for defaults. Avoid copying secrets or customer payloads into support reports.
Production URLs (Required for Production)
Section titled “Production URLs (Required for Production)”| Setting | Destination |
|---|---|
JUNJO_PROD_INGESTION_URL |
Public OTLP/gRPC ingestion origin, as an http:// or https:// URL. The web UI shows it in its SDK setup instructions. |
Studio’s own address needs no setting. The web UI and the HTTP API are one origin, and the application service does not need to know its public URL.
The coding agent’s JUNJO_AI_STUDIO_BACKEND_BASE_URL points to that Studio
origin, not the ingestion address. SDK/CLI control access requires HTTPS
outside loopback, including when using a VM or container hostname.
Volume Mounts
Section titled “Volume Mounts”The application and ingestion services must see the same underlying files at their expected container paths. The backend reads Parquet and the hot snapshot directly; a working network connection between the services does not replace the shared storage requirement.
Local Directory Structure
Section titled “Local Directory Structure”Data under the default .dbdata directory |
Role |
|---|---|
sqlite/junjo.db |
Canonical accounts, credentials, datasets, cases, runs, and attempts |
sqlite/metadata.db |
Telemetry file index |
spans/wal/ |
Recent trace storage in Arrow IPC segments |
spans/parquet/ |
Flushed trace storage |
spans/hot_snapshot.parquet |
Shared snapshot used for recent-evidence queries |
Preserve the complete data directory across container replacement. Back up the application database and telemetry consistently; retaining datasets alone does not retain the execution evidence their links identify. Stop writers before making a filesystem-copy backup and follow release-specific upgrade instructions.
Block Storage (Production)
Section titled “Block Storage (Production)”Mount persistent block storage on the Studio host and configure
JUNJO_HOST_DB_DATA_PATH. Confirm the mount is present and writable before
starting the services. Use the VM distribution’s instructions for a fresh
volume; an existing filesystem should be mounted, not formatted. Formatting
an existing device destroys its data.
Port Mappings
Section titled “Port Mappings”Internal Communication
Section titled “Internal Communication”The released minimal distribution uses these Compose service names and container ports:
| Destination | Service and container port | Purpose |
|---|---|---|
| Web UI and HTTP API | junjo-ai-studio-app:26154 |
Browser application; browser, SDK, and CLI HTTP API |
| Ingestion | junjo-ai-studio-ingestion:26155 |
Application OTLP/gRPC traces |
| Ingestion private RPC | junjo-ai-studio-ingestion:50052 |
Backend hot-snapshot coordination |
| Backend private RPC | junjo-ai-studio-app:50053 |
Ingestion API-key validation |
Application exporters and evaluation clients do not use the two private RPC ports. Preserve their private routing when adapting the deployment.
External Access
Section titled “External Access”For local host processes, the default Studio and ingestion addresses use
localhost and host ports 26154 and 26155 respectively.
JUNJO_BACKEND_HOST_PORT and JUNJO_INGESTION_HOST_PORT can change those
host ports without changing the container ports.
For remote access, use the HTTPS origins configured by your reverse proxy. The Studio origin must be reachable from the coding agent’s execution environment as well as from the human’s browser. Both use the same address.
Resource Requirements
Section titled “Resource Requirements”The supported small-host profile is designed for a 1GB RAM VM with a shared vCPU. The application, model clients, and evaluation execution can run on other machines. Deployment settings include backend memory and query limits, with swap guidance in the distribution.
Actual capacity depends on span volume, payload size, retained history, and concurrent queries. Measure those workloads when allocating CPU, memory, and disk; this host profile is not a claim of a fixed throughput or retention limit.
Network Configuration
Section titled “Network Configuration”Docker Network
Section titled “Docker Network”Compose creates a project-scoped junjo-network; the actual Docker network
name includes the Compose project name. There is no globally fixed
junjo_network name to pre-create.
An application in the same Compose project can join that network and use the
ingestion service name. For a separate Compose project, either deliberately
attach to the actual existing Studio network or use the configured externally
reachable endpoint. Do not assume an unconnected container can resolve Studio
service names, and do not use its own localhost as the Studio destination.
Scaling Considerations
Section titled “Scaling Considerations”See performance and deployment sizing for measured throughput by resource allocation, workload sizing, and the requirements for separating services across machines.
Vertical Scaling
Section titled “Vertical Scaling”Keep backend and ingestion together on the supported shared-storage host. Increase CPU, memory, and disk performance as measured workloads require; review the distribution’s memory/query profile alongside host capacity.
Independent application experiments can record their runs into the same Studio instance. This does not turn Studio into a distributed application executor. Splitting the storage-reading backend and ingestion across unrelated VMs, or duplicating them behind a load balancer, is not the supported Compose topology.
Troubleshooting
Section titled “Troubleshooting”Service Won’t Start
Section titled “Service Won’t Start”Run docker compose ps and inspect logs from the distribution directory.
The canonical service names are junjo-ai-studio-app and
junjo-ai-studio-ingestion; for example,
docker compose logs junjo-ai-studio-ingestion reads ingestion logs.
Check required settings, host port conflicts, the persistent mount, and write permissions. Let Compose create its project network. Preserve persistent data while investigating; deleting volumes or formatting disks is not a general startup fix.
API Errors
Section titled “API Errors”Verify the actual Studio origin and the reverse-proxy route to the application service. Check the application service’s logs. If the browser works but the CLI fails, check the developer access token’s scopes and expiration, and confirm HTTPS for a non-loopback origin. An ingestion API key cannot authenticate the CLI.