Deploying Janus WebRTC Gateway
Introduction
Janus is a general-purpose WebRTC gateway designed and developed by Meetecho. It acts as a media server hub that can power real-time audio and video sessions for applications, functioning as an SFU (Selective Forwarding Unit) to relay media streams between participants.
Built in C for performance and stability, Janus provides a modular plugin architecture supporting various use cases including video conferencing rooms, audio bridges, streaming, SIP integration, and more. The server handles all the complexity of WebRTC media negotiation, ICE connectivity, and DTLS encryption while exposing simple APIs for application integration.
Key highlights of Janus:
- WebRTC Gateway: Full WebRTC stack handling media and data channels
- Plugin Architecture: Modular design with plugins for different use cases
- VideoRoom: Multi-party video conferencing as an SFU
- AudioBridge: Audio conferencing with mixing capabilities
- Streaming: WebRTC-based media streaming
- SIP Gateway: Bridge WebRTC to SIP/VoIP systems
- Text Room: Data channel-based text communication
- Recording: Record sessions to local files
- REST/WebSocket API: Multiple transport options for signaling
- Event Handlers: Integration hooks for analytics and logging
- High Performance: Written in C for minimal latency
This guide walks through deploying Janus on Klutch.sh using Docker, configuring plugins for your use case, and setting up the gateway for production real-time communication.
Why Deploy Janus on Klutch.sh
Deploying Janus on Klutch.sh provides several advantages for WebRTC applications:
Simplified Deployment: Klutch.sh handles Docker container deployment, making Janus setup straightforward.
Persistent Storage: Attach volumes for recordings and configuration persistence.
HTTPS by Default: Klutch.sh provides automatic SSL certificates, essential for WebRTC security requirements.
GitHub Integration: Connect your configuration repository for automated deployments.
Scalable Resources: Allocate CPU and memory based on expected concurrent sessions.
Environment Variable Management: Securely store API secrets and configuration.
Custom Domains: Use your domain for the signaling endpoint.
Always-On Availability: Your WebRTC gateway remains accessible 24/7.
Prerequisites
Before deploying Janus on Klutch.sh, ensure you have:
- A Klutch.sh account
- A GitHub account with a repository for your Janus configuration
- Understanding of WebRTC concepts
- Basic familiarity with Docker and containerization
- (Optional) STUN/TURN server access for NAT traversal
- (Optional) A custom domain for your Janus instance
Understanding Janus Architecture
Janus operates with a core engine and pluggable modules:
Core Engine: Handles WebRTC negotiation, ICE, DTLS, SRTP, and media routing.
Transports: HTTP/HTTPS, WebSocket, RabbitMQ, MQTT for signaling.
Plugins: Modular components providing specific functionality:
- VideoRoom: SFU for video conferencing
- AudioBridge: MCU for audio mixing
- Streaming: One-to-many broadcasting
- SIP: VoIP gateway
- TextRoom: Data channel messaging
- NoSIP: RTP/RTSP integration
Event Handlers: Integration with external systems for logging and analytics.
Preparing Your Repository
Repository Structure
janus-deploy/├── Dockerfile├── conf/│ ├── janus.jcfg│ ├── janus.transport.http.jcfg│ ├── janus.transport.websockets.jcfg│ └── janus.plugin.videoroom.jcfg├── README.md└── .dockerignoreCreating the Dockerfile
FROM canyanio/janus-gateway:latest
# Copy configuration filesCOPY conf/ /usr/local/etc/janus/
# Expose ports# HTTP APIEXPOSE 8088# HTTPS APIEXPOSE 8089# WebSocketEXPOSE 8188# Secure WebSocketEXPOSE 8989# Admin APIEXPOSE 7088
# RTP ports (UDP) - for mediaEXPOSE 10000-10200/udp
# Health checkHEALTHCHECK --interval=30s --timeout=10s --start-period=30s --retries=3 \ CMD curl -f http://localhost:8088/janus/info || exit 1
CMD ["janus"]Creating Configuration Files
Create conf/janus.jcfg:
general: { configs_folder = "/usr/local/etc/janus" plugins_folder = "/usr/local/lib/janus/plugins" transports_folder = "/usr/local/lib/janus/transports" events_folder = "/usr/local/lib/janus/events" log_to_stdout = true debug_level = 4}
certificates: { cert_pem = "/usr/local/share/janus/certs/mycert.pem" cert_key = "/usr/local/share/janus/certs/mycert.key"}
nat: { stun_server = "stun.l.google.com" stun_port = 19302 nice_debug = false full_trickle = true}
media: { rtp_port_range = "10000-10200"}
plugins: { disable = "libjanus_recordplay.so,libjanus_voicemail.so"}Create conf/janus.transport.http.jcfg:
general: { json = "indented" base_path = "/janus" http = true port = 8088 https = false}
admin: { admin_http = true admin_port = 7088 admin_https = false}
cors: { allow_origin = "*"}Create conf/janus.transport.websockets.jcfg:
general: { json = "indented" ws = true ws_port = 8188 wss = false}
admin: { admin_ws = false}Create conf/janus.plugin.videoroom.jcfg:
general: { admin_key = "supersecretkey" lock_rtp_forward = true}
room-1234: { description = "Demo Room" secret = "adminpwd" publishers = 10 bitrate = 512000 fir_freq = 10 audiocodec = "opus" videocodec = "vp8" record = false}Creating the .dockerignore File
.git.github*.mdLICENSE.gitignore*.log.DS_Store.env.env.localEnvironment Variables Reference
| Variable | Required | Default | Description |
|---|---|---|---|
JANUS_API_SECRET | No | - | API authentication secret |
JANUS_ADMIN_SECRET | No | - | Admin API secret |
JANUS_STUN_SERVER | No | stun.l.google.com | STUN server address |
JANUS_TURN_SERVER | No | - | TURN server address |
JANUS_TURN_USER | No | - | TURN username |
JANUS_TURN_PASSWORD | No | - | TURN password |
Deploying Janus on Klutch.sh
- Connect your GitHub repository
- Select the repository containing your Dockerfile
- Configure HTTP traffic on port 8088 (or 8188 for WebSocket)
Push Your Repository to GitHub
Initialize your repository and push to GitHub:
git initgit add Dockerfile conf/ .dockerignore README.mdgit commit -m "Initial Janus deployment configuration"git remote add origin https://github.com/yourusername/janus-deploy.gitgit push -u origin mainCreate a New Project on Klutch.sh
Navigate to the Klutch.sh dashboard and create a new project. Give it a descriptive name like “janus” or “webrtc-gateway”.
Create a New App
Within your project, create a new app:
Set Environment Variables
Configure optional environment variables:
| Variable | Value |
|---|---|
JANUS_API_SECRET | Your API secret |
JANUS_ADMIN_SECRET | Your admin secret |
Attach Persistent Volumes
Add persistent storage for recordings:
| Mount Path | Recommended Size | Purpose |
|---|---|---|
/recordings | 50+ GB | Session recordings |
/usr/local/etc/janus | 1 GB | Configuration files |
Deploy Your Application
Click Deploy to start the build process.
Verify Deployment
Once deployed, verify Janus is running by accessing:
https://your-app-name.klutch.sh/janus/info
Using Janus Plugins
VideoRoom (Video Conferencing)
Create a video conference room:
// Join a video roomconst janusSession = await janus.createSession();const videoRoom = await janusSession.attach("janus.plugin.videoroom");
await videoRoom.send({ message: { request: "join", room: 1234, ptype: "publisher", display: "User Name" }});AudioBridge (Audio Conferencing)
Set up audio-only conferences:
const audioBridge = await janusSession.attach("janus.plugin.audiobridge");
await audioBridge.send({ message: { request: "join", room: 1234, display: "User Name" }});Streaming Plugin
One-to-many broadcasting:
const streaming = await janusSession.attach("janus.plugin.streaming");
await streaming.send({ message: { request: "watch", id: 1 }});Client Integration
JavaScript Client
Use the official Janus JavaScript library:
<script src="https://your-app.klutch.sh/janus.js"></script><script>Janus.init({ debug: "all", callback: function() { var janus = new Janus({ server: 'wss://your-app.klutch.sh:8989', success: function() { // Janus connected }, error: function(error) { console.error(error); } }); }});</script>REST API
Interact via HTTP:
# Get server infocurl https://your-app.klutch.sh/janus/info
# Create sessioncurl -X POST https://your-app.klutch.sh/janus \ -H "Content-Type: application/json" \ -d '{"janus":"create","transaction":"abc123"}'Production Best Practices
Security Recommendations
- API Secrets: Configure API and admin secrets
- HTTPS/WSS: Use secure transports only
- Room Secrets: Protect rooms with passwords
- Token Authentication: Implement token-based auth
- CORS Configuration: Restrict allowed origins
Performance Optimization
- Codec Selection: Choose appropriate codecs for use case
- Bitrate Limits: Set reasonable bitrate caps
- Simulcast: Enable for variable quality streaming
- ICE Configuration: Optimize STUN/TURN settings
TURN Server Setup
For reliable NAT traversal:
- Deploy a TURN server (coturn recommended)
- Configure Janus to use your TURN server
- Provide credentials in configuration
Troubleshooting Common Issues
Connection Failures
Symptoms: Clients can’t connect to Janus.
Solutions:
- Verify Janus is running and ports are accessible
- Check STUN/TURN configuration
- Review browser console for WebRTC errors
- Ensure secure transport for HTTPS pages
Media Issues
Symptoms: No audio/video after connecting.
Solutions:
- Check media permissions in browser
- Verify codec compatibility
- Review ICE candidate gathering
- Check firewall for UDP traffic
High Latency
Symptoms: Noticeable delay in streams.
Solutions:
- Use TURN only as fallback
- Optimize network path
- Reduce video quality/bitrate
- Check server resource utilization
Additional Resources
- Official Janus Website
- Janus Documentation
- Janus GitHub Repository
- Janus Community Forum
- Klutch.sh Persistent Volumes
- Klutch.sh Deployments
Conclusion
Deploying Janus on Klutch.sh provides a powerful WebRTC gateway for building real-time communication applications. The combination of Janus’s flexible plugin architecture and Klutch.sh’s container hosting enables rapid development of video conferencing, streaming, and VoIP solutions.
Whether you’re building a simple video chat or a complex multi-party conferencing system, Janus on Klutch.sh delivers the infrastructure needed for reliable, scalable real-time communication.