Skip to content

Container sound: ALSA or Pulseaudio

mviereck edited this page Nov 22, 2018 · 14 revisions

ALSA or Pulseaudio sound in docker container

This page describes three possible ways how to set up sound for docker containers without x11docker. Most common is the easy ALSA setup. A bit more advanced, but better integrating in most desktop environments is a setup with Pulseaudio.

Pulseaudio can be provided with shared unix sockets or with a TCP connection. Both ways need Pulseaudio server on host and Pulseaudio client library (debian: libpulse0) in image. x11docker supports both ways with --pulseaudio=socket or --pulseaudio=tcp.

ALSA

For ALSA sound just share sound devices with --device /dev/snd. You would not need the more advanced Pulseaudio setup, but will have trouble if more than one application tries to access the sound hardware.

  • If you can't hear sound, you might need to set environment variable --env ALSA_CARD=Generic or another card name that shows up in aplay -l.
  • To check ALSA sound in container, install alsa-utils in image and run speaker-test:
docker run --rm --device /dev/snd alsaimage speaker-test
  • Applications that only support Pulseaudio can be fooled with apulse. Example: apulse firefox sets up a fake Pulseaudio environment, but forwards the sound signals to ALSA.

Pulseaudio with shared socket

Create pulseaudio socket:

pactl load-module module-native-protocol-unix socket=/tmp/pulseaudio.socket

Create /tmp/pulseaudio.client.conf for pulseaudio clients:

default-server = unix:/tmp/pulseaudio.socket
# Prevent a server running in the container
autospawn = no
daemon-binary = /bin/true
# Prevent the use of shared memory
enable-shm = false

Share socket and config file with docker and set environment variables PULSE_SERVER and PULSE_COOKIE. Container user must be same as on host:

docker run --rm \
    --env PULSE_SERVER=unix:/tmp/pulseaudio.socket \
    --env PULSE_COOKIE=/tmp/pulseaudio.cookie \
    --volume /tmp/pulseaudio.socket:/tmp/pulseaudio.socket \
    --volume /tmp/pulseaudio.client.conf:/etc/pulse/client.conf \
    --user $(id -u):$(id -g) \
    imagename

The cookie will be created by pulseaudio itself.

Pulseaudio over TCP

Get IP address from host:

# either an arbitrary IPv4 address from host
Hostip="$(ip -4 -o a | awk '{print $4}' | cut -d/ -f1 | grep -v 127.0.0.1 | head -n1)"

# or especially IP from docker daemon
Hostip="$(ip -4 -o a| grep docker0 | awk '{print $4}' | cut -d/ -f1)"

Run docker image. You need a free TCP port, here 34567 is used. (TCP port number must be in range of cat /proc/sys/net/ipv4/ip_local_port_range and must not be in use. Check with ss -nlp | grep 34567.)

docker run --rm \
    --name pulsecontainer \
    --env PULSE_SERVER=tcp:$Hostip:34567 \
    imagename

After docker run get IP of container with:

Containerip="$(docker inspect --format '{{ .NetworkSettings.IPAddress }}' pulsecontainer)"

Load pulseaudio TCP module authenticated with container IP:

pactl load-module module-native-protocol-tcp  port=34567 auth-ip-acl=$Containerip

Be aware that the TCP module is loaded after container is up and running. It takes a moment until pulseaudio server is available for container applications. If TCP connection fails, check for possible iptables and ufw settings that might prohibit the connection.

Clone this wiki locally