Home
Operate

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-stopped
Note

network_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.

Note

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.target
sudo systemctl daemon-reload
sudo systemctl enable --now icey-server
sudo journalctl -u icey-server -f

Minimal 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: 5
Warning

WebRTC 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.

1

Stream mode, local file, no TURN

icey-server --source ./demo.mp4 --no-turn

This 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.

2

Record mode

icey-server --mode record --record-dir ./recordings --no-turn

This 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.

3

Relay mode

icey-server --mode relay --no-turn

This validates the full bidirectional path. First browser becomes the source, second browser becomes the viewer.

4

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-root points at the actual built dist/ directory (or the Docker image includes it)
  • --record-dir is writable if you use record mode
  • --source points 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

ServicePortProtocolRequired
HTTP / WebSocket4500TCPAlways
TURN relay3478UDP + TCPUnless --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.