Self-host Junjo AI Studio with Docker Compose
Junjo AI Studio runs as two lightweight containerized services: the Studio application, which serves the web UI and the HTTP API, and the ingestion service. Deploy them alongside your application or on a separate host. Your application runs its own models, tools, and evaluators; Studio stores the shared experiment data and execution evidence.
Upgrading to Studio 0.85.0
Section titled “Upgrading to Studio 0.85.0”Use Junjo Python SDK 0.69.0 with Studio 0.85.0. This is a breaking telemetry contract upgrade: wipe Studio application data or select a new empty data directory, then complete first-user setup and create new credentials. Existing users, credentials, evaluations, and telemetry are not migrated.
Follow the canonical reset procedure.
It covers the shared SQLite, WAL, and Parquet data directory. docker compose down --volumes does not clear host-mounted application data.
Upgrading from Studio 0.85.0 or earlier
Section titled “Upgrading from Studio 0.85.0 or earlier”Releases after Studio 0.85.0 serve the web UI and the HTTP API from one
application container. Upgrading to one of them from Studio 0.85.0 or earlier
is a breaking change to the deployment as well as its data: the data directory
is reset, two containers replace three, the separate API hostname and port
26153 go away, six settings are removed, and everyone signs in again.
Follow Upgrading from Studio 0.85.0 or earlier in the reset procedure before starting the new release on an existing deployment.
Minimal Build Template (Recommended Starting Point)
Section titled “Minimal Build Template (Recommended Starting Point)”Use the Junjo AI Studio minimal distribution for local development or an existing Docker Compose environment. It contains versioned images, a configuration example, and a setup script. Bring your own reverse proxy and TLS when making the services remotely accessible.
- Clone or download the distribution.
- Run its
./scripts/junjo setupwizard. Choose the environment and memory profile; it generates the required internal token and reports your service URLs. The distribution’s README also documents manual.envsetup. - Start it with
docker compose up -dfrom the distribution directory. - Open the web UI at the address printed by setup. With default local host
ports, this is
http://localhost:26154.
For an existing Compose stack, use the distribution’s versioned Compose file as the configuration source. Preserve the application/ingestion shared storage, private RPC settings, and service-specific environment overrides. The Docker reference explains these boundaries.
The standalone repository is a generated release distribution. Its canonical source is apps/studio/deployments/minimal in the Junjo monorepo. Download a supported release and follow that release’s files; copying an older Compose snippet can lose required configuration.
Digital Ocean VM Deployment Example
Section titled “Digital Ocean VM Deployment Example”The VM/Caddy distribution walks through a fresh VM, DNS, Docker Compose, persistent storage, and automatic HTTPS. It includes the two Studio services and Caddy routing for:
| Destination | Example public address |
|---|---|
| Studio web UI and HTTP API for browser, CLI, and SDK | https://junjo.example.com |
| OTLP/gRPC ingestion | https://ingestion.junjo.example.com |
Studio runs well on a 1GB RAM VM with the supported small-host profile. Model inference and evaluation execution remain in your application environment. Size persistent storage for your actual trace volume and retained history; the VM size is a practical starting point, not a throughput benchmark.
See performance and deployment sizing for measured spans per second under explicit CPU and memory limits, the storage pipeline, and guidance on growing beyond the initial host profile.
Use the distribution’s setup and Caddy configuration together. The web UI and the HTTP API are one origin, so production needs one hostname for Studio and one for ingestion. The canonical source lives in apps/studio/deployments/vm-caddy.
Connect your application and coding agent
Section titled “Connect your application and coding agent”Studio has two independent connections. Configure both before asking your coding agent to perform a recursive self improvement cycle.
Send application telemetry
Section titled “Send application telemetry”Sign in to Studio and create a key in API Keys. Give the application that
key as JUNJO_AI_STUDIO_API_KEY; the OTLP exporter sends it in the
x-junjo-api-key header to ingestion.
Studio records which key sent each span. Give each application or environment its own key, and the Traces page can list one key’s traces. Deleting a key stops it from authorizing exports; the traces it already sent stay.
Select the destination for the application’s actual network:
| Application location | Default minimal-distribution ingestion destination |
|---|---|
| On the same local host | localhost:26155 |
| Container on the Studio Compose network | junjo-ai-studio-ingestion:26155 |
| Another host | Your configured public OTLP/gRPC endpoint with TLS |
Host-port overrides affect the localhost address. Containers on the shared
Compose network keep the service’s container port. Inside an application
container, localhost refers to that container.
Follow the OpenTelemetry setup guide for application-owned tracing and lifecycle configuration. For an OpenAI Agents application, follow the first-party integration guide.
Give the coding agent evaluation and evidence access
Section titled “Give the coding agent evaluation and evidence access”Open Access Tokens in Studio and create a developer access token with the scopes needed for the task:
evaluation:readto inspect datasets and run results.evaluation:writeto create cases and record experiments.evidence:readto investigate execution evidence.
Configure JUNJO_AI_STUDIO_CLI_TOKEN with that token and
JUNJO_AI_STUDIO_BACKEND_BASE_URL with the Studio origin, the same address
as the web UI. With the default local distribution, the origin is
http://localhost:26154. For a remote deployment, use its HTTPS origin, such
as https://junjo.example.com.
A person at a terminal can run junjo auth login instead of creating and
copying a token: Studio shows an approval page, and the CLI stores the token
it is given. The environment variable still takes precedence. See
Credentials stay separate.
The SDK accepts plain HTTP only for loopback. A VM address or Docker service hostname is not loopback; use HTTPS for that control connection, or a local forwarded loopback endpoint. This is independent of OTLP/gRPC transport setup.
The developer token does not authorize trace ingestion, and an ingestion API key does not authorize evaluation or evidence queries. Keep both outside application source and copied investigation reports.
Install the matching Junjo SDK in the application environment and make its packaged evaluation skill available to your coding agent. The evaluation guide owns the skill installation and application harness setup.
Verify both connections
Section titled “Verify both connections”- Execute a small instrumented application request. Let its telemetry provider finish exporting, then find the expected service and trace in Studio. Check an intermediate operation you will need to diagnose.
- With the developer token, ask the coding agent to list datasets through
junjo eval. An empty successful list verifies access on a new instance. - Follow the dataset and run guide to create the first dataset and run. Confirm that the coding agent can read that record and that its View spans link opens the corresponding execution in Studio.
An application can finish before its evidence is queryable. Treat a pending evidence response as delivery still to verify; a local exporter flush result alone is not proof of remote storage.
Preserve the experiment history
Section titled “Preserve the experiment history”The application and ingestion services use the same persistent host data directory. It holds canonical accounts, credentials, datasets, runs, and results as well as trace storage and the telemetry index. Preserve the whole data directory and the deployment configuration when moving or replacing containers.
The storage backing this directory is under your control. Choose and operate it according to the same data-protection requirements as your production application, including storage encryption, access restrictions, and backup handling.
Before an upgrade, read the chosen release’s compatibility and migration instructions and take a consistent backup. Some greenfield releases require an explicit data reset. Treat that as a release-specific destructive step, not a routine way to troubleshoot service startup.
For existing block storage, mount the existing filesystem and point
JUNJO_HOST_DB_DATA_PATH to it. Formatting a disk destroys its contents; it
is only part of deliberately provisioning an empty volume. See the
storage reference.
Continue with your first improvement
Section titled “Continue with your first improvement”Use recursive self improvement to connect diagnosis, targeted scenarios, local experiments, and human review. The Studio investigation guide shows how your coding agent’s findings link back to the records your team can inspect.