> ## Documentation Index
> Fetch the complete documentation index at: https://docs.myrmagent.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Single-VM Docker Compose

> Deploy the Myrm control plane and per-user sandboxes on one Linux VM

## Overview

The supported private deployment runs on **one Linux VM** with Docker Compose. It starts the control plane, the WebUI, PostgreSQL, Redis and Caddy (automatic TLS). The control plane creates one sandbox container and one persistent volume per employee.

> [!NOTE]
>
> This page is for **company-hosted** deployments with OIDC SSO and central audit. For personal use, use the [Desktop App](/docs/getting-started/desktop-app) or [Local Deployment](/docs/getting-started/local-deployment).

## Architecture

```
Browser ──HTTPS──► Caddy ──► WebUI (3000)
                     │
                     └─────► Control Plane (8003)
                                   │
                    ┌──────────────┼──────────────┐
                    ▼              ▼              ▼
              PostgreSQL        Redis       Host Docker
                                                │
                                   ┌────────────┴────────────┐
                                   ▼                         ▼
                            per-user sandbox          persistent volume
```

* **Caddy** terminates TLS and routes `/api`, `/proxy`, `/ws`, `/llm-relay`, `/tool-relay`, `/tunnel-relay`, `/vnc` to the control plane; everything else goes to the WebUI.
* The control plane uses the host Docker socket to create sandboxes and proxies WebSocket/HTTP traffic to them.
* PostgreSQL stores control-plane data; each sandbox keeps its workspace and memory in a Docker volume.

## Prerequisites

* Ubuntu 22.04/24.04, 8 vCPU / 16 GB RAM
* Docker 24+ with Compose v2
* A DNS record for your domain; ports 80/443 reachable
* OIDC identity provider (Okta, Entra ID, Keycloak, etc.)
* Signed enterprise license JWT and the vendor public key
* Optional: `runsc` (gVisor) on the host for stronger sandbox isolation

## Quick start

```bash theme={null}
cd myrm-control-plane
cp deploy/compose/.env.example deploy/compose/.env

# Edit .env:
#   MYRM_DOMAIN, POSTGRES_PASSWORD, DOCKER_GID
#   MYRM_CP_ENTERPRISE_LICENSE_KEY / _PUBLIC_KEY
#   MYRM_CP_JWT_SECRET, MYRM_CP_MASTER_ENCRYPTION_KEY
#   MYRM_CP_OIDC_* and MYRM_CP_ADMIN_USER_IDS

docker compose -f deploy/compose/docker-compose.yml up -d
docker compose -f deploy/compose/docker-compose.yml ps
```

`DOCKER_GID` is the group id of the host Docker socket:

```bash theme={null}
stat -c '%g' /var/run/docker.sock
```

By default the sandbox runtime is `docker`. If `runsc` is installed, set `MYRM_CP_RUNTIME=docker_gvisor` in `.env`.

## Configuration

| Variable | Purpose |
| - | - |
| `MYRM_DOMAIN` | Public hostname; Caddy obtains a certificate automatically |
| `POSTGRES_PASSWORD` | PostgreSQL password, also used by the control-plane DSN |
| `DOCKER_GID` | Host Docker socket group id |
| `MYRM_CP_ENTERPRISE_LICENSE_KEY` | Signed license JWT |
| `MYRM_CP_ENTERPRISE_LICENSE_PUBLIC_KEY` | Vendor public key for offline verification |
| `MYRM_CP_JWT_SECRET` | API token signing secret |
| `MYRM_CP_MASTER_ENCRYPTION_KEY` | 64 hex chars; encrypts sandbox secrets |
| `MYRM_CP_OIDC_ISSUER_URL` / `_CLIENT_ID` / `_CLIENT_SECRET` | Enterprise SSO |
| `MYRM_CP_ADMIN_USER_IDS` | First administrator(s), comma-separated |
| `MYRM_CP_RUNTIME` | `docker` (default) or `docker_gvisor` |

The OIDC redirect URI is:

```
https://<MYRM_DOMAIN>/api/auth/oauth/oidc/callback
```

## First administrator and organization

1. Sign in once through OIDC.

2. Create the organization owned by that user:

   ```bash theme={null}
   docker compose -f deploy/compose/docker-compose.yml exec control-plane \
     python -m myrm_control_plane.bootstrap --org "Company" --admin-email admin@company.com
   ```

3. Put the printed `owner_user_id` into `MYRM_CP_ADMIN_USER_IDS` in `.env` and restart the control plane:

   ```bash theme={null}
   docker compose -f deploy/compose/docker-compose.yml up -d control-plane
   ```

A browser setup wizard is planned; the CLI replaces the previous manual SQL + JWT API flow.

## Using an existing reverse proxy

Caddy is optional: it runs under the `caddy` Compose profile (`COMPOSE_PROFILES=caddy` in `.env`). If you already run Nginx/ALB on the same host, remove that line and route:

| Path | Upstream |
| - | - |
| `/api`, `/proxy`, `/ws`, `/llm-relay`, `/tool-relay`, `/tunnel-relay` | `127.0.0.1:8003` |
| `/vnc` | `127.0.0.1:8002` |
| everything else | `127.0.0.1:3000` |

Terminate TLS at your proxy; keep the CP API port private.

## Operations

```bash theme={null}
# Logs
docker compose -f deploy/compose/docker-compose.yml logs -f control-plane

# Restart
docker compose -f deploy/compose/docker-compose.yml restart

# Upgrade (pin MYRM_VERSION in .env first)
docker compose -f deploy/compose/docker-compose.yml pull
docker compose -f deploy/compose/docker-compose.yml up -d
```

**Backup:** run the bundled script (PostgreSQL + `cp-data` + SHA256 + retention):

```bash theme={null}
BACKUP_DIR=/srv/myrm-backups RETENTION_DAYS=30 ./deploy/compose/backup.sh
```

Restore is destructive and requires an explicit `--yes` flag; test it on a fresh VM before switching traffic.

## Scope and limits

* **Single VM only.** No HA, clustering or multi-region failover.
* **Small teams**; benchmark with your workload before rollout and size up or split by team as needed.
* **OIDC only.** SAML and SCIM are not part of this deployment.
* **No BYOK/KMS or air-gapped mode.**
* **Linux only** (the sandbox runtime uses the host Docker daemon).
* Supported OS: Ubuntu 22.04/24.04 with Docker from the official repository.

## Security notes

* Mounting the Docker socket gives the control plane host-level container control. Restrict SSH and Docker access to trusted administrators.
* Sandboxes drop privileges and unnecessary capabilities, and enforce CPU/memory/PID limits. Docker security options add seccomp/AppArmor. Install `runsc` and use `docker_gvisor` when stronger isolation is required.
* Each employee has a separate sandbox and volume. Administrators can review audit events and usage; configure retention and access according to company policy.
* Keep `.env` out of version control and rotate the JWT/master keys only with a planned migration.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.