See It Work
icey-server is a single C++ binary for browser-facing realtime media over WebRTC. No Node.js, no third-party services, no multi-container ceremony. One binary, two ports, live video.
60-Second Path
Run the server
docker run --rm --network host 0state/icey-server:latestOpen a browser
Go to http://localhost:4500.
Watch the stream
Click Watch on the icey peer. You should see live video in under a second.
That is the entire setup. The container includes the server binary, a bundled web UI, and a test source. Everything else — signalling, TURN relay, session control — is built in.
Browser Flow
What happened in the browser when you clicked Watch:
- The web UI loaded over HTTP from the server.
- A WebSocket connected to
/wsfor Symple signalling. - The browser discovered the
iceyserver peer via presence. - A call was placed. SDP offer/answer and ICE candidates exchanged over the signalling channel.
- The media path opened — in stream mode, the server started sending H.264 + Opus to the browser.
If the browser cannot see the server peer, you have a signalling problem (step 2-3). If it sees the peer but video never appears, you have a media or TURN problem (step 4-5). See the troubleshooting guide.
What Just Happened
The binary you just ran is not a wrapper around external services. It is the whole stack:
- HTTP serves the web UI and REST status endpoints
- Symple carries WebSocket signalling and peer presence
- WebRTC handles media session negotiation and RTP transport
- TURN relays media through NATs when direct paths fail
- AV captures, encodes, and packetizes H.264 video and Opus audio
Each of those is an independent icey library module. The server assembles them into one binary. If you want to understand how, read the architecture page. If you want to use those modules in your own C++ application, read the build guide.
Three Modes
icey-server has three operational modes. The default is stream.
Server pushes a local file, camera, or RTSP source to the browser over WebRTC.
icey-server --mode stream --source /path/to/video.mp4This is the default. If you ran the Docker command above, this is what you saw.
Browser sends H.264 video to the server, which decodes and writes MP4 files to disk.
icey-server --mode record --record-dir ./recordingsOpen the browser, grant camera access, and click Call. The server writes timestamped MP4 files under the recording directory.
First active browser caller becomes the live source. Later callers receive that source via server-side relay.
icey-server --mode relayNo server-side capture or encoding. The server forwards the first caller's encoded media to every subsequent viewer.
Each mode is covered in detail on the modes page.
Where To Go Next
Install
Docker, release binaries, Homebrew, APT, AUR, Nix, or build from source. Every install path in one place.
Build With icey
Use the library modules in your own C++ application. FetchContent, CMake targets, your first program.
Operate
Config file reference, deployment guides, TLS, TURN, health endpoints, and troubleshooting.
