Docker

Official BubbleUPnP Server multi-platform docker images based on openSUSE Tumbleweed are available on Docker Hub, for easily running BubbleUPnP Server on Linux x86_64, arm64 and armv7 plaftorms.

It provides everything needed to run BubbleUPnP Server optimally, including Java and FFmpeg binaries. GPU transcoding for Chromecast (Intel QSV, VA-API (Intel/AMD), NVIDIA) is supported on x86_64.

BubbleUPnP Server running in the container updates automatically to its latest version and to newer FFmpeg binaries, so there is no need to recreate the container for that.

The Docker image itself can sometimes be updated (in particular for newer Java version and/or fixes or new features). In that case you will need to recreate the container.

By default, this container runs BubbleUPnP Server’s java process (and ffmpeg) under an unprivileged user private to the container. To instead run it under your own user in the host, refer to the section below about this.

Choose an image #

Several images are provided:

  • bubblesoftapps/bubbleupnpserver: OpenJDK Java runtime, GPU support on x86_64
  • bubblesoftapps/bubbleupnpserver:nogpu: OpenJDK Java runtime, no GPU support, x86_64 only
  • bubblesoftapps/bubbleupnpserver-openj9: Eclipse OpenJ9 Java runtime, GPU support on x86_64, no armv7 support
  • bubblesoftapps/bubbleupnpserver-openj9:nogpu: Eclipse OpenJ9 Java runtime, no GPU support, x86_64 only

If running on arm64 or armv7 platform, pick the bubblesoftapps/bubbleupnpserver or bubblesoftapps/bubbleupnpserver-openj9 image (armv7 excluded for the latter).

If running on x86_64 platform, pick the the nogpu variant if you do not need GPU support for Chromecast video transcoding, as this variant is much smaller. Otherwise pick either variant with GPU support.

Eclipse OpenJ9 images uses less memory, making it ideal for memory constrained devices. OpenJ9 is supposedly a bit slower than OpenJDK, but for software such as BubbleUPnP Server, it does not matter. Moreover, some Synology NAS running DSM 7 may crash with the OpenJDK image and the workaround is to use the OpenJ9 image.

The rest of this document will use the bubblesoftapps/bubbleupnpserver image in examples. Replace it by the image you use.

Running and operating a basic container (no GPU transcoding) #

If your user is not already part of the docker group, you will have to prefix all docker commands with sudo. To avoid this, add you user to the docker group whit this command, then launch a new terminal to make the change effective:

sudo usermod -aG docker $USER

Create a persistent container named bubbleupnpserver from the image:

docker create --name bubbleupnpserver --net=host bubblesoftapps/bubbleupnpserver 
  • --net=host: required for proper networking and working device discovery
  • --restart=unless-stopped: optional, if you want to start the bubbleupnpserver container automatically when the docker daemon starts
  • at the end of the command-line above, you can pass BubbleUPnP Server command-line arguments

Then start the container with:

docker start bubbleupnpserver

On some older Docker versions, the container may fail to start. In that case and if you cannot update Docker to a newer version, recreate the container adding the --security-opt seccomp=unconfined option.

Connect to the web configuration with your web browser: http://localhost:58050 (from your machine) or http://<server LAN ip>:58050 (from another machine on the LAN).

to stop the container: docker stop bubbleupnpserver
to restart the container: docker restart bubbleupnpserver
to show continuously updated logs: docker logs -f bubbleupnpserver
to remove the container (for uninstalling or recreating it): docker rm -f bubbleupnpserver
to remove the image: docker rmi bubblesoftapps/bubbleupnpserver

Adding NVIDIA GPU transcoding support #

  • make sure you are using an image with GPU support
  • follow these instructions to install the NVIDIA Container Toolkit on your distro. Once done, verify that docker run --rm --runtime=nvidia --gpus all ubuntu nvidia-smi runs sucessfully before proceeding to the next step
  • add these additional options: --runtime=nvidia --gpus all:
docker create --name bubbleupnpserver --net=host --runtime=nvidia --gpus all bubblesoftapps/bubbleupnpserver 

You can test that GPU is working in the web BubbleUPnP Server configuration > Settings tab > Chromecast transcoding tab > Perform GPU transcoding test.

Adding Intel QSV and VA-API (AMD) transcoding support #

  • make sure you are using an image with GPU support
  • add the --device and --group-add options as below:
docker create --name bubbleupnpserver --net=host \
       --device /dev/dri:/dev/dri \
       --group-add $(stat -c %g /dev/dri/renderD128) \
       bubblesoftapps/bubbleupnpserver 
  • --device /dev/dri:/dev/dri: necessary to access devices in /dev/dri in the container
  • --group-add $(stat -c %g /dev/dri/renderD128): necessary for ffmpeg to have proper permission to access the /dev/dri/renderD128 device

You can test that GPU is working in the web BubbleUPnP Server configuration > Settings tab > Chromecast transcoding tab > Perform GPU transcoding test.

Adding easy access to data files (configuration, logs, …) in the host #

By default, BubbleUPnP Server runs in the container under an unprivileged user private to the container. The configuration file is not easily accessible for editing it. Log files are not easily accessible as well. And if you recreate the container you will lose the configuration and cached data.

To address these, you can run BubbleUPnP Server under your own user in the host and have the data files easily accessible in the host with a volume mount.

  • first, create a folder that your host user can write to, for storing BubbleUPnP Server’s data:
mkdir ~/bubbleupnpserver_data
  • add the -u option to set the numeric user id and group id of your host user
  • add the --volume option to mount the host data directory created above into the image at the /data location
  • add the BubbleUPnP Server -dataDir option to specify where it should look for its data directory in the container:
docker create --name bubbleupnpserver \
       --net=host \
       -u $(id -u):$(id -g) \
       --volume ~/bubbleupnpserver_data:/data \
       bubblesoftapps/bubbleupnpserver \
       -dataDir /data

With this, all the files in the ~/bubbleupnpserver_data directory will be owned by your user in the host. You can edit configuration.xml if necessary with your favorite editor (stop the container first). You can also reuse that directory if you recreate the container.

Disabling all writing to to disk #

If your Docker installation and BubbleUPnP Server container reside on a spinning hard drive and you do not want the running container to prevent the hard drive to go to sleep, there are additional options required to prevent all periodic writing to disk, both performed by Docker on the host and BubbleUPnP Server in the running container:

  • -e USER_JVM_ARGS="-XX:-UsePerfData": to pass JVM arguments to BubbleUPnP Server to disable the JVM writing performance data at regular intervals into the image’s /tmp folder. This is only needed if using the OpenJDK Docker image. This USER_JVM_ARGS environment variable is only available since the BubbleUPnP Server container released in August 2022.
  • --log-driver none: for Docker to not write to file (stored on host) BubbleUPnP Server’s console output (stdout)
  • --no-healthcheck: for Docker to not write health check status to config.v2.json file (stored on host) at periodic intervals
  • -nologfile: BubbleUPnP Server option for BubbleUPnP Server to not write log files (stored in the running container)

With everything combined (eventual other command-line options ommited):

docker create --name bubbleupnpserver \
       --net=host \
       --log-driver none \
       --no-healthcheck \
       -e USER_JVM_ARGS="-XX:-UsePerfData" \
       bubblesoftapps/bubbleupnpserver \
       -nologfile

Using Docker Compose to run BubbleUPnP Server #

  • create a directory for holding the docker-compose.yml file whose content is a the end of this paragraph.
mkdir ~/bubbleupnpserver
cd ~/bubbleupnpserver
mkdir data
  • download the docker-compose.yml file:
wget https://bubblesoftapps.com/bubbleupnpserver/docker-compose.yml
  • edit the docker-compose.yml file and uncomment sections for functionality you need. The file is heavily commented. Otherwise refer to explanations in previous paragraphs.

  • if you uncommented some features requiring it, create a .env file to define the evironmnent variables referenced in the docker-compose.yml file:

echo -e USER_UID=$(id -u):$(id -g)\\nRENDER_GROUP_UID=$(stat -c %g /dev/dri/renderD128) > .env
  • start the container:
docker-compose up -d

docker-compose.yml #

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
version: '3'
services:

  bubbleupnpserver:

# image choices: 
#
# bubblesoftapps/bubbleupnpserver: OpenJDK Java runtime, GPU support on x86_64 
# bubblesoftapps/bubbleupnpserver:nogpu: OpenJDK Java runtime, no GPU support, x86_64 only
# bubblesoftapps/bubbleupnpserver-openj9: Eclipse OpenJ9 Java runtime, GPU support on x86_64, no armv7 support
# bubblesoftapps/bubbleupnpserver-openj9:nogpu: Eclipse OpenJ9 Java runtime, no GPU support, x86_64 only 

    image: bubblesoftapps/bubbleupnpserver

    container_name: bubbleupnpserver

    # required for proper networking and device discovery to work
    network_mode: host 

    expose:
      - 1900/udp
      - 58050/tcp
      - 58051/tcp


############# OPTIONAL FEATURES ############################
    
# Support for accessing config/log/data files on the host
#
# Uncomment section below to run the container under the same user/group than the user
# running the container in the host
# This will also make BubbleUPnP Server write all its data files
# in the ./data folder on the host. This allows:
#
# - to easily edit the configuration.xml file
# - to easyly access the log files
# - to preserve configuration/data accross container runs or recreations
#
# You must add this line to an .env file in the same folder than this docker-compose file:
# echo USER_UID=$(id -u):$(id -g) >> .env
#
### START uncomment
#    command:
#      - -dataDir
#      - /data
#    user: ${USER_UID}
#    volumes:
#      - ./data:/data
### END

# Support for Intel QSV or VA-API for Chromecast transcoding
#
# This requires an image with GPU support
#
# You must add this line to an .env file in the same folder than this docker-compose file:
# echo RENDER_GROUP_UID=$(stat -c %g /dev/dri/renderD128) >> .env
#
### START uncomment
#    devices:
#      - /dev/dri:/dev/dri
#    group_add:
#      - ${RENDER_GROUP_UID} 
### END

### Support for NVIDIA GPU for Chromecast transcoding
#
# This requires an image with GPU support
# This requires the  NVIDIA Container Toolkit to be installed and working in the host
#
### START uncomment
#    deploy:
#      resources:
#        reservations:
#          devices:
#            - driver: nvidia
#              count: 1
#              capabilities: [gpu]
### END