Simple RTMP Restreamer ships as a single Docker image and is designed to run as a long-lived container managed by Docker Compose. This page covers everything you need to deploy it reliably on a Linux server or VPS, including port configuration, persistent storage, firewall rules, and putting the web UI behind a reverse proxy.

Docker Compose setup

The recommended way to run Simple RTMP Restreamer is with Docker Compose. The complete docker-compose.yml is shown below.
docker-compose.yml
services:
  restreamer:
    image: ghcr.io/kbats183/simple-rtmp-restreamer:latest
    container_name: "restreamer"
    environment:
      - BASIC_AUTH_USER=live
      - BASIC_AUTH_PASS=changeme
    volumes:
      - ./simple-rtmp-restreamer.data.json:/app/simple-rtmp-restreamer.data.json
      - ./web:/app/web
    ports:
      - "1935:1935"
      - "6070:6070"
    restart: unless-stopped
Replace changeme with a strong, unique password before deploying. The default value is public knowledge and provides no real protection.
Pull the image and start the container in the background with:
docker compose up -d

Container image

The image is published to the GitHub Container Registry:
ghcr.io/kbats183/simple-rtmp-restreamer:latest
Using latest always pulls the most recent build. To pin to a specific version for reproducible deployments, replace latest with a version tag from the package page.

Port requirements

The container exposes two TCP ports. Both must be reachable by the appropriate clients.
PortProtocolPurposeWho needs access
1935TCPRTMP ingest — your encoder connects hereYour broadcasting machine
6070TCPWeb UI and REST APIYour browser / API clients
If you run the restreamer on a different host from your encoder, make sure your encoder can reach port 1935 on the server. Likewise, any machine that will use the dashboard or API must be able to reach port 6070.

Volume mounts

The docker-compose.yml defines two volume mounts. Both are bind mounts from the host directory where you placed the compose file.

simple-rtmp-restreamer.data.json

This file stores all your stream and push target configuration. Mounting it as a bind mount means your configuration survives container restarts, image updates, and container recreation. Create the file before starting the container for the first time:
echo '[]' > simple-rtmp-restreamer.data.json
If the file does not exist on the host, Docker creates it as a directory instead of a file, which causes the container to fail on startup.

web/

The web/ directory contains the frontend assets served by the web UI. Download the web/ folder from the project repository and place it alongside your docker-compose.yml before starting the container.

Restart policy

The restart: unless-stopped policy tells Docker to restart the container automatically if it exits unexpectedly, and after a host reboot, unless you explicitly stopped it with docker compose stop. This is appropriate for a long-running production service.

Firewall configuration

Restrict access to each port based on who actually needs it.

Port 1935 (RTMP ingest)

Open this port only to the IP address of your encoding machine. If you stream from a fixed location or a specific host, use a firewall rule to allow only that source.
# Example using ufw — allow RTMP only from your encoder's IP
ufw allow from <encoder-ip> to any port 1935 proto tcp
If your encoder IP changes or you stream from multiple locations, you may need to open port 1935 more broadly, but consider the risk: anyone who can reach port 1935 and knows a stream name can send a stream.

Port 6070 (web UI and API)

Do not expose port 6070 directly to the public internet without additional protection. The dashboard controls your stream configuration, and basic auth alone may not be sufficient in high-risk environments.
For a private deployment (local network or VPN only), you can restrict port 6070 to trusted IP ranges:
# Allow dashboard access only from your local network
ufw allow from 192.168.1.0/24 to any port 6070 proto tcp
For public access, put the web UI behind a reverse proxy and do not bind port 6070 to the public interface directly.

Reverse proxy configuration

If you want to access the dashboard over HTTPS or expose it on a standard port, put a reverse proxy such as nginx or Caddy in front of port 6070.

Caddy

Caddyfile
restreamer.example.com {
    reverse_proxy localhost:6070
}
Caddy provisions a TLS certificate automatically via Let’s Encrypt when you use a real domain name.

nginx

nginx.conf
server {
    listen 443 ssl;
    server_name restreamer.example.com;

    ssl_certificate     /etc/ssl/certs/restreamer.crt;
    ssl_certificate_key /etc/ssl/private/restreamer.key;

    location / {
        proxy_pass         http://localhost:6070;
        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;
    }
}
When using a reverse proxy, update the port binding in docker-compose.yml so port 6070 is only accessible from localhost:
docker-compose.yml
    ports:
      - "1935:1935"
      - "127.0.0.1:6070:6070"
Binding to 127.0.0.1:6070 instead of 0.0.0.0:6070 prevents Docker from bypassing ufw rules and ensures only the reverse proxy can reach the dashboard port.

Updating the container

To update to the latest image, pull the new version and recreate the container:
docker compose pull && docker compose up -d
Your configuration in simple-rtmp-restreamer.data.json is preserved because it lives on the host filesystem, not inside the container.