Skip to content

11. Architecture Details

This document explains the internal architecture of docker-rtmp-multistream and how it processes and distributes streams.

11.1 Overview

docker-rtmp-multistream is built on nginx with the RTMP module. It receives a single RTMP stream from your streaming software and simultaneously distributes it to multiple destinations with optional per-service transformations.

11.2 Core Components

11.2.1 nginx RTMP Module

The foundation is nginx-mod-rtmp, which provides RTMP server capabilities to nginx. This module handles:

  • Receiving RTMP streams on port 1935
  • Managing multiple RTMP applications
  • Pushing streams to multiple destinations
  • Recording streams to disk
  • Executing FFmpeg transformers

11.2.2 Service-Based Architecture

Each streaming destination (service) consists of modular components:

  1. RTMP Application Config - build/conf/nginx/http.d/apps/{service}.conf
  2. Optional Transformer - build/conf/nginx/http.d/transformers/{service}.conf
  3. Pre-init Script - build/scripts/pre-init.d/90_configure_{service}.sh
  4. Environment Variables - Configures the service and its behavior. Defined in Dockerfile and can be overridden in env/relay.env

Services are enabled/disabled dynamically at container startup based on configuration.

11.3 Stream Flow

11.3.1 High-Level Flow

Streaming Software (OBS)
    RTMP Stream (port 1935)
    relay application
    ┌────┴────┬────────┬──────────┐
    ↓         ↓        ↓          ↓
  Twitch  YouTube  Archive    [Other]
  (trans)  (relay)  (record)

11.3.2 Detailed Request Flow

  1. Stream Reception: Your streaming software connects to rtmp://localhostname:1935/relay/{stream-key}
  2. Application Routing: The relay application receives the stream
  3. Authorization: IP-based authentication checks PUBLISH_IP_RANGE
  4. Service Processing:
  5. Simple Relay Services (YouTube, Twitch partner mode): Stream pushed directly to destination
  6. Transformer Services (Twitch non-partner mode): Stream passed through FFmpeg, then pushed to destination
  7. Archive Service: Stream recorded to local disk

11.4 Service Patterns

docker-rtmp-multistream supports two architectural patterns for handling streams: Simple Relay and Transformer.

For a complete comparison of these patterns (use cases, pros/cons, and examples), see Service Patterns Reference.

11.4.1 Technical Implementation

Simple Relay (e.g., YouTube): Single apps/{service}.conf file that pushes the stream directly to the destination without modification.

Transformer (e.g., Twitch non-partner mode): Two-stage pipeline using transformers/{service}.conf (FFmpeg) and apps/{service}.conf (destination push).

Conditional Patterns

Some services support both patterns based on configuration. Twitch uses simple relay for partners (TWITCH_PARTNER=TRUE) and transformer for non-partners. See Twitch Configuration.

11.5 Configuration System

11.5.1 Startup Flow

When the container starts, configuration happens in this order:

1. Docker starts container
2. Environment variables loaded from env/relay.env
3. Pre-init scripts run (alphanumeric order):
   a. 89_configure_app.sh - Configure main relay app
   b. 90_configure_*.sh - Each service checks config
4. Service scripts:
   - Check if required env vars are set
   - Exit if service shouldn't be enabled
   - Use sed to replace placeholders in config
   - Call enableService.sh to activate
5. nginx starts with active services

11.5.2 Configuration Files

Main Configuration: - nginx.conf - Loads RTMP module, includes app.conf - app.conf - Defines relay application, commented service includes - auth.conf - IP-based publish authentication

Service Configurations: - apps/*.conf - Individual service RTMP applications - transformers/*.conf - FFmpeg transcoding pipelines

11.5.3 Dynamic Service Enabling

Services are commented out in app.conf by default:

# Service: Twitch
# include /etc/nginx/http.d/transformers/twitch.conf;
# include /etc/nginx/http.d/apps/twitch.conf;

The enableService.sh script uncomments these lines when a service is configured:

/scripts/enableService.sh twitch

Result:

# Service: Twitch
include /etc/nginx/http.d/transformers/twitch.conf;
include /etc/nginx/http.d/apps/twitch.conf;

11.6 Environment Variable Processing

11.6.1 Template Variables

Configuration files use placeholder variables (e.g., {TWITCH_KEY}) that are replaced at startup:

In config file:

push rtmp://live-jfk.twitch.tv/app/{TWITCH_KEY};

Pre-init script:

sed -i "s#{TWITCH_KEY}#$TWITCH_KEY#g" /path/to/twitch.conf

After processing:

push rtmp://live-jfk.twitch.tv/app/live_123456789_abc;

11.6.2 Layered Defaults

  1. Dockerfile - Hardcoded defaults for all variables
  2. env/relay.env - User overrides
  3. docker-compose.yml - Can override env file (not recommended)

11.7 Security

11.7.1 IP-Based Authentication

The PUBLISH_IP_RANGE variable restricts who can publish streams:

# In auth.conf
allow publish {PUBLISH_IP_RANGE};
deny publish all;

Default: 192.168.0.0/16 (local network only)

11.7.2 Stream Keys

Service stream keys are: - Stored in env/relay.env (not committed to git) - Injected into config at runtime - Never logged or exposed

11.8 Archive Service

The Archive service modifies the main relay application rather than creating a separate app:

application relay {
    live on;
    record all;
    record_path {ARCHIVE_PATH};
    record_suffix _{ARCHIVE_SUFFIX};
    # ... transformer and push directives
}

This ensures all incoming streams are archived regardless of destination.

11.9 See Also