Docker Compose
This guide starts every Rikoo service on a single machine with Docker Compose. Use it to evaluate Rikoo, run a demo or serve a small team. Its defaults are meant for a workstation: default database passwords, and PostgreSQL, Redis and MinIO published on the host. For production, deploy on Kubernetes, or harden the stack as described in Before exposing it.
Requirements
- Access to the Rikoo source repository,
Rikoo-app/rikoo(see Overview). - Docker Engine with Docker Compose 2.20 or later.
- Node.js 20 or later and pnpm on the host: they generate the keys and build the Studio.
- Free host ports: 3000 (api and Studio), 5432 (PostgreSQL), 6379 (Redis), 9000 and 9001 (MinIO).
Install
1. Get the source
Check out a release rather than main, which carries unreleased changes.
git clone https://github.com/Rikoo-app/rikoo.git
cd rikoo
git checkout v0.2.0
2. Build the Studio and the widget
The api container serves the Studio and the widget script from the web/dist and
widget/lib/dist folders of this checkout, mounted into the container. Build them before the first
start, widget first:
make install
pnpm --filter @rikoo/widget build
pnpm --filter @rikoo/web build:localized
Without this step the stack starts and reports healthy, but http://localhost:3000 serves no
Studio and /widget/widget.js is missing.
3. Configure
The stack reads deploy/compose/.env. Start from the example file, then fill in the values it
leaves empty:
cp deploy/compose/.env.example deploy/compose/.env
make secrets-keys # prints RIKOO_SECRETS_PUBLIC_KEY and RIKOO_SECRETS_PRIVATE_KEY
make sandbox-secret # prints MCP_SANDBOX_TOKEN_SECRET
node -e "console.log('WIDGET_SIGNING_KEY=' + require('node:crypto').randomBytes(32).toString('base64'))"
chmod 600 deploy/compose/.env
Copy each printed line into deploy/compose/.env, replacing the empty line of the same name.
| Variable | Required | What it is |
|---|---|---|
RIKOO_SECRETS_PUBLIC_KEY, RIKOO_SECRETS_PRIVATE_KEY | Yes | The vault's sealing key pair. The api seals secrets with the public key; only the worker holds the private key. Losing the private key makes every stored secret unreadable. |
MCP_SANDBOX_TOKEN_SECRET | Yes | Authenticates the worker to the tool sandbox. Compose refuses to start without it. |
WIDGET_SIGNING_KEY | Yes, in practice | Signs widget sessions, and derives the keys that protect two-factor secrets and the stored license. Compose falls back to a public development value when it is empty. Set it once, before the first account: changing it later invalidates what was derived from it. |
PUBLIC_URL | No, defaults to http://localhost:3000 | The address users type. It is the only origin the api accepts for Studio requests, and the base of links in e-mails. |
TRUST_PROXY_HOPS | Yes, set to 0 in the example | 0 when the api is reached directly, 1 behind one reverse proxy. |
When a required variable is empty, Compose refuses to start and names it:
required variable MCP_SANDBOX_TOKEN_SECRET is missing a value.
To replace the default database and storage passwords, set POSTGRES_PASSWORD and
MINIO_ROOT_PASSWORD now: PostgreSQL keeps the password its volume was created with.
4. Start
make up
This runs docker compose -f deploy/compose/docker-compose.yml up --build -d. The first run builds
the api, worker and sandbox images from source and takes several minutes. The api applies database
migrations each time it starts, so there is no separate migration step.
5. Check
curl http://localhost:3000/api/v1/health
curl -i http://localhost:3000/readyz # 200 once PostgreSQL and Redis answer, 503 otherwise
6. Create the first account
Open PUBLIC_URL (by default http://localhost:3000) and sign up. While no organization exists,
the first account may register and create the first organization, of which it becomes Owner.
Passwords need at least 10 characters. Everyone after that joins by invitation.
What runs
| Service | Role | Required |
|---|---|---|
api | REST API, Studio, widget, authentication | Yes |
worker | Runs, model calls, retrieval, tools, outbound calls | Yes |
postgres | Data and vectors (pgvector/pgvector:pg16) | Yes |
redis | Queues, sessions, pub/sub (redis:7-alpine) | Yes |
minio, minio-setup | S3-compatible storage; minio-setup creates the rikoo bucket and exits | Yes |
sidecar-parsing | PDF and Office extraction | No |
mcp-sandbox, playwright-mcp, mcp-egress | Embedded tools: the isolated workspace, the browser, and the proxy the browser leaves through | No |
The optional services start by default. When one is missing, the feature it carries degrades and runs continue. Infrastructure describes each service in detail.
The sandbox runs with a dedicated seccomp profile. On Linux hosts you can add gVisor as a second
isolation layer: the runtime: runsc line of the mcp-sandbox service is ready to uncomment once
gVisor is installed.
Enterprise edition
The Enterprise edition is a different build of the api and worker images. Set it in
deploy/compose/.env, then rebuild:
RIKOO_EDITION=ee
make up
Keep the line in .env: without it, the next make up rebuilds Community images. Then activate
your license, see Enterprise license.
Before exposing it
The example configuration is for a workstation. Before anyone else reaches the machine:
- Put the api behind a reverse proxy that terminates TLS, set
PUBLIC_URLto its public address andTRUST_PROXY_HOPS=1. - Stop publishing PostgreSQL and Redis on the host: remove their
portsentries indeploy/compose/docker-compose.yml. - Expose MinIO only through your proxy, and set
S3_BROWSER_ENDPOINTto that address: browsers upload attachments to it directly, so the defaulthttp://localhost:9000fails for anyone else. - Make sure
POSTGRES_PASSWORDandMINIO_ROOT_PASSWORDare not the defaults (see Configure). - Back up the
pgdataandminiodatavolumes and the sealing private key.
Operate
| Task | Command |
|---|---|
| Follow the logs | make logs |
Apply a change to .env | make up (recreates the affected containers; a plain docker compose restart does not read .env again) |
| Stop, keeping the data | make down |
| Stop and delete all data | make clean (removes the pgdata, redisdata, miniodata and sandboxdata volumes) |
Upgrade
Back up the database first. Then check out the new release, rebuild the Studio and restart:
git fetch --tags
git checkout v0.2.0 # the release you upgrade to
pnpm --filter @rikoo/widget build
pnpm --filter @rikoo/web build:localized
make up
The api applies pending migrations when it starts. Read the release notes before upgrading: a release can make a variable required.
Troubleshooting
| Symptom | Cause and fix |
|---|---|
required variable ... is missing a value | A required variable is empty in deploy/compose/.env. See Configure. |
Health is fine but http://localhost:3000 shows no Studio | The Studio was not built on the host. Run step 2, then make up. |
port is already allocated | Another process uses 3000, 5432, 6379, 9000 or 9001. Stop it, or change the published port in the compose file. |
| The worker cannot reach a model server on your network | The egress guard refuses private addresses. Allow the range with RIKOO_EGRESS_ALLOW_CIDRS in deploy/compose/.env, for example 10.0.0.0/8; Compose passes it to every service that applies the guard. |