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
- 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
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.
Confirm the restart landed by checking that uptime reset:
Terminal
Terminal