WebRTC

Janus WebRTC Gateway Installation on Ubuntu (Production Guide)

MYLINEHUB Team • 2026-02-21 • 18 min

Step-by-step production installation of Janus WebRTC Gateway on Ubuntu, including libsrtp, libnice, coturn, firewall rules, and common build failures.

Janus WebRTC Gateway Installation on Ubuntu (Production Guide)

Janus • WebRTC Gateway • Ubuntu • Production Hardening • NAT/ICE/TURN

Janus WebRTC Gateway Installation on Ubuntu (Production Guide: from Zero → Hardened)

This is a production-focused guide to installing Janus WebRTC Gateway on Ubuntu, with the exact decisions you must make for real traffic: which Ubuntu version, which Janus version strategy, why we run TURN, how to set NAT/ICE, how to run Janus as a service, how to secure it, and how to validate audio works end-to-end.

What Janus is (layman version): Janus is a “WebRTC network translator” server.

  • Browsers speak WebRTC (DTLS, SRTP, ICE candidates, NAT traversal)
  • Many systems (SIP/PBX/AI pipelines) don’t speak WebRTC natively
  • Janus sits in the middle: browsers connect to Janus via WebRTC, and Janus connects to the rest via plugins (SIP, streaming, recordings, etc.)

If you’re building a website “voice button” that talks to a PBX/AI bot, Janus is often the simplest stable bridge. See: https://mylinehub.com/articles/webrtc-website-voice-button-ai-bot-architecture

1) Choosing versions: Ubuntu, Janus, plugins

Ubuntu version: what to use and why

For production, use an Ubuntu LTS. The main reason is not “features”, it’s stability and predictable updates. Janus depends on low-level libraries; LTS reduces surprises.

Ubuntu Recommended? Why
22.04 LTS Yes Stable toolchain, modern libs, long support window
24.04 LTS Yes Also fine, but verify any custom patches/plugins you use
Non-LTS No More churn and unexpected dependency changes

If your team is new to WebRTC infrastructure, start with 22.04 LTS for maximum “known good” stability.

Janus version strategy (practical)

Janus is commonly installed from source so you can control features and plugin build options. In production, you want:

  • A repeatable build process
  • A pinned release or git tag (not “random latest commit”)
  • A rollback plan (keep previous binaries)

Rule of thumb: pin a Janus release tag, and only upgrade after testing in a staging environment with real browsers + real NAT paths.

2) Production architecture (why Janus + TURN + firewall)

The most common reason “WebRTC worked in my laptop test but fails in production” is networking: NAT, UDP policies, and missing TURN.

Browser Users WebRTC: DTLS/SRTP + ICE Behind NAT / firewalls Janus Gateway WebRTC termination Plugins: SIP / streaming RTP ports open on server Your Backends SIP/PBX (Asterisk) AI voice bot pipeline WebRTC media SIP/RTP or plugin

Why Janus (practical reasons):

  • Browsers speak WebRTC; PBX systems typically speak RTP/SIP
  • Janus is a proven middle layer with plugins and good observability
  • It keeps your PBX/AI pipeline clean: WebRTC ↔ Janus ↔ SIP/PBX/AI

If you’re combining WebRTC + Asterisk + AI, also read: https://mylinehub.com/articles/send-audio-back-to-caller-using-ari-externalmedia-working-rtp-guide

3) Server prerequisites and sizing

Minimum server sizing (starter)

Component Starter Notes
CPU 2–4 vCPU WebRTC encryption + packet handling is CPU sensitive
RAM 4–8 GB Janus itself is light, but plugins/logging add overhead
Network 1 Gbps RTP media is bandwidth-heavy; TURN (if colocated) increases usage
Disk 20+ GB Mostly for OS, logs, optional recordings

If you run TURN on the same box, plan more bandwidth and monitor egress costs.

Network reality check (before you install)

  • Do you have a public IPv4 (recommended) or only IPv6?
  • Are you behind cloud NAT? (some providers do this by default)
  • Can you open a UDP port range for RTP?
  • Do you have or plan a TURN server? (recommended)

If you cannot open UDP ports: WebRTC can still work using TURN over TCP/TLS, but latency increases.

4) Install dependencies (safe defaults)

Janus is C-based and commonly built from source. The dependency list looks long, but you can treat it as “build tools + crypto + WebSockets + codecs”.

Production habit: do updates first, and keep dependency installs in a script so you can reproduce builds.

# 1) Update OS packages
sudo apt-get update
sudo apt-get -y upgrade

# 2) Build tools + common libs
sudo apt-get install -y \
  git autoconf automake libtool pkg-config \
  build-essential cmake ninja-build \
  libmicrohttpd-dev libjansson-dev libssl-dev \
  libsrtp2-dev libcurl4-openssl-dev \
  libsofia-sip-ua-dev \
  libglib2.0-dev libopus-dev libogg-dev libini-config-dev \
  gengetopt libconfig-dev

# Optional but common:
sudo apt-get install -y \
  libnice-dev \
  libwebsockets-dev \
  libnanomsg-dev

# Helpful tools
sudo apt-get install -y \
  unzip wget curl htop net-tools tcpdump

What these “big” dependencies mean (layman)

  • OpenSSL: encryption (DTLS/TLS) essentials
  • libsrtp: secure RTP for media
  • libnice: ICE implementation (helps NAT traversal)
  • libwebsockets / microhttpd: Janus transport options
  • sofia-sip: SIP stack for SIP plugin (if you use SIP)
  • Opus: common WebRTC audio codec

Why ICE libs matter (and why people get confused)

WebRTC needs ICE to traverse NAT. Browsers have ICE built in. Janus also needs ICE because Janus itself is a WebRTC endpoint.

Read the foundations first: https://mylinehub.com/articles/ice-vs-stun-vs-turn-complete-webrtc-networking-guide

Why build from source? You control features, plugins, and versions. This prevents “it broke after apt upgrade” surprises.

# Choose a working directory
cd /usr/src

# Clone Janus
sudo git clone https://github.com/meetecho/janus-gateway.git
cd janus-gateway

# (Recommended) checkout a specific tag/release
# Example:
# sudo git checkout v1.2.3
# Use the tag you have tested in staging.

# Build system
sudo sh autogen.sh

# Configure install path
sudo ./configure --prefix=/opt/janus --enable-websockets --enable-rest

# Build and install
sudo make -j"$(nproc)"
sudo make install
sudo make configs

# Create a symlink for convenience
sudo ln -sf /opt/janus/bin/janus /usr/local/bin/janus

Where configs land (typical)

  • Binary: /opt/janus/bin/janus
  • Configs: /opt/janus/etc/janus
  • Plugins: /opt/janus/lib/janus/plugins
  • Transports: /opt/janus/lib/janus/transports

Keep these paths consistent across environments so systemd, logs, and docs stay stable.

Common build pitfalls (fast answers)

  • configure fails: missing -dev package → install it and rerun configure
  • SIP plugin missing: sofia-sip not installed when configuring
  • ICE issues: libnice not installed or not detected
  • WebSockets not enabled: libwebsockets missing

6) Core Janus config (janus.jcfg)

Janus uses configuration files to enable transports (how you connect to Janus) and plugins (what Janus can do). The single most important core file is typically: janus.jcfg.

Production approach: keep configs in git (private repo) and deploy them like application code.

# Example location:
# /opt/janus/etc/janus/janus.jcfg

general: {
  # In production, keep logs structured and not too verbose
  debug_level = 4
  debug_timestamps = true
  debug_colors = false

  # If you are behind NAT, you must handle this properly (covered below)
  # nat_1_1_mapping = "YOUR_PUBLIC_IP"
  # ice_enforce_list = "eth0"
}

# RTP settings:
media: {
  # IMPORTANT: open these ports in firewall (see firewall section)
  rtp_port_range = "20000-40000"
}

Key settings explained (no jargon)

Setting What it controls Why it matters
rtp_port_range The UDP ports Janus uses for media If your firewall blocks these, calls fail or become one-way
nat_1_1_mapping Public IP mapping if Janus is behind NAT Browsers must learn a reachable public address
ice_enforce_list Which network interface Janus should use Prevents Janus from advertising wrong IPs on multi-NIC servers
debug_level Verbosity of logs High logs help debugging but can flood disk in production

7) ICE / STUN / TURN: what to configure and why

If you deploy Janus in production and do not configure TURN, you will get user reports like: “Works on my home Wi-Fi, fails on office network.”

What Janus needs

  • Janus needs ICE because Janus is a WebRTC endpoint (like a browser)
  • ICE uses STUN to discover “public mapped addresses”
  • ICE uses TURN when direct connectivity fails

Foundation guide: https://mylinehub.com/articles/ice-vs-stun-vs-turn-complete-webrtc-networking-guide

Where to set TURN in Janus

Janus typically reads ICE server settings from its config (depending on transport/plugin setup). A common pattern is to configure STUN/TURN settings in Janus configs so Janus can advertise relay paths properly.

Production rule: run your own TURN (coturn), use ephemeral credentials, and expose UDP + TCP + TLS TURN endpoints.

ICE/STUN/TURN decision table (simple)

Network scenario What usually works What you need for reliability
Friendly home NAT STUN + direct ICE TURN still recommended as fallback
Office firewall Sometimes fails TURN over TCP/TLS
Mobile carrier NAT Often flaky TURN (UDP preferred, TCP/TLS fallback)

8) NAT, public IP, and tricky cloud networking

Most production Janus problems are not “Janus bugs”. They are: wrong public IP advertised, wrong interface selected, or blocked UDP ports.

Case A: Janus has a public IP (simplest)

  • Server has public IPv4 on the NIC
  • Firewall open for RTP port range
  • TURN still recommended (some clients still fail without relay)

This is the easiest to operate and debug.

Case B: Janus is behind NAT (common in some setups)

  • Server’s interface is private IP
  • You must configure mapping so Janus advertises the public IP
  • Without correct mapping, browsers try to send media to a private IP and fail

Typical fix: set nat_1_1_mapping and restrict ICE to the right NIC.

# Example (edit your janus.jcfg):
general: {
  # If Janus has private IP but is reachable via public IP:
  nat_1_1_mapping = "YOUR_PUBLIC_IP"

  # Ensure Janus advertises only the correct NIC (example: eth0)
  ice_enforce_list = "eth0"
}

media: {
  rtp_port_range = "20000-40000"
}

Beginner mistake: “My server can curl the internet, so it must be fine.”

WebRTC media is inbound UDP to your server. Outbound connectivity does not prove inbound RTP is reachable.

9) SIP plugin basics (optional but common)

Many deployments use Janus SIP plugin to connect WebRTC browsers to SIP infrastructure (like Asterisk/FreePBX) for PSTN or call routing.

What the SIP plugin does (simple)

  • Browser ↔ Janus: WebRTC (DTLS/SRTP)
  • Janus ↔ PBX: SIP signaling + RTP media (normal VoIP)
  • Janus handles codec negotiation and secure media on the browser side

Common “why no audio” causes in Janus ↔ PBX

  • PBX RTP ports blocked
  • NAT settings wrong on PBX (advertises private IP)
  • Codec mismatch (Opus vs PCMU/PCMA) depending on your bridge strategy

If your PBX side uses ARI ExternalMedia, also read: https://mylinehub.com/articles/send-audio-back-to-caller-using-ari-externalmedia-working-rtp-guide

Production hint: don’t try to “solve everything” on day one. First make Janus ↔ Browser stable, then add SIP/PBX bridging.

10) Run Janus with systemd (service, logs, restarts)

Production means: Janus starts on boot, restarts if it crashes, and logs are centralized. systemd is the standard way on Ubuntu.

# Create a dedicated user for Janus (recommended)
sudo useradd --system --no-create-home --shell /usr/sbin/nologin janus

# Create log directory
sudo mkdir -p /var/log/janus
sudo chown -R janus:janus /var/log/janus

# Create systemd unit
sudo tee /etc/systemd/system/janus.service > /dev/null <<'EOF'
[Unit]
Description=Janus WebRTC Gateway
After=network.target

[Service]
Type=simple
User=janus
Group=janus
ExecStart=/opt/janus/bin/janus -F /opt/janus/etc/janus
Restart=always
RestartSec=2
LimitNOFILE=1048576

# Hardening (safe defaults)
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=full
ProtectHome=true
ReadWritePaths=/var/log/janus /opt/janus

[Install]
WantedBy=multi-user.target
EOF

# Reload and start
sudo systemctl daemon-reload
sudo systemctl enable janus
sudo systemctl start janus

# Check status and logs
sudo systemctl status janus --no-pager
sudo journalctl -u janus -n 200 --no-pager

Log strategy: start with journald, then forward to your central logging (ELK/CloudWatch/etc.).

11) Firewall ports & network rules (tables)

The most important “production” part is opening the correct ports. If you do not open media UDP, your WebRTC will appear to “connect” and then have silence, or it will fail for some users.

Port table (Janus + TURN typical)

Purpose Protocol Port(s) From To Notes
Janus HTTP API (REST) TCP 8088 (example) Your app servers Janus Prefer internal/private access, not public internet
Janus HTTPS API TCP 8089 (example) Your app servers Janus Use TLS if crossing networks
Janus WebSockets TCP 8188/8989 (example) Browsers/app Janus Common for browser signaling
Janus RTP media range UDP 20000–40000 Browsers (via ICE) Janus Must be open for WebRTC media
TURN UDP/TCP 3478 Browsers TURN TURN allocations + relay
TURNS (TURN over TLS) TCP 5349 Browsers TURN Helpful when UDP blocked
TURN relay range UDP/TCP Configured range Browsers TURN Open the relay port range you set in coturn

Beginner mistake: opening only 443 and expecting WebRTC media to work.

WebRTC media uses dynamic UDP ports (RTP). TURN over TLS helps when UDP is blocked, but still requires correct TURN setup.

12) TLS: HTTPS, WSS, and secure signaling

WebRTC media is encrypted (DTLS/SRTP), but your signaling layer (how the browser talks to your server/Janus) still needs proper HTTPS/WSS in production.

What should be TLS?

  • Your website must be HTTPS (browsers restrict mic access on insecure origins)
  • Your signaling WebSocket should be WSS
  • TURN over TLS (TURNS) is recommended as a fallback when UDP is blocked

Where to terminate TLS

  • Common approach: Nginx in front of Janus for WSS/HTTPS
  • Keep Janus internal (private subnet) when possible
  • Expose only what browsers must reach

Operational habit: keep public edge (Nginx) separate from media servers if scaling.

13) Validation & troubleshooting (what to test first)

Test 1: Janus running and reachable

# Check service
sudo systemctl status janus --no-pager

# Check listeners (example)
sudo ss -lntup | grep -E 'janus|8088|8089|8188|8989'

# Tail logs
sudo journalctl -u janus -f

If Janus can’t start, fix that before touching WebRTC configs.

Test 2: RTP ports open (the real failure point)

# On Janus box: watch UDP traffic when a browser tries to connect
sudo tcpdump -n -i any udp portrange 20000-40000

# If you see nothing during call attempts:
# - firewall blocks UDP range
# - Janus advertised wrong IP (NAT mapping)
# - ICE/TURN not configured correctly

This is the fastest way to separate “signaling works” vs “media works”.

Test 3: Confirm ICE path (direct vs TURN relay)

In the browser, check WebRTC internals / stats to see if the selected candidate is srflx or relay. If many users need relay, TURN is required (that is normal in production).

Interpretation:

  • relay chosen: TURN is in use (good fallback)
  • srflx chosen but call fails: NAT mapping might be unstable or media ports blocked
  • no candidate works: TURN not reachable or not configured

14) Production checklist (copy/paste)

Item Done looks like Common failure
Ubuntu LTS 22.04/24.04 with security updates Non-LTS breaks deps unexpectedly
Pinned Janus build Tag/release pinned, reproducible install script “latest commit” drifts between servers
RTP UDP range open 20000–40000 UDP reachable from internet Only 80/443 open → no media
NAT mapping configured (if needed) Janus advertises reachable public IP Advertises private IP → users fail
TURN deployed coturn running with auth + TLS option No TURN → office/mobile users fail
systemd service Auto restart, logs, file limits set Manual run in terminal → outages on reboot
Observability Logs + metrics + alert on restarts “Users report it” is your monitoring

Production rule: If you want fewer support tickets, treat TURN + firewall rules as part of the product, not an optional add-on.

15) References and next articles

Try it

Want to see API-driven CRM + Telecom workflows in action? Try the WhatsApp bot or explore the demos.

💬 Try WhatsApp Bot ▶️ Watch CRM YouTube Demos
Tip: Comment “Try the bot” on our YouTube videos to see automation in action.
M
MYLINEHUB Team
Published: 2026-02-21
Quick feedback
Was this helpful? (Yes 0 • No 0)
Reaction

Comments (0)

Be the first to comment.