MediaMTX (formerly rtsp-simple-server) is a lightweight, single-binary media relay/server supporting RTSP, RTMP, HLS, WebRTC, and SRT. It's commonly used to ingest a stream from one source (a camera, OBS, another server) and re-publish it in multiple protocols, or to relay/restream to other platforms.
Assumptions: Ubuntu 22.04/24.04 VPS, root/sudo access. A domain is optional here — MediaMTX is often used purely on protocol ports without an HTTP frontend, but this guide includes an optional Nginx+TLS proxy for the HLS/WebRTC HTTP endpoints.
1. Initial server prep
sudo apt update && sudo apt upgrade -y
sudo apt install -y curl wget tar ufwCreate a dedicated user:
sudo adduser --disabled-password --gecos "" mediamtx2. Download and install MediaMTX
Check the latest release and grab the appropriate archive (example uses linux amd64 — swap the version/arch as needed):
cd /tmp
MTX_VERSION="v1.9.3" # check GitHub releases for the current version
wget https://github.com/bluenviron/mediamtx/releases/download/${MTX_VERSION}/mediamtx_${MTX_VERSION}_linux_amd64.tar.gz
tar -xzf mediamtx_${MTX_VERSION}_linux_amd64.tar.gz
sudo mkdir -p /opt/mediamtx
sudo mv mediamtx /opt/mediamtx/
sudo mv mediamtx.yml /opt/mediamtx/
sudo chown -R mediamtx:mediamtx /opt/mediamtx3. Configure firewall
MediaMTX's default ports (open only the protocols you actually use):
| Port | Protocol |
|---|---|
| 8554/tcp | RTSP |
| 1935/tcp | RTMP |
| 8888/tcp | HLS (HTTP) |
| 8889/tcp | WebRTC (HTTP) |
| 8189/udp | WebRTC/ICE |
| 8890/udp | SRT |
sudo ufw allow OpenSSH
sudo ufw allow 8554/tcp
sudo ufw allow 1935/tcp
sudo ufw allow 8888/tcp
sudo ufw allow 8889/tcp
sudo ufw allow 8189/udp
sudo ufw enableSkip any row for a protocol you won't use.
4. Basic configuration
Edit /opt/mediamtx/mediamtx.yml. Key settings to review:
# Authentication - set this to lock down publishing
authInternalUsers:
- user: publisher
pass: CHANGE_ME_STRONG_PASSWORD
permissions:
- action: publish
- user: any
pass:
permissions:
- action: read # allow anonymous read/playback; remove if you want reads locked down too
# Define named paths, or leave "all" (default) to accept any stream name
paths:
all_others:For a simple relay-everything setup, the defaults work out of the box — you just need to set credentials if you don't want the ingest point open to anyone on the internet.
5. Create a systemd service
sudo nano /etc/systemd/system/mediamtx.service[Unit]
Description=MediaMTX
After=network.target
[Service]
Type=simple
User=mediamtx
WorkingDirectory=/opt/mediamtx
ExecStart=/opt/mediamtx/mediamtx /opt/mediamtx/mediamtx.yml
Restart=on-failure
RestartSec=5
LimitNOFILE=65535
[Install]
WantedBy=multi-user.targetsudo systemctl daemon-reload
sudo systemctl enable --now mediamtx
sudo systemctl status mediamtx6. Test ingest and playback
Publish a test stream with ffmpeg from any machine:
ffmpeg -re -i test.mp4 -c copy -f rtsp rtsp://publisher:CHANGE_ME_STRONG_PASSWORD@your-vps-ip:8554/mystreamPlay it back:
# RTSP
ffplay rtsp://your-vps-ip:8554/mystream
# HLS (in a browser)
http://your-vps-ip:8888/mystream/index.m3u87. Optional: HTTPS for HLS/WebRTC via Nginx
Browsers increasingly require HTTPS for WebRTC and mixed-content pages. If you want HLS/WebRTC served over TLS on a domain:
sudo apt install -y nginx certbot python3-certbot-nginx/etc/nginx/sites-available/mediamtx:
server {
listen 80;
server_name media.example.com;
location /hls/ {
proxy_pass http://127.0.0.1:8888/;
add_header Cache-Control no-cache;
}
location /webrtc/ {
proxy_pass http://127.0.0.1:8889/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}sudo ln -s /etc/nginx/sites-available/mediamtx /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
sudo certbot --nginx -d media.example.comNote: WebRTC also needs its UDP ICE port (8189/udp) reachable directly — Nginx only proxies the HTTP signaling, not the media itself.
8. Ongoing maintenance
- Logs:
journalctl -u mediamtx -f - Update: download the new release tarball, replace the
mediamtxbinary in/opt/mediamtx/, keep your existingmediamtx.yml, thensudo systemctl restart mediamtx - Config reload without restart: MediaMTX supports hot-reloading — send
sudo systemctl reload mediamtxif configured, otherwise a full restart is safe since it's stateless
Troubleshooting
| Symptom | Check |
|---|---|
| Can't publish | Credentials in mediamtx.yml, firewall port for the protocol you're using |
| Playback works locally but not remotely | Firewall/UDP ports for WebRTC, or NAT/ICE candidate config if VPS has a private+public IP setup |
| High CPU | MediaMTX itself doesn't transcode by default (pure relay) — high CPU usually means you've configured runOnDemand transcoding via ffmpeg in the paths config |
