[Howto] Audio (via Pulseaudio) inside Container

Usecase:
If you want to hear audio from applications running inside your container.

Use the host’s Pulseserver.

We have two methods for this:
a. Use the Pulseaudio socket directly
b. Use the Pulseaudio network module

I always use method b, because somehow method a does not work reliable for me, but I encourage you to try method a first.


Method a - Pulseaudio socket:

  1. Add the Pulsesocket as unix-proxy device to your container:
    Notes:

    • The below example assumes that both (main) users (on host and inside container) have the uid and gid 1000.
      You can check this with id username.
    • Adjust the paths and uids/gids according to the distributions you use.

    Config:

     PulseSocket1:
         bind: container
         connect: unix:/run/user/1000/pulse/native
         listen: unix:/home/user/pulse-socket
         security.gid: "1000"
         security.uid: "1000"
         uid: "1000"
         gid: "1000"
         mode: "0777"
         type: proxy
    
  2. Add Pulseserver environment variable:
    a) As @stgraber suggested below, you can apply environment.PULSE_SERVER: unix:/home/user/pulse-socket 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=unix:/home/user/pulse-socket

  3. 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.


Method b - Pulseaudio Network module:

  1. Add this line to etc/pulse/default.pa or ~/.pulse/default.pa (or similar, look at your distributions documentation):
    This will allow access over 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: https://www.freedesktop.org/wiki/Software/PulseAudio/Documentation/User/Network/#index1h4

    load-module module-native-protocol-tcp auth-ip-acl=127.0.0.1
    
  2. Add a tcp-proxy device to your container:

     devices:
       Pulseovernetwork:
         bind: container
         connect: tcp:127.0.0.1:4713
         listen: tcp:127.0.0.1:4713
         type: proxy
    
  3. 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

  4. You might need to configure your firewall (on host) to allow access for tcp port 4713.

  5. 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
    • 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):

1 Like

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.

Ok :+1: , I added this option to the text.