Skip to content

WCS in Docker

WCS 5.3 was successfully tested and can be used in Docker with official Docker image since build 5.3.96. The image is based on Ubuntu 24.04 and includes OpenJDK 21.0.2 to run WCS.

Docker deployment example

Do the following steps to deploy the simple WebRTC streaming server in Docker container:

1. Pull the latest WCS image from Docker Hub

sudo docker pull flashphoner/webcallserver:5.3-latest

2. Set up docker bridge network

sudo docker network create \
 --subnet 192.168.1.1/24 \
 --gateway=192.168.1.1 \
 --driver=bridge \
 --opt com.docker.network.bridge.name=br-testnet testnet

3. Start WCS docker container with your own trial or commercial license number

docker run \
-e PASSWORD=password \
-e LICENSE=license_number \
-e LOCAL_IP=192.168.1.10 \
--net testnet --ip 192.168.1.10 \
--name wcs-docker-test --rm -d flashphoner/webcallserver:5.3-latest

4. Check if the container available by SSH

ssh root@192.168.1.10

5. Open Two Way Streaming example in local browser, publish a stream

6. Close the page, stop the container

sudo docker stop wcs-docker-test

License will be deactivated on container stop to prevent unnecessary billing.

Docker container configuration

Networking issues

By default, IP address will be set dynamically to the container. So if you suppose to use fixed IP address, you should set it with docker run options and pass to the container using LOCAL_IP variable:

docker run -e LICENSE=license_number -e PASSWORD=secret \
 -e LOCAL_IP=static_ip \
 --net your-docker-network \
 --ip static_ip \
 --name webcallserver-instance -d webcallserver:5.3-latest

If your docker host is behind NAT, and your WCS is supposed to be available from outside, you should set external IP address to EXTERNAL_IP variable:

docker run -e LICENSE=license_number -e PASSWORD=secret \
 -e LOCAL_IP=static_ip \
 -e EXTERNAL_IP=external_ip \
 --net your-docker-network \
 --ip static_ip \
 --name webcallserver-instance -d webcallserver:5.3-latest

Dynamic IP address detection issues

When IP address should be set dynamically to the container, and the container has more than one network interface (this can happen for example when docker host interfaces are used), IP address to bind WCS server should be chosen manually while the container is launching. In this case, the container should be started in interactive mode

docker run \
-e PASSWORD=password \
-e LICENSE=license_number \
--net host \
--name wcs-docker-test --rm -it flashphoner/webcallserver:5.3-latest

Container enrty point script detects all the IP addresses and asks to enter the address for WCS to bind to

The address chosen will be written to ip_local parameter, for example

ip_local=172.17.0.1

Environment variables reference

The following environment variables can be passed to the container:

  • PASSWORD - SSH password to access the container. If this variable is not defined, container will not be accessible by SSH using password
  • LICENSE - Web Call Server license number. If this variable is not defined, license can be entered on first web interface logon
  • LOCAL_IP - local IP address to set to ip_local parameter in flashphoner.properties configuration file. If this variable is not defined, container IP address will be detected automatically
  • EXTERNAL_IP - external IP address to set to ip parameter in flashphoner.properties configuration file. If this variable is not defined and LOCAL_IP is not defined, external IP address will be detected automatically.
  • CDN_ROLE - container role in CDN. If this variable is not defined, container will act as standalone server
  • CDN_ENTRY_POINT - CDN entry point server address for the container. If this variable is not defined, CDN entry point will not be set
  • CDN_GROUPS - CDN groups to which the container should belong. If this variable is not defined, the container will not belong to any CDN group
  • WCS_FD_LIMIT - a maximum file descriptors available to the WCS process (since 5.3.96)
  • USE_JEMALLOC=true - to use jemalloc memory allocation library (since 5.3.96)
  • SSH_PORT - SSH port to access the container (since 5.3.96). May be useful to set a non-standard SSH port when container is running in the host network --net host

Volumes reference

The following docker volumes can be mounted to the container

  • /conf - additional configuration files folder, the path starts from container root. This volume can be mounted as read-only. The files from the folder are copied into the container
  • /usr/local/FlashphonerWebCallServer/hls - HLS segments folder. This volume must be mounted with write access
  • /usr/local/FlashphonerWebCallServer/logs - logging folder. This volume must be mounted with write access
  • /usr/local/FlashphonerWebCallServer/media - media files for VOD playback folder. This volume can be mounted as read-only. This volume can be shared with another Web Call Server instances
  • /usr/local/FlashphonerWebCallServer/records - stream recoding files folder. This volume must be mounted with write access. This volume can be shared with another Web Call Server instances
  • /usr/local/FlashphonerWebCallServer/conf - WCS configuration folder (since 5.3.96). This volume must be mounted with write access
  • /usr/local/FlashphonerWebCallServer/report - WCS support reports collection folder (since 5.3.96). This volume must be mounted with write access
  • /usr/local/FlashphonerWebCallServer/snapshots - temporary snapshot files storage folder (since 5.3.96). This volume must be mounted with write access

The container launch example with all the volumes mounted:

docker run -e LICENSE=license_number -e CDN_ROLE=origin \
 -v /opt/wcs/conf:/usr/local/FlashphonerWebCallServer/conf \
 -v /opt/wcs/logs:/usr/local/FlashphonerWebCallServer/logs \
 -v /opt/wcs/hls:/usr/local/FlashphonerWebCallServer/hls \
 -v /opt/wcs/media:/usr/local/FlashphonerWebCallServer/media \
 -v /opt/wcs/records:/usr/local/FlashphonerWebCallServer/records \
 -v /opt/wcs/report:/usr/local/FlashphonerWebCallServer/report \
 -v /opt/wcs/snapshots:/usr/local/FlashphonerWebCallServer/snapshots \
 --name webcallserver-instance -d webcallserver:5.3-latest

Do not mount a separate files from the folder /usr/local/FlashphonerWebCallServer/conf as volumes!

For example, this is not allowed:

docker run -e LICENSE=license_number -e PASSWORD=secret \
 -v /opt/wcs/conf/flashphoner.properties:/usr/local/FlashphonerWebCallServer/conf/flashphoner.properties \
 --name webcallserver-instance -d webcallserver:5.3-latest

Additional instance configuration

A legacy way using a limited set of configuration files

The following additional configuration files can be placed to the host folder mounted as /conf volume:

  • id_rsa.pub - public SSH access key. If this file is found during the container start, the container will be accessible with corresponding private key. Otherwise, if PASSWORD variable is defined, the container will be accesible by password. If neiher key, nor password are defined, SSH daemon will not be started
  • flashphoner.properties - main server configuration file. It can be used for detailed Web Call Server instance configuration
  • wcs-core.properties - Java configuration file. It can be used for memory tuning and JMC connection configuration
  • log4j.properties - logging configuration file
  • wss.jks - SSL certificates key storage file. This file can be prepared with keytool
  • cdn_profiles.yml - CDN transcoding profiles configuration file
  • database.yml - user accounts and REST hook applications configuration
  • *.sdp - SDP settings files

All those files can be used for example to restore Web Call Server instance configuration from backup and automatic deployment. The files will be copied to the container 'as is', except flashphoner.properties:

  • ip and ip_local parameters will be changed (see IP_LOCAL variable description above)
  • if CDN_ROLE variable is set, but the file contains no CDN settings, the default settings will be added

Mount configuration folder

Since build 5.3.96 the configuration folder may be mounted as volume

docker run -e LICENSE=license_number -e PASSWORD=secret \
 -v /opt/wcs/conf:/usr/local/FlashphonerWebCallServer/conf \
 --name webcallserver-instance -d webcallserver:5.3-latest

A minimal set of custom files may be placed to the mounted folder before the first container start, for example

database.yml
flashphoner.properties
log4j.properties
wcs-core.properties
wss.jks

When container starts, it will copy all the needed configuration files to the folder if they not exists

Container ports

The following ports are available by default:

  • 22/tcp - SSH (this port is active only if password or key access is set)
  • 554/tcp - RTSP server port
  • 1935/tcp - RTMP server port
  • 1935/udp - RTMFP server port
  • 2001/tcp - server CLI port
  • 7777/tcp - server monitoring port
  • 8080-8084/tcp - WS, HTTP, CDN ports
  • 8443-8445/tcp - WSS, HTTPS ports
  • 8888/tcp - HTTPS port (for older versions compatibility)
  • 9091/tcp - HTTP port (for older versions compatibility)
  • 30000-35000/tcp - TCP media ports
  • 30000-35000/udp - UDP media ports
  • 50999/tcp - JMX port

The ports can be changed using docker run --expose parameters if necessary. In this case, the actual port values should be set to flashphoner.properties and wcs-core.properties files, see description above

Building a custom Docker image based on WCS

Sometimes the official image features is not enough out of the box, and a custom image should be built for testing or production purposes. For example, let's build the custom Docker image based on WCS with the following additional features:

  • a custom on_record_hook.sh script

1. Prepare the following Dockerfile

FROM flashphoner/webcallserver:5.3-latest
COPY on_record_hook.sh /usr/local/FlashphonerWebCallServer/bin/on_record_hook.sh
RUN chmod +x /usr/local/FlashphonerWebCallServer/bin/on_record_hook.sh

2. Prepare the example on_record_hook.sh script and place it near th Dockerfile

# This script logs a stream name and a recording file name to records.log file
STREAM_NAME=$1
FILE_NAME=$2

echo "Hello, I'm recording from docker" >> /usr/local/FlashphonerWebCallServer/logs/records.log
echo $STREAM_NAME >> /usr/local/FlashphonerWebCallServer/logs/records.log
echo $FILE_NAME >> /usr/local/FlashphonerWebCallServer/logs/records.log

3. Build the custom image named wcs-custom-image

sudo docker build -t wcs-custom-image .

4. All done! You can run a container from the custom image, for example

sudo docker network create \
 --subnet 192.168.1.1/24 \
 --gateway=192.168.1.1 \
 --driver=bridge \
 --opt com.docker.network.bridge.name=br-testnet testnet
sudo chmod -R og+w /opt/wcs/logs /opt/wcs/records /opt/wcs/conf
docker run \
 -e PASSWORD=password \
 -e LICENSE=license_number \
 -e LOCAL_IP=192.168.1.10 \
 -v /opt/wcs/logs:/usr/local/FlashphonerWebCallServer/logs \
 -v /opt/wcs/records:/usr/local/FlashphonerWebCallServer/records \
 -v /opt/wcs/conf:/usr/local/FlashphonerWebCallServer/conf
 --net testnet --ip 192.168.1.10 \
 --name wcs-docker-test --rm -d wcs-custom-image:latest

Known issues

1. Open files limit cannot be changed from inside container

Symptoms

The following message is displaying when container starts in interactive mode

ulimit: open files: cannot modify limit: Operation not permitted

Solution

Set open files limit in container parameters when launching it

docker run --ulimit nofile=100000:100000 \
-e LICENSE=license_number -e PASSWORD=secret -e WCS_FD_LIMIT=100000 \
--name webcallserver-instance --rm webcallserver:5.3-latest

Symptoms

WCS container is running but not available via SSH, HTTP/HTTPS, or WebRTC connection is not establishing when container is deployed in Docker on Windows

Solution

Use Docker on Linux, or launch WCS in WSL 2