Stream VLC multicast from a container and listen to frmo clients in the host network

I have this VLC command that works fine running on a Ubuntu physical host (a laptop) that also happnes to be the Docker Engine/Desktop host/server.

cvlc --loop song1.mp3 --sout “#rtp{dst=239.255.0.1,port=5000,mux=ts}” --no-sout-all --sout-keep --ttl 64

I am able to listen to this stream from an iPhone, Android, the server itself and other computers.

I want to bring this into a docker container. I need to figure out how to let the dst=239.255.0.1,port=5000 traffic out of the container and be listened to by other computers/clients.

I’ve already been able to do it with http but I need it to work with multicast/rtp.

Here’s my dockerfile, entrypoint (witht eh VLC command) and the container run script for the HHTP solution.

DOCKERFILE:

FROM ubuntu:22.04

Set environment variables to avoid interactive prompts

ENV DEBIAN_FRONTEND=noninteractive
ENV TZ=America/Cancun
ENV ROOT_PASSWORD=placehodlerpwdforroot
ENV VLCUSER_PASSWORD=placeholderpwdforvlcuser

Update package list and install required packages including specific versions for OpenSSH, VLC, cron, and tzdata

RUN apt-get update &&
apt-get install -y --no-install-recommends
openssh-server=1:8.9p1-3
openssh-client=1:8.9p1-3
openssh-sftp-server=1:8.9p1-3
vlc=3.0.16-1build7
cron=3.0pl1-137ubuntu3
tzdata=2022a-0ubuntu1
sudo
nano &&
ln -sf /usr/share/zoneinfo/$TZ /etc/localtime &&
echo “$TZ” > /etc/timezone &&
dpkg-reconfigure -f noninteractive tzdata &&
apt-get clean &&
rm -rf /var/lib/apt/lists/*

Create the user “vlcuser” with password set via environment variable and give root permissions

RUN useradd -m -s /bin/bash vlcuser &&
echo “vlcuser:$VLCUSER_PASSWORD” | chpasswd &&
usermod -aG sudo vlcuser

Set password for the root user via environment variable

RUN echo “root:$ROOT_PASSWORD” | chpasswd

Allow password authentication for SSH and disable root login

RUN sed -i ‘s/#PasswordAuthentication yes/PasswordAuthentication yes/’ /etc/ssh/sshd_config &&
sed -i ‘s/PermitRootLogin prohibit-password/PermitRootLogin no/’ /etc/ssh/sshd_config &&
sed -i ‘s/#PubkeyAuthentication yes/PubkeyAuthentication yes/’ /etc/ssh/sshd_config

Set up SSH key authentication for vlcuser

RUN mkdir -p /home/vlcuser/.ssh &&
chown -R vlcuser:vlcuser /home/vlcuser/.ssh &&
chmod 700 /home/vlcuser/.ssh

This is where the public key should be added.

COPY id_rsa.pub /home/vlcuser/.ssh/authorized_keys

Set permissions for the authorized_keys file

RUN chmod 600 /home/vlcuser/.ssh/authorized_keys &&
chown vlcuser:vlcuser /home/vlcuser/.ssh/authorized_keys

Create the privilege separation directory for SSH

RUN mkdir -p /run/sshd

Create a mount point for the Windows-hosted directory

RUN mkdir -p /mnt/musicstore

Expose ports

EXPOSE 22
EXPOSE 8080
EXPOSE 1234

Copy the entrypoint script into the container

COPY entrypoint.sh /entrypoint.sh

Set the appropriate permissions to make it editable

RUN chmod +x /entrypoint.sh &&
chmod 755 /entrypoint.sh

Set the entrypoint to the script

ENTRYPOINT [“/bin/bash”, “/entrypoint.sh”]
CMD

ENTRYPOINT:

#!/bin/sh

Start SSH service

/usr/sbin/sshd

Set the playlist to the environment variable, or use a default

PLAYLIST=${PLAYLIST_FILE:-/mnt/musicstore/newPlaylist.m3u}

Check if the playlist file exists

if [ ! -f “$PLAYLIST” ]; then
echo “Error: Playlist file ‘$PLAYLIST’ not found!”
exit 1
fi

Check if ROOT_PASSWORD and VLCUSER_PASSWORD are set and update accordingly

if [ ! -z “$ROOT_PASSWORD” ]; then
echo “root:$ROOT_PASSWORD” | chpasswd
fi

if [ ! -z “$VLCUSER_PASSWORD” ]; then
echo “vlcuser:$VLCUSER_PASSWORD” | chpasswd
fi

Ensure the password for vlcuser is updated by adding it to the user account

Before running the VLC command as vlcuser, ensure password change is reflected

su - vlcuser -c “echo ‘Password for vlcuser has been set correctly’”

Run VLC as vlcuser with the specified playlist

su - vlcuser -c “cvlc --no-audio --no-dbus --intf rc --rc-host=:1234 --loop $PLAYLIST --sout ‘#http{mux=ts,dst=:8080/stream}’ --sout-keep”

Keep the container running by tailing /dev/null (so the container doesn’t exit)

tail -f /dev/null

CONTAINER RUN:

docker run -d --name playlistSalsa -p 2221:22 -p 8081:8080 -p 1231:1234 -v “/home/docker-host/Music:/mnt/musicstore” -e PLAYLIST_FILE=/mnt/musicstore/playlistSalsa.m3u -e ROOT_PASSWORD=rootSalsa -e VLCUSER_PASSWORD=vlcuserSalsa streamer-http

This will only work with docker-ce on a Linux host if the container uses host networking or macvlan. It will not work with Docker Desktop, and not with docker-ce if the container use bridge or overlay networks.

On Linux with docker-ce, a bridge or overlay network could technically be used in combination with a udp broadcast relay running in a container using the host network or macvlan, so that the broad messages can be announced on the hosts lan. Can it be done: i guess so, Is it a good idea: not really, the other option is better.