├── pulse-client.conf ├── host_runner.sh ├── Dockerfile ├── LICENSE └── README.md /pulse-client.conf: -------------------------------------------------------------------------------- 1 | # Connect to the host's server using the mounted UNIX socket 2 | default-server = unix:/run/user/1000/pulse/native 3 | 4 | # Prevent a server running in the container 5 | autospawn = no 6 | daemon-binary = /bin/true 7 | 8 | # Prevent the use of shared memory 9 | enable-shm = false 10 | -------------------------------------------------------------------------------- /host_runner.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -x 4 | 5 | echo "Searching for Docker image ..." 6 | DOCKER_IMAGE_ID=$(docker images --format="{{.ID}}" docker-pulseaudio-example:latest | head -n 1) 7 | echo "Found and using ${DOCKER_IMAGE_ID}" 8 | 9 | USER_UID=$(id -u) 10 | 11 | docker run -t -i \ 12 | --volume=/run/user/${USER_UID}/pulse:/run/user/1000/pulse \ 13 | ${DOCKER_IMAGE_ID} \ 14 | ${@} 15 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:16.04 2 | MAINTAINER Guy Taylor 3 | 4 | ENV UNAME pacat 5 | 6 | RUN apt-get update \ 7 | && DEBIAN_FRONTEND=noninteractive apt-get install --yes pulseaudio-utils 8 | 9 | # Set up the user 10 | RUN export UNAME=$UNAME UID=1000 GID=1000 && \ 11 | mkdir -p "/home/${UNAME}" && \ 12 | echo "${UNAME}:x:${UID}:${GID}:${UNAME} User,,,:/home/${UNAME}:/bin/bash" >> /etc/passwd && \ 13 | echo "${UNAME}:x:${UID}:" >> /etc/group && \ 14 | mkdir -p /etc/sudoers.d && \ 15 | echo "${UNAME} ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/${UNAME} && \ 16 | chmod 0440 /etc/sudoers.d/${UNAME} && \ 17 | chown ${UID}:${GID} -R /home/${UNAME} && \ 18 | gpasswd -a ${UNAME} audio 19 | 20 | COPY pulse-client.conf /etc/pulse/client.conf 21 | 22 | USER $UNAME 23 | ENV HOME /home/pacat 24 | 25 | # run 26 | CMD ["pacat", "-vvvv", "/dev/urandom"] 27 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Docker PulseAudio Example 2 | An example of a PulseAudio app working within a Docker container using the hosts sound system 3 | 4 | [Docker Hub](https://hub.docker.com/r/thebiggerguy/docker-pulseaudio-example/) 5 | 6 | ## Building 7 | ```bash 8 | ./buid.sh 9 | ``` 10 | 11 | ## Running 12 | ```bash 13 | ./host_runner.sh 14 | ``` 15 | 16 | ## Explanation 17 | Getting a PulseAudio app to work within a Docker container is harder than it looks. This example is designed to produce the smallest working configuration that can be used in your own containers. 18 | 19 | To be clear this is designed so the app within the Docker container does not run a PulseAudio server. Instead the app connects as a client directly to the hosts PulseAudio server and uses it's configuration/devices to output the sound. This is achieved by mapping the UNIX socket used by PulseAudio in the host into the container and configuring its use. 20 | 21 | Most of the complexity of the Dockerfile is setting up a non root user. This is kept in the example as near all uses of this **should** not be running the app as root. 22 | 23 | ## Common / Known Issues 24 | 25 | ### SHM 26 | `shm_open() failed: No such file or directory` Is caused by PulseAudio trying to use Shared Memory (`/dev/shm` or `/run/shm`) as a performance enhancement. In this example SHM is disabled to prevent this issue. 27 | 28 | ### TCP / Avahi 29 | This would be another method to configure PulseAudio by enabling the host server to open an TCP server and the container connecting to it. This was avoided as it: 30 | * Unnecessarily causes the container to be networked to the host. 31 | * Requires additional PulseAudio modules and changed configuration on the host. 32 | * Is less performant. 33 | --------------------------------------------------------------------------------