Skip to main content
If you prefer to run the components without Docker, the complete manual setup steps are in CONTRIBUTING.md. The same environment variables documented in Configuration apply.

Running each component

The signaling server and the web client are two long-lived processes, so each needs its own terminal (or a supervisor, as below). Run each block from the repository root.
Terminal
Terminal
Terminal
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.

Environment variables

Copy and configure the environment files before starting:
Terminal
Set at minimum:
  • In server/.env: CLIENT_URL=http://localhost:3000
  • In client/.env.local: NEXT_PUBLIC_SOCKET_URL=http://localhost:3001
NEXT_PUBLIC_SOCKET_URL is inlined when the client is built, so on this path changing it later needs another pnpm build. To change the address without rebuilding, leave it unset and set the unprefixed SOCKET_URL in the environment of the process that runs pnpm start instead; the browser then reads it per request from /api/config. See How the Client Finds the Signaling Server. Leave both empty when the client and the signaling server share one origin behind a reverse proxy. Also set NODE_ENV=production in server/.env. Docker sets it for you; a direct Node run does not. Floe registers its own final error handler that returns a generic JSON error at every setting, so this is not a stack-trace leak. Set it anyway: production is what both the published image and server/.env.example use, so a direct Node run matches what is tested.

Updating an existing deployment

The Docker instructions in Operations assume there is no repository to keep in sync. Running directly with Node means there is, so pull, reinstall, then restart:
Terminal
Then restart both processes with whatever supervises them (pm2 restart <name>, systemctl restart <unit>, or your own runner). pnpm start serves whatever pnpm build last produced, so skipping the client rebuild leaves the old client running with nothing to indicate it is stale.
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.
Confirm the restart landed by checking that uptime reset:
Terminal
To confirm a specific dependency actually moved, read the installed version rather than trusting the restart:
Terminal