> ## Documentation Index
> Fetch the complete documentation index at: https://nextmind-85153aa2-dev.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Deployment

> Install and run Mycel in production

## Prerequisites

**Required:**

* Python 3.11+
* `uv` package manager — [installation guide](https://docs.astral.sh/uv/getting-started/installation/)
* Node.js 18+ (for the Web UI)
* Git

**Optional (by sandbox provider):**

* Docker daemon — for the Docker sandbox provider
* E2B API key — [e2b.dev](https://e2b.dev)
* Daytona API key — [daytona.io](https://daytona.io) or self-hosted instance
* AgentBay API key and region access

## Installation

<Steps>
  <Step title="Clone the repository">
    ```bash theme={null}
    git clone https://github.com/OpenDCAI/Mycel.git
    cd Mycel
    ```
  </Step>

  <Step title="Install Python dependencies">
    ```bash theme={null}
    # Core dependencies
    uv sync

    # With specific sandbox providers
    uv sync --extra e2b        # E2B
    uv sync --extra daytona    # Daytona
    uv sync --extra sandbox    # AgentBay
    uv sync --extra all        # Everything
    ```

    Docker works out of the box — just needs Docker installed.
  </Step>

  <Step title="Install frontend dependencies">
    ```bash theme={null}
    cd frontend/app && npm install && cd ../..
    ```
  </Step>
</Steps>

## Configuration

### Runtime configuration

Mycel service configuration comes from process environment variables and explicit server configuration. Agent configs, Skills, threads, Library resources, and user profiles are product state and are stored through the configured backend storage.

### Quick setup

Export variables in the shell or point `ENV_FILE` at an explicit env file:

```env theme={null}
ANTHROPIC_API_KEY=sk-ant-xxx
# Or use OpenAI-compatible format:
# OPENAI_API_KEY=your-key
# OPENAI_BASE_URL=https://api.openai.com/v1
# MODEL_NAME=gpt-4o
```

## Starting services

### Local communication backend

The previous `deploy/local-communication/compose.yml` path has been removed because it booted from a hand-written schema fork. Treat it as historical proof only, not as a valid self-hosting contract.

`deploy/cli-minimal/compose.yml` is the current CLI-minimal local communication
profile. It reuses the formal Mycel app schema/init path, runs PostgreSQL plus
PostgREST, exposes `/rest/v1/*` through a thin nginx gateway, and starts the
backend with `MYCEL_RUNTIME_PROFILE=communication`.

It is not the full Mycel platform. Full deployment is still represented by the
root `docker-compose.yml` plus operator-managed Supabase/Coolify configuration,
not by a `deploy/full` public self-hosting contract.

Start the local-only profile:

```bash theme={null}
python3 deploy/cli-minimal/generate-env.py > deploy/cli-minimal/.env
docker compose --env-file deploy/cli-minimal/.env -f deploy/cli-minimal/compose.yml up
```

To let another machine connect, publish an explicit URL and point `cel` at it:

```bash theme={null}
python3 deploy/cli-minimal/generate-env.py \
  --bind-host 0.0.0.0 \
  --public-url http://<host-or-lan-ip>:8042 \
  > deploy/cli-minimal/.env
docker compose --env-file deploy/cli-minimal/.env -f deploy/cli-minimal/compose.yml up
cel connect http://<host-or-lan-ip>:8042
```

### Full development stack

```bash theme={null}
# Terminal 1: backend
uv run python -m backend.web.main
# → http://localhost:8001

# Terminal 2: frontend
cd frontend/app && npm run dev
# → http://localhost:5173
```

Override the backend port:

```bash theme={null}
PORT=9000 uv run python -m backend.web.main
# or
LEON_BACKEND_PORT=9000 uv run python -m backend.web.main
```

## Sandbox provider setup

See [Sandbox](/en/sandbox) for full provider configuration. Quick reference:

### Docker

Set `LEON_SANDBOXES_DIR` to your sandbox provider config directory, then create `docker.json` in that directory:

```json theme={null}
{
  "provider": "docker",
  "on_exit": "pause",
  "docker": {
    "image": "python:3.12-slim",
    "mount_path": "/workspace"
  }
}
```

### E2B

```json theme={null}
{
  "provider": "e2b",
  "on_exit": "pause",
  "e2b": {
    "api_key": "${E2B_API_KEY}",
    "template": "base",
    "cwd": "/home/user",
    "timeout": 300
  }
}
```

### Daytona (SaaS)

```json theme={null}
{
  "provider": "daytona",
  "on_exit": "pause",
  "daytona": {
    "api_key": "${DAYTONA_API_KEY}",
    "api_url": "https://app.daytona.io/api",
    "cwd": "/home/daytona"
  }
}
```

### Daytona (self-hosted)

```json theme={null}
{
  "provider": "daytona",
  "on_exit": "pause",
  "daytona": {
    "api_key": "${DAYTONA_API_KEY}",
    "api_url": "http://localhost:3986/api",
    "target": "us",
    "cwd": "/workspace"
  }
}
```

Self-hosted requirements:

1. Runner container image must have bash at `/usr/bin/bash`
2. Workspace image must have bash at `/usr/bin/bash`
3. Runner must be on both the compose network **and** the default Docker bridge network

**Docker Compose network configuration:**

```yaml theme={null}
services:
  daytona-runner:
    image: your-runner-image-with-bash
    environment:
      - RUNNER_DOMAIN=runner  # NOT localhost
    networks:
      - default
      - bridge

networks:
  bridge:
    external: true
```

Add to `/etc/hosts` on the runner:

```
127.0.0.1 proxy.localhost
```

Daytona Proxy (port 4000) must be accessible from the runner for file operations.

### AgentBay

```json theme={null}
{
  "provider": "agentbay",
  "on_exit": "pause",
  "agentbay": {
    "api_key": "${AGENTBAY_API_KEY}",
    "region_id": "ap-southeast-1",
    "context_path": "/home/wuying"
  }
}
```

## Verification

Open the Web UI at `http://localhost:5173`, register an account, and confirm the agent responds.

## Production notes

### Database

Mycel runtime storage is explicit. Full production deployments should provide their own managed Supabase-compatible storage and secrets.

Back up the configured database with the tools for that database.

### Security

* Store API keys in the deployment secret store or an explicit env file, never in code or version control
* Use `${VAR}` substitution in JSON config files instead of hardcoding keys
* Restrict env file permissions when using one: `chmod 600 /path/to/mycel.env`
* The `block_dangerous_commands` setting (default: `true`) prevents `rm -rf` and similar shell commands

### Proxy environments

If your environment uses an HTTP proxy:

```bash theme={null}
# Prevent proxy from affecting the LLM client or Docker CLI
env -u ALL_PROXY -u all_proxy uv run python -m backend.web.main
```

## Troubleshooting

<AccordionGroup>
  <Accordion title="&#x22;Could not import module&#x22; on backend startup">
    * Confirm you're in the correct directory
    * Confirm the virtual environment is active: `source .venv/bin/activate`
    * Try using the full path: `.venv/bin/python -m backend.web.main`
  </Accordion>

  <Accordion title="&#x22;SOCKS proxy error&#x22; from LLM client">
    Your shell has `all_proxy=socks5://...` set. Unset before starting:

    ```bash theme={null}
    env -u ALL_PROXY -u all_proxy uv run python -m backend.web.main
    ```
  </Accordion>

  <Accordion title="Docker provider hangs">
    Proxy environment variables inherited by the Docker CLI. Mycel strips these automatically, but if issues persist, check the `docker_host` config field in `$LEON_SANDBOXES_DIR/docker.json`.
  </Accordion>

  <Accordion title="Daytona PTY bootstrap fails">
    Check each of these in order:

    1. Workspace image has bash at `/usr/bin/bash` — test with `docker run <image> /usr/bin/bash -c "echo ok"`
    2. Runner has bash at `/usr/bin/bash`
    3. Runner is on the Docker bridge network (see Docker Compose config above)
    4. Daytona Proxy (port 4000) is accessible from the runner — test with `curl http://proxy.localhost:4000`

    Common error messages:

    * `fork/exec /usr/bin/bash: no such file or directory` → workspace image missing bash
    * `Failed to create sandbox within 60s` → network isolation, check runner networks
    * File operations fail silently → Daytona Proxy unreachable
  </Accordion>
</AccordionGroup>
