Search code examples
dockerubuntu-16.04audio-streamingpulseaudio

Create pulseaudio socket at system startup in Ubuntu 16.04


I'm running a docker container and I pass the pulse server environment variable to my container. The container is set to restart always policy. The container fails to run if the "pulseaudio.socket" is not present in the /tmp folder.

So to achieve my goal I added the command "pactl load-module module-native-protocol-unix socket=/tmp/pulseaudio.socket" to startup applications[the GUI program which is accessed by searcing startup programs]. This command creates a pulseaudio.socket file in the /tmp folder

This method works most of the time if the pulseaudio.socket file is created before docker starts the container. If docker starts the container before the pulseaudio.socket is created, the container fails to start.

To make sure the pulseaudio.socket is always created before docker starts the container I added the code "pactl load-module module-native-protocol-unix socket=/tmp/pulseaudio.socket" to /etc/rc.local and also tried to add it to init.d.

But adding the code to /etc/rc.local or init.d creates a pulse-PKdhtXMmr18n folder in the /tmp folder instead of the file pulseaudio.socket

How do I make sure that instead of pulse-PKdhtXMmr18n , file called pulseaudio.socket is always created ?

My main objective is to create /tmp/pulseaudio.socket file before docker starts or before docker tries to start a container with restart policy.

Or is there any way such that the docker service first checks if the pulseaudio.socket file exists and if it exists then only start the containers?

How do I do it?


Solution

  • I resolved the issue like this :

    My container has got a node script which starts the application and this application needs pulseaudio to run properly. So here is my docker run command. Notice the code in bold. That's what I modified.

    Previous command

    sudo docker run --pid=host -dit --restart unless-stopped --env PULSE_SERVER=unix:/tmp/pulseaudio.socket --env PULSE_COOKIE=/home/$USER/pulseaudio.cookie **--volume /tmp/pulseaudio.socket:/tmp/pulseaudio.socket** --volume /home/$USER/pulseaudio.client.conf:/etc/pulse/client.conf --user $(id -u):$(id -g) --privileged --net=host ubuntu bash -c "**node service.js** && tail -F anything"
    

    Current command

    sudo docker run --pid=host -dit --restart unless-stopped --env PULSE_SERVER=unix:/tmp/pulseaudio.socket --env PULSE_COOKIE=/home/$USER/pulseaudio.cookie **--volume /tmp:/tmp** --volume /home/$USER/pulseaudio.client.conf:/etc/pulse/client.conf --user $(id -u):$(id -g) --privileged --net=host ubuntu bash -c "**sh checksocket.sh** && tail -F anything"
    

    In the previous command , the container used to start only if there was a pulseaudio.socket file in the /tmp folder of host.

    Now the current working command mounts --volume /tmp:/tmp instead of --volume /tmp/pulseaudio.socket:/tmp/pulseaudio.socket

    and sh checksocket.sh command executes the checksocket.sh file that I created inside the container.

    Here is the code of my checksocket.sh file :

    #!/bin/bash
    while sleep 0.5;
    do if [ -e /tmp/pulseaudio.socket ]
      then
        value="node service.js"
        exec $value
        break
      fi
    done
    

    This shell script keeps checking for the pulseaudio.socket file in the mounted /tmp folder and if it exists then only it starts my node service.

    In this way my container always starts whenever I reboot my machine and the node service starts once the shell script detect a pulseaudio.socket in the /tmp folder.

    I hope this helps someone who are trying to use pulseaudio with docker for the purpose of sound multiplexing or to avoid “device or resource busy” error(device or resource busy error comes when you use docker with alsa as alsa directly captures the sound card) on the host machine. Let me know if anybody needs more help