mviereck / x11docker

Run GUI applications and desktops in docker and podman containers. Focus on security.
MIT License
5.62k stars 378 forks source link

--pulseaudio option not working #54

Closed ajhamwood closed 6 years ago

ajhamwood commented 6 years ago

Apologies in advance if this is a simple fix.

I'm running x11docker with

sudo ./x11docker -acpdf --hostipc --size="1920x1080" --homedir="myhomedir" --user="myuser" -- "-p 1935:1935" myimagename

(--hostipc seems to be required for using the x11grab input in ffmpeg, not sure if that's correct but it's a separate issue.)

My dockerfile extends x11docker/xfce, with the relevant lines being:

RUN sed -i "s/buster main/buster main contrib non-free/" /etc/apt/sources.list
RUN echo "deb http://http.debian.net/debian buster main contrib non-free" >> /etc/apt/sources.list
RUN apt-get update && apt-get install -y ffmpeg pulseaudio-utils pavucontrol

When I run x11docker as above, pavucontrol in the container tries unsuccessfully to connect to pulseaudio in the host, repeating every 5s.

In the container I have

$ echo $PULSE_SERVER
unix:/pulse/native

$ cat /etc/pulse/client.conf
# Connect to the host's server using the mounted UNIX socket
default-server = unix:/pulse/native
# Prevent a server running in the container
autospawn = no
daemon-binary = /bin/true
# Prevent the use of shared memory
enable-shm = false

as expected.

In the host I have

$ sudo docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                    PORTS                      NAMES
a7482c40e7de        063534af197c        "env /bin/sh - /x11d…"   27 minutes ago      Up 27 minutes             0.0.0.0:1935->1935/tcp     x11docker_X101_04c384_mycontainername
$ getent group audio video
audio:x:29:pulse
video:x:44:

$ sudo docker inspect -f '{{ .Mounts }}' a7482c40e7de
[{bind  ~~~/x11docker/myhomedir /home/myuser  rw true rprivate}\
 {bind  /tmp/.X11-unix/X101 /X101  rw true rprivate}\
 {bind  /run/user/1000/pulse /pulse  rw true rprivate}\
 {bind  /~~~/.cache/x11docker/X101-myimagename/pulseclient.conf /etc/pulse/client.conf  rw true rprivate}\
 {bind  /usr/bin/docker-init /x11docker/tini  ro false rprivate}\
 {bind  /~~~/.cache/x11docker/X101-myimagename/share /x11docker  rw true rprivate}]
$ sudo docker inspect -f '{{ .HostConfig.GroupAdd }}' a7482c40e7de
[29 44]
$ sudo docker inspect -f '{{ .HostConfig.Devices }}' a7482c40e7de
[]

I add the devices info because of the comment here, but as I expected, adding "--device /dev/snd" after -- in the x11docker args doesn't change anything.

Running pulseaudio -k in the host after the container is up doesn't change anything.

The line load-module module-native-protocol-unix is in /etc/pulse/system.pa in both host and container.

Not sure what else could be the problem...

mviereck commented 6 years ago

Thanks for reporting!

On the first glance I see one bug, not sure if that is the cause of the issue:

RUN sed -i "s/buster main/buster main contrib non-free/" /etc/apt/sources.list
RUN echo "deb http://http.debian.net/debian buster main contrib non-free" >> /etc/apt/sources.list

x11docker/xfce is based on debian stretch. With the commands above you get a mix of stretch and buster repositories, you don't replace the stretch line.

To have a clean base, rather change the Dockerfile of x11docker/xfce: Replace:

FROM debian:stretch

with:

FROM debian:buster
RUN echo "deb http://deb.debian.org/debian buster non-free contrib" >> /etc/apt/sources.list

and build again.

A first test with another pulseaudio image on my system succeeds, sound is working here.

Please try with a clean buster build again. I will check with buster, too, maybe something changed.

Edit: I did a test with debian:buster as base for x11docker/xfce and pulseaudio works (tested with mpv). Check pavucontrol in container whether it shows a valid output device and whether it is muted or not.

ajhamwood commented 6 years ago

Thanks for the quick reply!

I've rebuilt x11docker/xfce as you recommend (moving the DEBIAN_FRONTEND export to the second line), and slimmed the testing dockerfile down to

FROM local_xfce:buster
RUN apt-get update && apt-get install -y ffmpeg pulseaudio pavucontrol --no-install-recommends

However, running pavucontrol still displays "Connection to Pulseaudio failed. Automatic retry in 5s", etc.

As further information, I am running Ubuntu 18.04 with Unity in the host. Also the pulseaudio version in host and container is now the same, pulseaudio 11.1.

Something like docker run -it -v "/run/user/$UID/pulse:/run/user/1000/pulse" thebiggerguy/docker-pulseaudio-example works fine for me. Can I know what image you are using to test pa with locally?

ajhamwood commented 6 years ago

I managed to get pulseaudio working, but without being able to send sound to the host yet.

The fix was to replace --user="myuser" with --hostuser="myuser", so that the host pa server can accept connection from the container. Now pavucontrol in the container shows AudioIPC Server: AudioCallbackDriver in the Playback menu, same as in host.

After including lines

RUN apt-get install -y apt-transport-https ca-certificates curl gnupg --no-install-recommends
RUN apt-get install -y iceweasel

in the testing dockerfile, and in the container browsing to eg http://www.szynalski.com/tone-generator/ , I'm not able to hear sound as yet though. (For some reason youtube refuses to play buffered video either, but I'm sure I've just forgot to include a dependency...)

ajhamwood commented 6 years ago

After restarting, I was able to confirm streaming video + audio from the container, so that's good enough for me. Not being able to receive sound from the container was likely due to host and container being different users, but it's not an issue any more. Thanks and feel free to close this issue :)

mviereck commented 6 years ago

Good to hear you got it working! Clever that you found out the issue is due to different host user/container user, I just missed that. I will look if I find a solution for that.

Formerly I set up pulseaudio in container with a TCP connection, but switched to sharing pulseaudio unix socket due to some annoying issues with the pulseaudio TCP module. Also, sound over unix socket is more performant. Though, the TCP solution does not have issues with different users.

--hostipc seems to be required for using the x11grab input in ffmpeg, not sure if that's correct but it's a separate issue

Feel free to open a ticket for this.