Skip to content

Deployment

Deploy MikroRoom to various platforms and environments.

Before deploying to production:

  • Configure HTTPS/WSS
  • Set up TURN server
  • Update mikroroom.config.json with production URLs
  • Set strong TURN credentials
  • Configure firewall rules
  • Test from different networks

MikroRoom includes example deployment scripts. Copy and customize:

Terminal window
# Backend deployment
cp deploy-backend.example.sh deploy-backend.sh
chmod +x deploy-backend.sh
# Edit with your server details
./deploy-backend.sh
# Frontend deployment
cp deploy-frontend.example.sh deploy-frontend.sh
chmod +x deploy-frontend.sh
# Edit with your hosting details
./deploy-frontend.sh

Note: Docker deployment requires building from source code. If you installed via the MikroRoom CLI (mikroroom install), use the Linux Server (Systemd) method instead.

For source code deployments:

Terminal window
# Clone the repository
git clone https://github.com/mikaelvesavuori/mikroroom.git
cd mikroroom
# Build image
docker build -t mikroroom .
# Run container
docker run -d \
-p 3000:3000 \
--name mikroroom \
-e TURN_SERVER_URL=turn:turn.yourdomain.com:3478 \
-e TURN_SERVER_USERNAME=mikroroom \
-e TURN_SERVER_CREDENTIAL=your-password \
mikroroom

For source code deployments, create docker-compose.yml in your project directory:

version: '3.8'
services:
mikroroom:
build: .
ports:
- "3000:3000"
environment:
- PORT=3000
- TURN_SERVER_URL=turn:turn.yourdomain.com:3478
- TURN_SERVER_USERNAME=mikroroom
- TURN_SERVER_CREDENTIAL=${TURN_PASSWORD}
restart: unless-stopped
healthcheck:
test: ["CMD", "wget", "--spider", "-q", "http://localhost:3000/health"]
interval: 30s
timeout: 3s
retries: 3

Run:

Terminal window
TURN_PASSWORD=your-password docker-compose up -d

Recommended for: CLI installations and production deployments without Docker

Copy and edit the systemd service:

Terminal window
# Copy example service file
sudo cp mikroroom.service.example /etc/systemd/system/mikroroom.service
# Edit paths and environment
sudo nano /etc/systemd/system/mikroroom.service
# Enable and start
sudo systemctl daemon-reload
sudo systemctl enable mikroroom
sudo systemctl start mikroroom
sudo systemctl status mikroroom

Example service file for CLI installation (mikroroom install):

[Unit]
Description=MikroRoom Server
After=network.target
[Service]
Type=simple
User=mikroroom
WorkingDirectory=/home/mikroroom/.mikroroom
Environment="NODE_ENV=production"
Environment="PORT=3000"
Environment="TURN_SERVER_URL=turn:turn.yourdomain.com:3478"
ExecStart=/usr/bin/node /home/mikroroom/.mikroroom/api/mikroroom.mjs
Restart=on-failure
[Install]
WantedBy=multi-user.target

Example service file for source code deployment:

[Unit]
Description=MikroRoom Server
After=network.target
[Service]
Type=simple
User=mikroroom
WorkingDirectory=/opt/mikroroom
Environment="NODE_ENV=production"
Environment="PORT=3000"
Environment="TURN_SERVER_URL=turn:turn.yourdomain.com:3478"
ExecStart=/usr/bin/node /opt/mikroroom/dist/api/mikroroom.mjs
Restart=on-failure
[Install]
WantedBy=multi-user.target
Terminal window
# Create app
heroku create your-app-name
# Set environment variables
heroku config:set NODE_ENV=production
heroku config:set TURN_SERVER_URL=turn:turn.yourdomain.com:3478
heroku config:set TURN_SERVER_USERNAME=mikroroom
heroku config:set TURN_SERVER_CREDENTIAL=your-password
# Deploy
git push heroku main
Terminal window
# Install flyctl
curl -L https://fly.io/install.sh | sh
# Launch app
fly launch
# Set secrets
fly secrets set TURN_SERVER_URL=turn:turn.yourdomain.com:3478
fly secrets set TURN_SERVER_USERNAME=mikroroom
fly secrets set TURN_SERVER_CREDENTIAL=your-password
# Deploy
fly deploy
  1. Connect your GitHub repository
  2. Configure build command: npm run build
  3. Configure run command: npm start
  4. Add environment variables in the dashboard
  5. Deploy!

For separate frontend/backend deployment:

Terminal window
npm run build
npx wrangler pages deploy dist/app --project-name=mikroroom
Terminal window
npm run build
npx netlify deploy --dir=dist/app --prod
Terminal window
npm run build
npx vercel --prod dist/app
Terminal window
# Build frontend
npm run build
# Upload to S3
aws s3 sync dist/app/ s3://your-bucket-name/ --delete
# Invalidate CloudFront cache
aws cloudfront create-invalidation --distribution-id YOUR_ID --paths "/*"

Full example with HTTPS:

# HTTP -> HTTPS redirect
server {
listen 80;
server_name yourdomain.com;
return 301 https://$server_name$request_uri;
}
# HTTPS server
server {
listen 443 ssl http2;
server_name yourdomain.com;
# SSL certificates
ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
# WebSocket upgrade
location /ws {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
# API endpoints
location /api/ {
proxy_pass http://localhost:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
# Static files (if serving frontend from Nginx)
location / {
root /var/www/mikroroom;
try_files $uri $uri/ /index.html;
}
}

Enable and reload:

Terminal window
sudo ln -s /etc/nginx/sites-available/mikroroom /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

Caddy auto-handles HTTPS:

yourdomain.com {
# Serve static files
root * /var/www/mikroroom
file_server
# WebSocket proxy
@websocket {
path /ws
}
reverse_proxy @websocket localhost:3000
# API proxy
reverse_proxy /api/* localhost:3000
}

Reload:

Terminal window
sudo systemctl reload caddy

MikroRoom exposes a health endpoint:

Terminal window
curl https://yourdomain.com/health

Returns:

{
"status": "ok",
"totalRooms": 5,
"totalParticipants": 12,
"peakParticipants": 24,
"uptime": 3600000,
"version": "1.0.0"
}
Terminal window
# Follow logs
sudo journalctl -u mikroroom -f
# Last 100 lines
sudo journalctl -u mikroroom -n 100
# Logs since boot
sudo journalctl -u mikroroom -b
Terminal window
# Follow logs
docker logs -f mikroroom
# Last 100 lines
docker logs --tail 100 mikroroom

Integrate with:

  • Prometheus - Metrics collection
  • Grafana - Dashboards
  • Uptime Kuma - Uptime monitoring
  • Sentry - Error tracking
Terminal window
# Allow SSH
sudo ufw allow 22/tcp
# Allow HTTP/HTTPS
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
# Allow TURN (if running Coturn)
sudo ufw allow 3478/tcp
sudo ufw allow 3478/udp
sudo ufw allow 49152:65535/udp
# Enable firewall
sudo ufw enable
  • Use Let’s Encrypt for free SSL certificates
  • Enable TLS 1.2+ only
  • Configure HSTS headers
  • Use strong cipher suites
  • Auto-renew certificates

MikroRoom includes built-in rate limiting:

  • 10 WebSocket connections per minute per IP
  • 10 room creation requests per minute per IP

For additional protection, use Nginx rate limiting or Cloudflare.

For larger deployments:

  1. Run multiple MikroRoom instances
  2. Use a load balancer (Nginx, HAProxy)
  3. Enable sticky sessions for WebSocket connections
  4. Share TURN server across instances
upstream mikroroom_backend {
ip_hash; # Sticky sessions
server 10.0.0.1:3000;
server 10.0.0.2:3000;
server 10.0.0.3:3000;
}
server {
listen 443 ssl http2;
server_name yourdomain.com;
location / {
proxy_pass http://mikroroom_backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
  • Verify apiUrl matches deployment protocol (ws/wss)
  • Check reverse proxy WebSocket headers
  • Ensure firewall allows WebSocket traffic
  • HTTPS is required for camera/microphone access
  • Check browser permissions
  • Verify SSL certificate is valid
  • Add TURN server configuration
  • Test TURN with Trickle ICE
  • Verify firewall allows TURN ports