Skip to content

Reverse proxy

Browsers only allow microphone access on secure origins, so Inari must be served over HTTPS. A reverse proxy terminates TLS and forwards traffic to Inari on port 3030.

Three rules apply to every proxy:

  1. Forward the web port (3030) and enable WebSocket upgrades: the app uses /ws.
  2. Do not proxy the WebRTC port (44444, UDP and TCP). Audio goes directly from players to Inari, so that port must be open on your firewall.
  3. SERVER_PUBLIC_IP must be the public IP of the machine, not the proxy domain.

In the examples below, replace inari.example.com with your domain and 127.0.0.1:3030 with the address of your Inari container.

/etc/nginx/sites-available/inari
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 80;
server_name inari.example.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
http2 on;
server_name inari.example.com;
ssl_certificate /etc/letsencrypt/live/inari.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/inari.example.com/privkey.pem;
location / {
proxy_pass http://127.0.0.1:3030;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# WebSocket
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
}
}

Get a certificate with certbot --nginx -d inari.example.com if you do not have one yet.

Caddy gets and renews certificates automatically and supports WebSockets out of the box.

Caddyfile
inari.example.com {
reverse_proxy 127.0.0.1:3030
}

With Docker labels, assuming a websecure entrypoint and a letsencrypt certificate resolver already exist:

docker-compose.yml
services:
inari:
image: thedrewen/inari:stable
restart: unless-stopped
environment:
API_KEY: change-me
SERVER_PUBLIC_IP: 203.0.113.10
ports:
- "44444:44444/udp"
- "44444:44444/tcp"
labels:
- traefik.enable=true
- traefik.http.routers.inari.rule=Host(`inari.example.com`)
- traefik.http.routers.inari.entrypoints=websecure
- traefik.http.routers.inari.tls.certresolver=letsencrypt
- traefik.http.services.inari.loadbalancer.server.port=3030

Traefik forwards WebSockets automatically. Only the WebRTC port is published on the host; the web port is reached through Traefik.

Enable the required modules first:

Terminal window
a2enmod proxy proxy_http proxy_wstunnel rewrite ssl headers
/etc/apache2/sites-available/inari.conf
<VirtualHost *:80>
ServerName inari.example.com
Redirect permanent / https://inari.example.com/
</VirtualHost>
<VirtualHost *:443>
ServerName inari.example.com
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/inari.example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/inari.example.com/privkey.pem
ProxyPreserveHost On
RequestHeader set X-Forwarded-Proto "https"
RewriteEngine On
RewriteCond %{HTTP:Upgrade} =websocket [NC]
RewriteRule /(.*) ws://127.0.0.1:3030/$1 [P,L]
ProxyPass / http://127.0.0.1:3030/
ProxyPassReverse / http://127.0.0.1:3030/
</VirtualHost>
  1. Add a Proxy Host with your domain.
  2. Scheme http, forward host/IP of Inari, forward port 3030.
  3. Enable Websockets Support and Block Common Exploits.
  4. In the SSL tab, request a Let’s Encrypt certificate and enable Force SSL.

Cloudflare’s proxy (orange cloud) can carry the web page and WebSocket, but cannot carry the WebRTC port. Make sure SERVER_PUBLIC_IP is the real IP of your server and that port 44444 is reachable directly, not through Cloudflare.

  • https://inari.example.com/ shows the Inari page with a valid certificate.
  • The browser developer tools show a wss://inari.example.com/ws connection with status 101.
  • Audio works from a second network: this validates the WebRTC port.