Nowdays we have a Pipewire and if you want an application inside of the docker container to play / record sounds using your Pipewire server running on a host, here's what you can do:
- First of all, we obviously need to have a Pipewire server running on our host. On modern distros the Pipewire is started when systemd reaches
graphical.target
and login manager (gdm, sddm, whatever) is executed. And then, later on, when the user logs in, the Pipewire is restarted to be owned by that user.
In order for the application inside of docker container to use Pipewire, we're going to pass the socket file descriptor to that container. For that we need to know who is running the Pipewire server on your host machine. You can check that by looking under whom the pipewire processes is running and then find out what will be the proper socket file:
testuser@asrock-ubuntu:~$ ps -fp $(pgrep -d, -x pipewire)
UID PID PPID C STIME TTY TIME CMD
testuser 4250 4206 1 13:32 ? 00:00:27 /usr/bin/pipewire
testuser@asrock-ubuntu:~$ id testuser
uid=1000(testuser) gid=1000(testuser) groups=1000(testuser),4(adm),6(disk),24(cdrom),27(sudo),30(dip),46(plugdev),105(input),107(kvm),122(lpadmin),134(lxd),135(sambashare),140(libvirt),64055(libvirt-qemu),997(docker)
So in this our case, I expect there should be a socket file /run/user/1000/pipewire-0
. Go check that on your system.
- Now we are going to create a lightweight Alpine docker container, while passing that Pipewire socket file to it and setting XDG_RUNTIME_DIR variable, which is needed for Pipewire client inside of container.
docker run -it -v /run/user/1000/pipewire-0:/tmp/pipewire-0 -e XDG_RUNTIME_DIR=/tmp --rm alpine /bin/ash
- Inside of the container we install some packages into it, to make the whole thing work:
- alsa-utils - provide a set of ALSA utilities we're going to use as our example software, which needs ALSA
- pipewire - Pipewire server (and client) binaries. But we're not going to run full-fledged server in a container, not at all, we just need its client part to be there
- pipewire-alsa - introduces a virtual ALSA device "pipewire" we're going to use in our software, which requires ALSA. Simply speaking that's the bridge between ALSA and our Pipewire client
apk add pipewire-alsa pipewire alsa-utils
- Now let's test if everything works. Make sure you see "pipewire" device when you run
aplay -L
and then run our simple test to play some noise through that device:
speaker-test -Dpipewire -c2
At this point you should hear a sound coming. If it does not, check your default Pipewire sink device on your host. If you're running Gnome, open Gnome Settings -> Sound -> Output
Inside the container, we can now record a wave file with arecord and play it back with using pure ALSA tools:
arecord --duration=5 --device=pipewire test.wav
aplay --device=pipewire test.wav
- One last thing, before we go - let's also check that native pipewire clients can be executed inside of that container. For that we install
pipewire-tools
. The example wav file I'm going to play, came with alsa-utils
pacakge we installed earlier:
apk add pipewire-tools
pw-play /usr/share/sounds/alsa/Rear_Center.wav
In a nutshell, the overall setup is something like this: