Media Relay
    RTSP / RTMP / WebRTC

    Deploy MediaMTX on a VPS

    Self-host MediaMTX, a lightweight RTSP, RTMP, HLS, WebRTC, and SRT media relay, on a RamNode VPS with systemd and optional Nginx TLS.

    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

    shell
    sudo apt update && sudo apt upgrade -y
    sudo apt install -y curl wget tar ufw

    Create a dedicated user:

    shell
    sudo adduser --disabled-password --gecos "" mediamtx

    2. Download and install MediaMTX

    Check the latest release and grab the appropriate archive (example uses linux amd64 — swap the version/arch as needed):

    shell
    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/mediamtx

    3. Configure firewall

    MediaMTX's default ports (open only the protocols you actually use):

    PortProtocol
    8554/tcpRTSP
    1935/tcpRTMP
    8888/tcpHLS (HTTP)
    8889/tcpWebRTC (HTTP)
    8189/udpWebRTC/ICE
    8890/udpSRT
    shell
    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 enable

    Skip any row for a protocol you won't use.

    4. Basic configuration

    Edit /opt/mediamtx/mediamtx.yml. Key settings to review:

    shell
    # 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

    shell
    sudo nano /etc/systemd/system/mediamtx.service
    shell
    [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.target
    shell
    sudo systemctl daemon-reload
    sudo systemctl enable --now mediamtx
    sudo systemctl status mediamtx

    6. Test ingest and playback

    Publish a test stream with ffmpeg from any machine:

    shell
    ffmpeg -re -i test.mp4 -c copy -f rtsp rtsp://publisher:CHANGE_ME_STRONG_PASSWORD@your-vps-ip:8554/mystream

    Play it back:

    shell
    # RTSP
    ffplay rtsp://your-vps-ip:8554/mystream
    
    # HLS (in a browser)
    http://your-vps-ip:8888/mystream/index.m3u8

    7. 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:

    shell
    sudo apt install -y nginx certbot python3-certbot-nginx

    /etc/nginx/sites-available/mediamtx:

    shell
    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";
        }
    }
    shell
    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.com

    Note: 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 mediamtx binary in /opt/mediamtx/, keep your existing mediamtx.yml, then sudo systemctl restart mediamtx
    • Config reload without restart: MediaMTX supports hot-reloading — send sudo systemctl reload mediamtx if configured, otherwise a full restart is safe since it's stateless

    Troubleshooting

    SymptomCheck
    Can't publishCredentials in mediamtx.yml, firewall port for the protocol you're using
    Playback works locally but not remotelyFirewall/UDP ports for WebRTC, or NAT/ICE candidate config if VPS has a private+public IP setup
    High CPUMediaMTX itself doesn't transcode by default (pure relay) — high CPU usually means you've configured runOnDemand transcoding via ffmpeg in the paths config