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

# Run the Project (Windows)

> Run a Demos Network node on Windows via WSL 2 + Docker Compose (recommended) or bare metal.

# Run the project (Windows)

The supported Windows path is **WSL 2 with Docker Compose**. Docker Desktop's WSL 2 backend integrates the `docker` and `docker compose` CLIs into your Ubuntu shell, and the node treats your WSL distro as a normal Linux host.

## Prerequisites

* Windows 10 (with the WSL2 update package) or Windows 11
* WSL 2 with an Ubuntu distro — see the [WSL 2 setup guide](/cookbook/project-setup/run-the-project-windows/wsl-2-setup)
* [Docker Desktop](https://www.docker.com/products/docker-desktop/) with the **WSL 2 based engine** enabled and **WSL Integration** turned on for your Ubuntu distro
* `git` (already present in Ubuntu)

Verify inside the Ubuntu (WSL 2) shell:

```bash theme={null}
docker --version
docker compose version
```

<Note>
  Use `docker compose` (with a space). The legacy hyphenated `docker-compose` is the deprecated Python script and is not supported.
</Note>

## Track 1: Docker Compose (recommended)

### Step 1 — Enable Docker Desktop WSL 2 integration

1. Open **Docker Desktop → Settings**.
2. Under **General**, enable **Use the WSL 2 based engine**.
3. Under **Resources → WSL Integration**, enable integration and toggle on your Ubuntu distro.
4. Click **Apply & Restart**.

### Step 2 — Three-step quickstart inside WSL 2

Open the Ubuntu shell and run:

```bash theme={null}
git clone https://github.com/kynesyslabs/node.git && cd node
cp .env.example .env
docker compose up
```

The first run pulls images and builds the node container, which can take a few minutes. Subsequent starts are near-instant.

When the stack is healthy (browse from Windows; ports forward through Docker Desktop):

* Node RPC: `http://localhost:53550` — try `curl http://localhost:53550/info` from the WSL shell
* Grafana: `http://localhost:3000` (default `admin` / `demos`)
* Prometheus: `http://localhost:9091`

<Tip>
  Clone the repo **inside the WSL 2 filesystem** (e.g. `~/node`), not under `/mnt/c/...`. WSL 2's Linux filesystem is dramatically faster for builds and Docker bind mounts than the Windows-mounted drive.
</Tip>

### Step 3 — Tour of `.env`

`.env.example` is the canonical template. The defaults work for local development. The variables you are most likely to touch:

| Variable                     | Default                  | Notes                                                                                                                                        |
| ---------------------------- | ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------- |
| `CONSENSUS_TIME`             | `10`                     | Block production interval (seconds).                                                                                                         |
| `RPC_FEE`                    | `1`                      | Per-tx fee component. Total flat fee = `RPC_FEE + NETWORK_FEE + BURN_FEE` (default `1+1+1=3`).                                               |
| `NETWORK_FEE`                | `1`                      | Per-tx fee component.                                                                                                                        |
| `BURN_FEE`                   | `1`                      | Per-tx fee component.                                                                                                                        |
| `RPC_PORT`                   | `53550`                  | Host-mapped RPC port. Change if 53550 is taken.                                                                                              |
| `EXPOSED_URL`                | `http://localhost:53550` | Public URL advertised to peers. **Loopback default is fine for local dev — set it to your reachable address before joining a real network.** |
| `OMNI_ENABLED` / `OMNI_PORT` | `true` / `53551`         | OmniProtocol binary RPC. Modes via `OMNI_MODE`: `HTTP_ONLY`, `OMNI_PREFERRED`, `OMNI_ONLY`.                                                  |
| `TLSNOTARY_ENABLED`          | `true`                   | Set to `false` to skip TLSNotary entirely.                                                                                                   |
| `TLSNOTARY_SIGNING_KEY`      | *(empty)*                | **Leave empty in default docker mode** — the sidecar manages its own key. Only set when `TLSNOTARY_MODE=ffi`.                                |
| `GRAFANA_ADMIN_PASSWORD`     | `demos`                  | Change this.                                                                                                                                 |
| `COMPOSE_PROFILES`           | `monitoring,tlsnotary`   | Which compose profiles to bring up.                                                                                                          |

Leave `PG_HOST=postgres` and `TLSNOTARY_HOST=tlsnotary` exactly as shipped — those are the in-network service names used by docker compose.

<Warning>
  Old docs referenced `RPC_FEE=5` and `SERVER_PORT`. Both are wrong. The current names are `RPC_FEE` (default `1`, plus `NETWORK_FEE=1` and `BURN_FEE=1`) and `RPC_PORT`.
</Warning>

### Common operations (run from the WSL shell)

```bash theme={null}
# Follow logs
docker compose logs -f node

# Update to the latest source
git pull
docker compose up -d --build

# Stop containers, KEEP volumes (your identity, chain data, etc.)
docker compose down

# Stop AND DELETE all volumes — nuclear, destroys identity + state
docker compose down -v
```

State persists in named Docker volumes prefixed `demos_` (e.g. `demos_node_state` holds `.demos_identity`). Docker Desktop manages the volumes — they survive `docker compose down` but not `docker compose down -v`.

### Going public

If you want peers to reach a node hosted on a Windows machine, you'll need to forward the relevant inbound TCP ports through both the Windows Defender Firewall and your router (and set `EXPOSED_URL` to your public address) **before** advertising the URL:

* `53550` — Node RPC
* `53551` — OmniProtocol
* `7047` — TLSNotary (only if enabled)

For production deployments, a Linux VPS is strongly preferred over a desktop Windows host.

### Troubleshooting

If you hit an issue, see the dedicated [Issue Troubleshooting](/cookbook/project-setup/run-the-project-windows/issue-troubleshooting) page.

***

## Track 2: Bare metal with `./run` (advanced)

Track 2 runs the node binary natively via Bun inside WSL 2 and uses Docker only for a Postgres sidecar managed by the `./run` script. Pick this path only for core development, kernel-level debugging, or TUI-driven operation. **Do not run Track 2 from Windows directly** — always use the Ubuntu shell inside WSL 2.

The full walkthrough — Bun via Mise (or the direct installer), Rust for `wstcp`, `./scripts/install-deps.sh`, `./run` flags — lives in the source of truth:

* [INSTALL.md — Track 2: Bare metal with `./run`](https://github.com/kynesyslabs/node/blob/main/INSTALL.md#track-2-bare-metal-with-run)

For the bare-metal path, override these in your `.env`:

* `PG_HOST=localhost`
* `PG_PORT=5332`
* `TLSNOTARY_HOST=localhost`
