NODED.CLOUD/Blog/MediaMTX Server on a VPS: RTSP, SRT, WebRTC and HLS in One Box

MediaMTX Server on a VPS: RTSP, SRT, WebRTC and HLS in One Box

15 Oct 2026 · Mario Marin

How to run a MediaMTX server on a VPS: which ports to open, a minimal authenticated config, three common setups, and why bandwidth rather than CPU decides the size of the box.

Most small live-video jobs need the same box: something that takes a stream in — OBS over SRT or WHIP, IP cameras over RTSP — and serves it out as WebRTC for sub-second browser playback, LL-HLS for bigger audiences, or RTSP for an NVR. A MediaMTX server does all of that from one binary, and a small VPS suits it, because the work is moving packets, not encoding them.

This post covers what MediaMTX is, the ports to open, a minimal config with authentication, three common setups, sizing (you are buying bandwidth, not CPU), security, and where one server stops being enough. Config keys and default ports come from the mediamtx.yml of the current release, v1.21.2.

What a MediaMTX server is (and is not)

MediaMTX — called rtsp-simple-server until it outgrew RTSP — is an MIT-licensed live media server and proxy from the bluenviron project. It is written in Go and ships as a single executable with no dependencies, or as the bluenviron/mediamtx Docker image. Publishers push to a named path; readers pull that path in any protocol the server speaks.

  • In: SRT, WebRTC (WHIP), RTSP, RTMP, HLS, MPEG-TS, RTP and Media-over-QUIC, or pulled from cameras and other servers.
  • Out: SRT, WebRTC (WHEP and a browser player), RTSP, RTMP, HLS and LL-HLS, Media-over-QUIC.
  • Also: recording, native forwarding, hooks that run commands on events, a control API and Prometheus metrics.

The part that matters for sizing: MediaMTX remuxes, it does not transcode. Resolution, bitrate and codec arrive as your source sent them; to change them, the docs pair it with FFmpeg. That keeps the server light, and it means the codec you publish decides who can watch. For on-demand playback of a file library you want a different tool — see our Jellyfin guide.

MediaMTX ports: what to open on the VPS

The defaults from the stock config. Open only the rows you use, and switch the rest off in the config too.

PortProtocolOpen it?
8554/tcpRTSPIf cameras, NVRs or players use RTSP
8000–8001/udpRTP/RTCP for RTSPNo: set rtspTransports: [tcp]
1935/tcpRTMP (RTMPS on 1936)Only for RTMP ingest
8890/udpSRTFor SRT ingest
8889/tcpWebRTC: player, WHIP, WHEPFor WebRTC
8189/udpWebRTC media (ICE)Always with 8889
8888/tcpHLS / LL-HLSFor HLS viewers
8892/tcp+udp, 8893/udpMedia-over-QUIC, on by defaultNo, unless used: moq: no
9997/tcp, 9998/tcpControl API, metrics (off by default)Never

On a public VPS, WebRTC is the usual snag: the handshake uses 8889/tcp, the video 8189/udp, and the server must tell each browser where to send it. Set webrtcAdditionalHosts to the public IP or a DNS name — required on Docker's bridge network, cheap insurance elsewhere — and if a viewer's network blocks UDP, webrtcLocalTCPAddress: :8189 adds a TCP fallback. Older guides use protocols, webrtcICEHostNAT1To1IPs and runOnReady; these are deprecated in favour of rtspTransports, webrtcAdditionalHosts and runOnAvailable.

MediaMTX setup: install and a minimal config

Docker with host networking is the simplest install: RTSP over UDP sees real client addresses, and Docker adds no firewall rules in host mode, so ufw applies as written.

docker run -d --name mediamtx --restart always \
  --network host \
  -v /etc/mediamtx/mediamtx.yml:/mediamtx.yml \
  bluenviron/mediamtx:1

The :1 tag tracks the latest 1.x release; 1-ffmpeg adds FFmpeg for hooks. Without Docker, put the release binary in /usr/local/bin and add the short systemd unit from the docs' start-on-boot page; mediamtx --upgrade updates it in place.

Start from the stock mediamtx.yml and change three things. First, the default lets anyone publish and read any path, so replace authInternalUsers:

authInternalUsers:
  - user: obs
    pass: long-random-publish-secret
    permissions:
      - action: publish
        path: live
  - user: viewer
    pass: different-read-secret
    permissions:
      - action: read
        path: "~^(live|cam[0-9]+)$"
  - user: any
    ips: ["127.0.0.1", "::1"]
    permissions:
      - action: api

A leading tilde makes path a regular expression. Browsers show a login prompt; for a public stream, give user: any the read permission instead. Argon2 or SHA-256 hashed passwords also work. Second, switch off unused protocols and set the WebRTC address. Third, replace the catch-all all_others path with your own — unlisted paths are refused:

rtspTransports: [tcp]
rtmp: no
moq: no
webrtcAdditionalHosts: [203.0.113.10]
paths:
  live:

Three setups that cover most jobs

IP cameras: RTSP to WebRTC in the browser

Cameras sit on a private network, and exposing their RTSP ports to the internet is the thing not to do. Either run a WireGuard tunnel from the site so the VPS pulls cameras over private addresses, or run MediaMTX at the site and forward each camera to the VPS over SRT. Over a tunnel:

paths:
  cam1:
    source: rtsp://user:[email protected]:554/stream1
    rtspTransport: tcp
    sourceOnDemand: yes

sourceOnDemand pulls the camera only while someone watches. Browsers open http://your-vps:8889/cam1; an NVR reads rtsp://your-vps:8554/cam1. Set cameras to H.264: many browsers cannot play H.265 over WebRTC, and MediaMTX will not convert it.

OBS: SRT or WHIP in, WebRTC and LL-HLS out

For SRT, pick a Custom service in OBS, use srt://your-vps:8890?streamid=publish:live:obs:SECRET&pkt_size=1316 as the server and leave the key empty; it is the right choice on a lossy uplink, as our SRT ingest post explains. For WHIP, the server is http://your-vps:8889/live/whip and the Bearer Token obs:SECRET.

The choice decides who hears audio. WebRTC carries Opus or G.711, not AAC, and MediaMTX skips a track it cannot deliver rather than converting it. OBS's usual SRT setup sends AAC, so WebRTC viewers get silent video; its WHIP output sends Opus with B-frames off, as browsers require. HLS takes AAC or Opus. So: WHIP for WebRTC audiences, SRT for HLS audiences or bad uplinks — or a runOnAvailable hook running one audio-only FFmpeg re-encode to Opus into a second path. Viewers use port 8889 for WebRTC or 8888 for LL-HLS, the default HLS variant: http://your-vps:8888/live.

Relay: forward to another server or platform

Current releases forward natively, without FFmpeg:

paths:
  live:
    forward:
      - dest: srt://backup.example.net:8890?streamid=publish:live:relay:SECRET
      - dest: rtmps://a.rtmps.youtube.com/live2#YOUR-STREAM-KEY

RTMP destinations take the stream key after a #; check the platform's current ingest URL, and note YouTube rejects streams without audio. Each destination is another copy of the bitrate leaving the server. For a web UI across several platforms, see the Restreamer walkthrough and our multistreaming use case.

Sizing a MediaMTX VPS: bandwidth, not CPU

Because MediaMTX repackages rather than re-encodes, CPU and memory stay modest; its scalability docs say bottlenecks are "almost always related to the limited bandwidth between server and readers". Two things do use real CPU: transcoding, and large WebRTC audiences, since WebRTC encrypts each viewer's connection separately while HLS is packaged once and served as files. There is no GPU on any of our VPS plans, so encode on the sender, and if you must transcode on the server, keep it to one rendition or to audio.

Egress is bitrate × concurrent viewers, plus forwarded copies, plus about 20% headroom for overhead and encoder peaks. Our standard shapes have no transfer quota but are shaped per machine, from 100 to 300 Mbps; the media server plans are unmetered with no per-VM ceiling. For a 6 Mbps stream:

ViewersEgress + 20%Fits onBucharest, monthly
1072 MbpsVPS I (100 Mbps)€4
20144 MbpsVPS III (180 Mbps)€10
30216 MbpsVPS IV (220 Mbps)€16
50360 MbpsStreaming II or III€18.99 / €34.99
2001,440 MbpsStreaming III or IV€34.99 / €59.99

The crossover is around 30 viewers: beyond it, VPS V at €30 or VPS VI at €58 would be bought only for their bandwidth figure, and Streaming II at €18.99 has no ceiling at all. The streaming line also carries more vCPU from the third shape up — 4 on Streaming III against 2 on VPS III — which large WebRTC audiences use. At 200 viewers you depend on the node's shared uplink, so talk to us before a big event or put a CDN in front. Location premiums apply: Streaming II is €23.99 and Streaming III €44.99 in Warsaw, Sofia or Vienna; VPS III is €14 in Warsaw and €16 in Sofia or Vienna.

Locking it down

  • Credentials on publish and read, separate and scoped to paths. SRT can also encrypt per path with srtPublishPassphrase and srtReadPassphrase.
  • Firewall to the rows you use, plus SSH, and switch unused protocols off so a firewall mistake exposes nothing.
  • API and metrics on localhost. Both are off by default; if enabled, set apiAddress: 127.0.0.1:9997 and metricsAddress: 127.0.0.1:9998 and reach them over SSH.
  • TLS for HLS and WebRTC. Set hlsEncryption: yes and webrtcEncryption: yes, with hlsServerKey/hlsServerCert and webrtcServerKey/webrtcServerCert pointing at an ACME certificate; restart after renewals. LL-HLS needs HTTPS to work properly on Apple devices. A TLS reverse proxy in front of 8888 and 8889 also works; list it in hlsTrustedProxies and webrtcTrustedProxies.
  • Ban repeat offenders. The authentication docs include a fail2ban filter for failed logins. DDoS protection is included on every Noded VPS; it stops floods, not weak passwords.

Where one VPS stops being the answer

  • No GPU. None of our VPS plans has one, so a multi-rendition bitrate ladder encoded on the server is the wrong job for this box.
  • Not a CDN. This is one origin in one city. For thousands of viewers, put a CDN in front of the HLS output — MediaMTX has an hlsCDNSecret setting to recognise its requests — or add read replicas behind a load balancer. WebRTC cannot be cached, so sub-second delivery at scale means more servers.
  • Disk. The largest disk a VPS can carry is 270 GB: 120 GB on the biggest shape plus three 50 GB add-ons at €4 a month each. A 6 Mbps recording grows about 2.7 GB an hour — roughly 100 hours, minus the OS. recordDeleteAfter defaults to one day; set it deliberately.
  • Unmanaged. You patch it, rotate the secrets and watch it during the event.

How Noded Can Help

Test the config first: an hourly VPS II from the VPS page is €0.0083 an hour in Bucharest, so an evening with OBS and a camera costs about four cents. Hourly machines need €5 of account credit and bill until destroyed, not merely powered off. If your audience fits under the shaped rate, run a standard shape monthly; if not, move to the media server line with the same config. For a second opinion before an event, open a ticket.

FAQ

What ports does MediaMTX use?

By default 8554/tcp for RTSP, 1935/tcp for RTMP, 8888/tcp for HLS, 8889/tcp plus 8189/udp for WebRTC, 8890/udp for SRT and 8892–8893 for Media-over-QUIC. The API (9997) and metrics (9998) are off by default.

Can MediaMTX convert RTSP to WebRTC?

Yes: pull or publish an RTSP stream into a path and open it on port 8889 in a browser. Use H.264 without B-frames and Opus or G.711 audio, because MediaMTX repackages streams but does not transcode them.

How much bandwidth does a MediaMTX server need?

Bitrate times concurrent viewers, plus forwarded copies, plus about 20% headroom. Twenty viewers of a 6 Mbps stream need about 144 Mbps, which fits a VPS III; past roughly 30 viewers the unshaped media server plans are the cheaper fit.

Why does my WebRTC stream not play from a VPS?

Usually 8189/udp is closed or the server advertises the wrong address. Open it, set webrtcAdditionalHosts to the public IP, and enable webrtcLocalTCPAddress for networks that block UDP.

← All posts

Related services

Run this on NODED.CLOUD.

Keep reading

More from the NOC.

04 Aug 2026·Mario Marin

SRT Ingest Server Hosting

RTMP falls apart on unstable contribution feeds. Here's when SRT ingest wins, the latency numbers that matter, and how to stand up an SRT gateway with MediaMTX or MistServer on a full-root streaming VPS.

Read post
19 Aug 2026·Mario Marin

Remote Access to Home Assistant via a VPS

Port forwarding exposes your router, and Nabu Casa or Cloudflare Tunnel hand your traffic to someone else's edge. Here's how to run your own WireGuard relay on a cheap VPS instead, and keep the keys to your own Home Assistant remote access.

Read post

Like the way we run things? Spin up a server in 60 seconds.