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

# Run Self-Hosted Floe Without Docker

> Run the Floe signaling server and web client directly with Node.js, pnpm, and Go instead of Docker Compose for custom self-hosted deployments.

If you prefer to run the components without Docker, the complete manual setup steps are in [CONTRIBUTING.md](https://github.com/jannskiee/floe/blob/main/CONTRIBUTING.md#development-setup). The same environment variables documented in [Configuration](/docs/self-hosting/configuration) apply.

## Running each component

```bash theme={null}
# Signaling server (Node.js)
cd server
npm install
npm start

# Web client (Next.js)
cd client
pnpm install
pnpm build
pnpm start

# CLI (optional, for local testing against your server)
cd cli
go build ./cmd/floe
./floe send photo.jpg --server http://localhost:3001
```

<Note>
  The client requires a production build (`pnpm build` then `pnpm start`) to serve static files. Use `pnpm dev` only during development, as it enables Next.js hot-reloading and is not suitable for production.
</Note>

## Environment variables

Copy and configure the environment files before starting:

```bash theme={null}
cp server/.env.example server/.env
cp client/.env.example client/.env.local
```

Set at minimum:

* In `server/.env`: `CLIENT_URL=http://localhost:3000`
* In `client/.env.local`: `NEXT_PUBLIC_SOCKET_URL=http://localhost:3001`

For anything reachable from the internet, also set `NODE_ENV=production` in `server/.env`. Docker sets it for you; a direct Node run does not, and Express only suppresses stack traces in its built-in error responses when the value is exactly `production`.

## Updating an existing deployment

The Docker instructions in [Operations](/docs/self-hosting/operations) assume there is no repository to keep in sync. Running directly with Node means there is, so pull, reinstall, then restart:

```bash theme={null}
cd /path/to/floe
git pull
cd server
npm ci --omit=dev
```

Then restart the server with whatever supervises it (`pm2 restart <name>`, `systemctl restart <unit>`, or your own runner).

<Warning>
  Reinstall before you restart, and do not skip it. A dependency update that only moves a lockfile changes no source file, so a restart on its own re-executes the same `node_modules` and the update silently does not take effect. The process comes back healthy and the old version is still running.
</Warning>

Confirm the restart landed by checking that uptime reset:

```bash theme={null}
curl -s http://localhost:3001/health
```

To confirm a specific dependency actually moved, read the installed version rather than trusting the restart:

```bash theme={null}
npm --prefix server ls <package-name>
```
