Add Pulseserver environment variable:
Either:
a) As @stgraber suggested below, you can apply environment.PULSE_SERVER: unix:/home/username/pulse-socket to your container configuration or profile (under config:).
or:
b) add the following line to .bashrc (inside the home folder of your main user inside the container):
Now reload the .bashrc file with source .bashrc or restart the container and you should be able to start applications and hear their sound.
Method b - Pulseaudio Network module:
Add this line to etc/pulse/default.pa or ~/.pulse/default.pa (or similar, look at your distributions documentation):
This will allow access over the network, but only from the IP 127.0.0.1 (which is only your computer).
As an Alternative you can also use cookie authentication, see: Network Setup – PulseAudio
Add Pulseserver environment variable:
a) As @stgraber suggested below, you can apply environment.PULSE_SERVER: tcp:127.0.0.1:4713 to your container configuration or profile (under config:).
b) Or add the following line to .bashrc (inside the home folder of your main user inside the container): export PULSE_SERVER=tcp:127.0.0.1:4713
You might need to configure your firewall (on host) to allow access for tcp port 4713.
See General Steps below.
Now reload the .bashrc with source .bashrc or restart the container and you should be able to start applications and hear their sound.
General Steps (for all methods):
Install the following audio software inside your container:
pulseaudio or pipewire-pulse (in case you use pipewire)
pulseaudio-alsa (this is sometimes (e.g. in Debian) included in alsa-plugins (deb-package: libasound2-plugins))
32bit versions of pulseaudio and alsa for compatibility with 32bit applications.
The software packages might have different names in your distributions, look at their documentation and wikis for help or search in the software repos.
Control loudness etc.:
You should be able to control the loudness of applications in your host’s pulseaudio control interface.
Todo:
Security: What are implications on host and container seperation?
Can pulseaudio clients listen to other clients and can this be prevented?
Other methods: Are there other methods?
Credits:
Thx to simos for describing method a in his blog (with focus on Ubuntu though):
If you mostly care about lxc exec, you can set env variables through the environment.PULSE_SERVER config key. Those will be applied to all lxc exec sessions automatically.
You can manually put extra entries in the profile using raw.apparmor in the LXD config.
Is there more context on that DENIED log entry? Normally I’d expect apparmor to complain about exact paths rather than just connect and a profile name.
Thanks for the guide.
Sorry for the necrobump …
I struggled with this, and also added binding for pipewire itself, so I wrote a note to myself … and others:
It does work with “GUI apps”.
I needed it for running google-chrome in a container.
(Don’t want google backdooring my host).
The disk-approach seems rather complicated - and x11 + pulseaudio works fine for me.
I use X11 with this profile:
(In another container on Fedora 38)
When I experimented with Wayland, one thing I noticed is that adding environment.WAYLAND_DISPLAY: <path> to a profile didn’t work. You may need to add wayland socket path to your container’s user .profile file: export WAYLAND_DISPLAY=<path>
And thanks for pipewire socket stuff, I’ll add this to my gui profile.
There are several ways to get a shell into an Incus container.
When I investigated those different ways some time ago, I noticed that in some cases the environment variables that are set by Incus, are being cleared (not carried on) by the login scripts of the container.
There’s no single way to get a shell into an Incus instance, and this is why the results vary.
When I set environment.DISPLAY: in a profile, it’s being propagated perfectly well, but for some reason environment.WAYLAND_DISPLAY: is not. I never figured out why certain environment variables are ignored.