Deploy
How to run icey-server in production. Pick the deployment method that fits your infrastructure.
version: "3.8"
services:
icey:
image: 0state/icey-server:0.1.1
network_mode: host
environment:
ICEY_MODE: stream
ICEY_SOURCE: /app/media/video.mp4
ICEY_LOOP: 1
volumes:
- ./media:/app/media:ro
- ./recordings:/app/recordings
restart: unless-stoppednetwork_mode: host is the simplest path. It avoids port mapping and NAT complications. If you need bridge networking, you must publish ports 4500 and 3478 and set ICEY_TURN_EXTERNAL_IP to the host's public IP.
The published Docker image is environment-driven (ICEY_MODE, ICEY_SOURCE, ICEY_LOOP, ICEY_TURN_EXTERNAL_IP). For config-file-driven bring-up, use a native icey-server install or the repo-backed nilstate/icey-cli source path.
Create /etc/systemd/system/icey-server.service:
[Unit]
Description=icey-server media runtime
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
ExecStart=/usr/bin/icey-server \
--config /etc/icey-server/config.json
Restart=on-failure
RestartSec=5
User=icey
Group=icey
WorkingDirectory=/var/lib/icey-server
[Install]
WantedBy=multi-user.targetsudo systemctl daemon-reload
sudo systemctl enable --now icey-server
sudo journalctl -u icey-server -fMinimal deployment. Adjust resource limits and storage for your workload.
apiVersion: apps/v1
kind: Deployment
metadata:
name: icey-server
spec:
replicas: 1
selector:
matchLabels:
app: icey-server
template:
metadata:
labels:
app: icey-server
spec:
containers:
- name: icey-server
image: 0state/icey-server:0.1.1
ports:
- containerPort: 4500
name: http
- containerPort: 3478
name: turn
protocol: UDP
env:
- name: ICEY_MODE
value: relay
livenessProbe:
httpGet:
path: /api/health
port: 4500
periodSeconds: 10
readinessProbe:
httpGet:
path: /api/ready
port: 4500
periodSeconds: 5WebRTC and TURN require UDP. If your cluster uses a network policy that blocks UDP, TURN relay will not work. You may need hostNetwork: true or a UDP-capable load balancer.
Bring-Up Order
If you are deploying for the first time, validate each layer before adding the next.
Stream mode, local file, no TURN
icey-server --source ./demo.mp4 --no-turnThis validates HTTP serving, Symple signalling, and the server-to-browser media path. If the browser cannot see the server peer, you have a signalling problem. If video does not play, you have a media path problem. Neither involves TURN.
Record mode
icey-server --mode record --record-dir ./recordings --no-turnThis validates the browser-to-server media path. Grant camera access in the browser, click Call, and check that MP4 files appear in the recording directory.
Relay mode
icey-server --mode relay --no-turnThis validates the full bidirectional path. First browser becomes the source, second browser becomes the viewer.
Enable TURN
Remove --no-turn. Set --turn-external-ip to your public IP. Test from a browser outside your local network.
If relay fails under NAT, check the TURN deployment guide before touching the media code.
Pre-Flight Checklist
Before starting the server in any environment:
- OpenSSL is installed and discoverable by the binary
- FFmpeg is installed and discoverable by the binary
--web-rootpoints at the actual builtdist/directory (or the Docker image includes it)--record-diris writable if you use record mode--sourcepoints to a real file, device, or reachable RTSP URL if you use stream mode- TURN port (3478) is reachable from outside if you expect relay through NATs
Ports And Firewalls
| Service | Port | Protocol | Required |
|---|---|---|---|
| HTTP / WebSocket | 4500 | TCP | Always |
| TURN relay | 3478 | UDP + TCP | Unless --no-turn |
If you are behind a firewall, both ports must be reachable from the browser. TURN uses UDP by default with TCP fallback.
TLS
See the TLS guide for HTTPS and WSS termination options.
