2015-03-11 32 views
23

To pytanie jest zainspirowane przez Can you run GUI apps in a docker container?.uruchamianie aplikacji za pomocą dźwięku w pojemniku dokowania

Podstawowym założeniem jest, aby uruchomić aplikacje z dźwiękiem i ui (vlc, firefox, skype, ...)

szukałem kontenerów Docker korzystających PulseAudio ale wszystkich kontenerów znalazłem gdzie za pomocą PulseAudio przesyłanie poprzez TCP. (Sandboxing bezpieczeństwo aplikacji)

W moim przypadku chciałbym preferują odtwarzanie dźwięku z aplikacji wewnątrz pojemnika bezpośrednio do mojego hosta PulseAudio. (Bez ssh tunelowanie i nadęty obrazów Döcker)

PulseAudio ponieważ mój qt aplikacja używa go;)

Odpowiedz

21

zajęło mi trochę czasu, dopóki nie dowiedział się, co jest potrzebne. (Ubuntu)

zaczynamy polecenia uruchomienia doker docker run -ti --rm myContainer sh -c "echo run something"

ALSA:
musimy /dev/snd i jakiś dostępu do sprzętu, jak to wygląda. kiedy kładziemy to razem mamy

docker run -ti --rm \ 
    -v /dev/snd:/dev/snd \ 
    --lxc-conf='lxc.cgroup.devices.allow = c 116:* rwm' \ 
    myContainer sh -c "echo run something"` 

w nowych wersjach Döcker bez lxc flagi ty powinien użyj:

docker run -ti --rm \ 
    -v /dev/snd:/dev/snd \ 
    --privileged \ 
    myContainer sh -c "echo run something"` 

PulseAudio:
Tutaj musimy w zasadzie /dev/shm, /etc/machine-id i /run/user/$uid/pulse. Ale to nie wszystko (być może ze względu na Ubuntu i sposób, w jaki robili to w przeszłości). Zmienna środowiskowa musi być taka sama w systemie hosta i w kontenerze dokowania. Możesz także potrzebować /var/lib/dbus, ponieważ niektóre aplikacje uzyskują dostęp do identyfikatora komputera (może to być tylko dowiązanie symboliczne do "prawdziwego" identyfikatora komputera). I przynajmniej możesz potrzebować ukrytego folderu domowego ~/.pulse dla niektórych danych tymczasowych (nie jestem tego pewien).

docker run -ti --rm \ 
    -v /dev/shm:/dev/shm \ 
    -v /etc/machine-id:/etc/machine-id \ 
    -v /run/user/$uid/pulse:/run/user/$uid/pulse \ 
    -v /var/lib/dbus:/var/lib/dbus \ 
    -v ~/.pulse:/home/$dockerUsername/.pulse \ 
    myContainer sh -c "echo run something" 

W nowych wersjach Döcker może trzeba dodać --privileged.
Oczywiście można łączyć zarówno ze sobą i używać go razem z xServer ui spedycji jak tutaj: https://stackoverflow.com/a/28971413/2835523

Wystarczy wspomnieć:

  • można obsługiwać większość to (wszystko bez używane id) w dockerfile
  • użyciu uid=$(id -u) aby uzyskać identyfikator użytkownika i gid z id -g
  • tworzeniu użytkownika Döcker z tym id

utworzyć skrypt użytkownika:

mkdir -p /home/$dockerUsername && \ 
echo "$dockerUsername:x:${uid}:${gid}:$dockerUsername,,,:/home/$dockerUsername:/bin/bash" >> /etc/passwd && \ 
echo "$dockerUsername:x:${uid}:" >> /etc/group && \ 
mkdir /etc/sudoers.d && \ 
echo "$dockerUsername ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/$dockerUsername && \ 
chmod 0440 /etc/sudoers.d/$dockerUsername && \ 
chown ${uid}:${gid} -R /home/$dockerUsername 
+0

Niestety, opcja --lxc-conf został usunięty w 2014 r https://github.com/docker/docker/ pull/5797 – tudor

+0

Nie testowałem tego, ale myślę, że są zamienniki dla parametru. - uprzywilejowane, --cap-add, -cgroup-parent i --device może pracować –

+0

-v/dev/snd:/dev/snd --privileged działa! Sprawdź: https://github.com/pwasiewi/docker-freeciv-client – 42n4

3

Zainspirowany linki już napisanych, udało mi się stworzyć następujące rozwiązanie. Jest tak lekki, jak tylko mogłem go zdobyć. Jednak nie jestem pewien, czy jest (1) bezpieczny i (2) całkowicie pasuje do twojego przypadku użycia (ponieważ nadal używa sieci).

  1. Zainstaluj na swoim hoście paprefs, np. przy użyciu sudo apt-get install paprefs na komputerze z systemem Ubuntu.
  2. Uruchom Preferencje PulseAudio, przejdź do zakładki "Serwer sieciowy" i zaznacz pole "Włącz dostęp sieciowy do lokalnych urządzeń dźwiękowych" pole wyboru [1]
  3. Uruchom ponownie komputer. (Tylko restartowanie Pulseaudio nie działało dla mnie na Ubuntu 14.10)
  4. Zainstaluj Pulseaudio w swoim kontenerze, np. sudo apt-get install -y pulseaudio
  5. W swoim pojemniku uruchom export "PULSE_SERVER=tcp:<host IP address>:<host Pulseaudio port>". Na przykład export "PULSE_SERVER=tcp:172.16.86.13:4713" [2]. Możesz znaleźć swój adres IP za pomocą ifconfig i portu Pulseaudio przy użyciu pax11publish [1].
  6. To wszystko. Krok 5 powinien prawdopodobnie zostać zautomatyzowany, jeśli adres IP i port Pulseaudio mogą ulec zmianie. Ponadto nie jestem pewien, czy Docker stale przechowuje zmienne środowiskowe, takie jak PULSE_SERVER: Jeśli nie, to musisz go zainicjować po każdym uruchomieniu kontenera.

Sugestie, aby moje podejście było jeszcze lepsze, byłyby bardzo mile widziane, ponieważ obecnie pracuję nad podobnym problemem, co OP.

Odniesienia:
[1] https://github.com/jlund/docker-chrome-pulseaudio
[2] https://github.com/jlund/docker-chrome-pulseaudio/blob/master/Dockerfile

Update (i prawdopodobnie lepsze rozwiązanie)
działa również przy użyciu gniazda Unix zamiast gniazda TCP:

  1. Uruchom kontener z -v /run/user/$UID/pulse/native:/path/to/pulseaudio/socket
  2. W pojemniku uruchom export "PULSE_SERVER=unix:/path/to/pulseaudio/socket"

Numer /path/to/pulseaudio/socket może być dowolny, do celów testowych użyłem /home/user/pulse.
Może to będzie działać nawet z tą samą ścieżką, co na hoście (dbając o część $ UID) jako domyślnym gniazdem, w ten sposób ostatecznym rozwiązaniem będzie -v /run/user/$UID/pulse/native:/run/user/<UID in container>/pulse; Nie testowałem tego jednak.

+0

chodziło o to, aby działał bez zmiany ustawień regionalnych PulseAudio (i bez korzystania z połączenia sieciowego). ale dzięki za informację –

+0

Musisz również skonfigurować plik cookie impulsów, abyś był uprawniony do hosta pulseaudio. Zasadniczo -v $ HOME/.config/pulse/cookie:/run/pulse/cookie: ro lub coś podobnego. Jednak zmiana $ PULSE_COOKIE na point/run/pulse/cookie nie sprawdziła się, ponieważ powiązanie jest tylko do odczytu, a impuls powraca do ~/.config/pulse/cookie. Zrobiłem więc ln -fs/run/pulse/cookie ~/.config/pulse/cookie i to wszystko. –

2

Po wypróbowaniu większości opisanych tutaj rozwiązań znalazłem tylko PulseAudio over network, aby naprawdę działało. Jednak możesz go zabezpieczyć, utrzymując uwierzytelnianie.

  1. Install paprefs (na maszynie hosta):

    $ apt-get install paprefs 
    
  2. uruchamiania paprefs (Preferencje PulseAudio)> Serwer sieci> [X] Włącz dostęp do sieci lokalnych urządzeń dźwiękowych.

  3. Restart PulseAudio:

    $ service pulseaudio restart 
    
  4. Sprawdź to pracował lub restart maszyny:

    $ (pax11publish || xprop -root PULSE_SERVER) | grep -Eo 'tcp:[^ ]*' 
    tcp:myhostname:4713 
    

teraz używać tego gniazda:

$ docker run \ 
    -e PULSE_SERVER=tcp:$(hostname -i):4713 \ 
    -e PULSE_COOKIE=/run/pulse/cookie \ 
    -v ~/.config/pulse/cookie:/run/pulse/cookie \ 
    ... 

Sprawdź, czy użytkownik r wybranie w kontenerze ma dostęp do pliku cookie ~/.config/pulse/cookie.

Aby przetestować to działa:

$ apt-get install mplayer 
$ mplayer /usr/share/sounds/alsa/Front_Right.wav 

Więcej informacji można sprawdzić Docker Mopidy projektu.

1

Zakładając, że pulseaudio jest zainstalowany na hoście i na obrazie, można zapewnić dźwięk pulseaudio na tcp za pomocą zaledwie kilku kroków. pulseaudio nie musi być ponownie uruchamiane, a także nie trzeba konfigurować hosta ani obrazu. W ten sposób to jest wliczone w x11docker, bez konieczności VNC lub SSH:

Najpierw find a free tcp port:

read LOWERPORT UPPERPORT < /proc/sys/net/ipv4/ip_local_port_range 
while : ; do 
    PULSE_PORT="`shuf -i $LOWERPORT-$UPPERPORT -n 1`" 
    ss -lpn | grep -q ":$PULSE_PORT " || break 
done 

Uzyskaj adres IP od demona Döcker. I zawsze znaleźć to istota 172.17.42.1/16

ip -4 -o a | grep docker0 | awk '{print $4}' 

Załaduj moduł PulseAudio TCP uwierzytelnienia połączenia do dokowanym IP:

PULSE_MODULE_ID=$(pactl load-module module-native-protocol-tcp port=$PULSE_PORT auth-ip-acl=172.17.42.1/16) 

Na metę Döcker, utworzyć zmienną środowiskową PULSE_SERVER

docker run -e PULSE_SERVER=tcp:172.17.42.1:$PULSE_PORT yourimage 

Następnie zwolnij moduł tcp. (Uwaga: z nieznanych powodów, rozładunku moduł ten może zatrzymać PulseAudio demona na host):

pactl unload-module $PULSE_MODULE_ID