The installer checks for Docker and offers to install it automatically on Ubuntu/Debian, Fedora, and macOS (via Homebrew). Use `--skip-docker-install` to skip this step.
> **MCP note:** Docker/Compose installs run the daemon inside the container. The MCP client snippets shown in Settings are stdio/local-path based and require a local/source install for now. Container-friendly MCP transport will be added in a follow-up.
## Interactive install walkthrough
Running the installer without flags launches an interactive wizard:
```
╔══════════════════════════════════════╗
║ O P E N D E S I G N ║
║ One-Click Installer ║
╚══════════════════════════════════════╝
[open-design] OS: Linux ubuntu 24.04 (x86_64)
[open-design] Docker: Docker version 26.1.3, build b72abbb
[open-design] Compose: Docker Compose version v2.27.1
| **Docker image** | `ghcr.io/nexu-io/od:latest` | Use `:latest` for the newest stable image, `:<version>` for a pinned release, or `@sha256:<digest>` for reproducibility |
| **Port** | `7456` | The port the daemon listens on. Must not be in use. |
| **Allowed origins** | _(empty)_ | CORS origins for reverse-proxy setups. See [`network-security.md`](network-security.md). Leave empty for localhost-only use. |
| **Memory limit** | `384m` | Container memory cap. Raise for large concurrent agent runs. |
After you confirm, the installer:
1. Writes a `deploy/.env` file (backs up any existing one).
2. Runs `docker compose pull` to fetch the image.
3. Runs `docker compose up -d --no-build` to start the container.
4. Polls `/api/health` for up to 60 seconds to confirm the daemon is ready.
5. On Linux: installs a `systemd --user` unit so the service starts on login.
## Non-interactive install
For CI, headless servers, and automated provisioning:
> **Data:** Before documenting, changing, deleting, or preserving persistent daemon storage, you MUST read root [`AGENTS.md`](../AGENTS.md) → **Daemon data directory contract**. This guide MUST NOT restate that contract or define storage paths.
| `OPEN_DESIGN_PORT` | `7456` | Host-side port (bound to `127.0.0.1`) |
| `OPEN_DESIGN_ALLOWED_ORIGINS` | _(empty)_ | CORS origins for reverse-proxy setups |
| `OPEN_DESIGN_MEM_LIMIT` | `384m` | Container memory cap |
| `NODE_OPTIONS` | `--max-old-space-size=192` | Node.js heap cap inside the container |
The container always binds `127.0.0.1:<port>:7456` — the daemon is never directly exposed to the network. To allow remote access, put an authenticated reverse proxy in front. See [`network-security.md`](network-security.md).
## Troubleshooting
| Problem | Likely cause | Fix |
|---------|-------------|-----|
| `Docker is not installed` | Docker not on PATH | Install Docker Desktop or Docker Engine |
| `Docker daemon is not running` | Docker Desktop not started | Open Docker Desktop or run `sudo systemctl start docker` |
| `Port 7456 is already in use` | Another service on that port | Re-run with `--port 8080` |
| Health check times out | Image pull slow or daemon slow to start | Wait and check `docker compose -f deploy/docker-compose.yml logs` |
| `Permission denied` on install.sh | Script not executable | Run `chmod +x deploy/scripts/install.sh` |
| systemd unit not created | `systemd` not found | Omit `--no-systemd` if systemd is available, or manage via Docker CLI |
| `.env` has wrong port after re-install | Old backup not restored | Edit `deploy/.env` directly or delete it and re-run |