この質問は GUIアプリをdockerコンテナで実行できますか? に触発されています。
基本的な考え方は、オーディオとUI(vlc、firefox、skypeなど)を使用してアプリを実行することです
Pulseaudioを使用してdockerコンテナーを検索していましたが、tcpでpulseaudioストリーミングを使用しているすべてのコンテナーを見つけました。 (アプリケーションのセキュリティサンドボックス化)
私の場合、コンテナ内のアプリからホストpulseaudioに直接オーディオを再生することを好みます。 (sshトンネリングおよび肥大化したDockerイメージなし)
Pulseaudioは私のqtアプリが使用しているためです;)
必要なものが見つかるまで時間がかかりました。 (Ubuntu)
docker runコマンド_docker run -ti --rm myContainer sh -c "echo run something"
_から始めます
ALSA:
_/dev/snd
_およびハードウェアアクセスが必要です。これをまとめると、
_docker run -ti --rm \
-v /dev/snd:/dev/snd \
--lxc-conf='lxc.cgroup.devices.allow = c 116:* rwm' \
myContainer sh -c "echo run something"`
_
Lxcフラグのない新しいdockerバージョンでは、これを使用する必要があります:
_docker run -ti --rm \
-v /dev/snd:/dev/snd \
--privileged \
myContainer sh -c "echo run something"`
_
パルスオーディオ:
ここでは、基本的に_/dev/shm
_、_/etc/machine-id
_、_/run/user/$uid/Pulse
_が必要です。しかし、それだけではありません(おそらく、Ubuntuと過去のやり方によるものでしょう)。環境変数_XDG_RUNTIME_DIR
_は、ホストシステムとdockerコンテナで同じである必要があります。一部のアプリはここからマシンIDにアクセスしているため、_/var/lib/dbus
_も必要になる場合があります(「実際の」マシンIDへのシンボリックリンクのみが含まれる場合があります)。また、少なくとも一時データには隠しホームフォルダー_~/.Pulse
_が必要になる場合があります(これについてはわかりません)。
_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"
_
新しいdockerバージョンでは、_--privileged
_の追加が必要になる場合があります。
もちろん、両方を組み合わせて、次のようなxServer
ui転送と一緒に使用できます: https://stackoverflow.com/a/28971413/2835523
言及するだけで:
dockerfile
でこのほとんど(すべて使用済みIDなし)を処理できます。uid=$(id -u)
を使用して、_id -g
_でユーザーIDとgidを取得しますユーザースクリプトの作成:
_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
_
あなたが投稿したリンクに触発されて、次のソリューションを作成することができました。それは私がそれを得ることができるのと同じくらい軽量です。ただし、(1)安全であり、(2)ユースケースに完全に適合するかどうかはわかりません(まだネットワークを使用しているため)。
paprefs
をインストールします。 UbuntuマシンでSudo apt-get install paprefs
を使用します。Sudo apt-get install -y pulseaudio
export "Pulse_SERVER=tcp:<Host IP address>:<Host Pulseaudio port>"
を実行します。たとえば、export "Pulse_SERVER=tcp:172.16.86.13:4713"
[2]。 ifconfig
を使用してIPアドレスを確認し、pax11publish
[1]を使用してPulseaudioポートを確認できます。Pulse_SERVER
のような環境変数を永続的に保存するかどうかもわかりません。そうでない場合は、各コンテナーの起動後に初期化する必要があります。私は現在、OPと同様の問題に取り組んでいるので、私のアプローチをさらに改善するための提案をいただければ幸いです。
参照:
[1] https://github.com/jlund/docker-chrome-pulseaudio
[2] https://github.com/jlund/docker-chrome-pulseaudio/blob/master/Dockerfile
更新(そしておそらくより良い解決策):
これは、TCPソケットの代わりにUnixソケットを使用しても機能します。
-v /run/user/$UID/Pulse/native:/path/to/pulseaudio/socket
でコンテナを開始しますexport "Pulse_SERVER=unix:/path/to/pulseaudio/socket"
を実行します/path/to/pulseaudio/socket
は何でも構いません。テスト目的で/home/user/Pulse
を使用しました。
たぶんデフォルトのソケットと同じパス($ UID部分を処理)で動作するかもしれません。このように究極の解決策は-v /run/user/$UID/Pulse/native:/run/user/<UID in container>/Pulse
です;ただし、これはテストしていません。
ここで説明したほとんどのソリューションを試してみたところ、実際に機能しているのは PulseAudio over network だけでした。ただし、認証を保持することで安全にできます。
インストールpaprefs(ホストマシン上):
$ apt-get install paprefs
paprefs
(PulseAudioの設定)>ネットワークサーバー> [X]を起動し、ローカルサウンドデバイスへのネットワークアクセスを有効にします。
PulseAudioを再起動します。
$ service pulseaudio restart
動作確認するか、マシンを再起動します。
$ (pax11publish || xprop -root Pulse_SERVER) | grep -Eo 'tcp:[^ ]*'
tcp:myhostname:4713
次に、そのソケットを使用します。
$ docker run \
-e Pulse_SERVER=tcp:$(hostname -i):4713 \
-e Pulse_COOKIE=/run/Pulse/cookie \
-v ~/.config/Pulse/cookie:/run/Pulse/cookie \
...
コンテナ内で実行しているユーザーがCookieファイルにアクセスできることを確認します~/.config/Pulse/cookie
。
動作をテストするには:
$ apt-get install mplayer
$ mplayer /usr/share/sounds/alsa/Front_Right.wav
詳細については Docker Mopidy プロジェクトを確認してください。
ホストおよびイメージにpulseaudioがインストールされていると仮定すると、わずかな手順でtcp経由でpulseaudioサウンドを提供できます。 pulseaudioを再起動する必要はなく、ホストまたはイメージで設定を行う必要もありません。このように、VNCやSSHを必要とせずに、 x11docker に含まれています。
まず、 無料のtcpポートを見つける :
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
DockerデーモンのIPアドレスを取得します。常に172.17.42.1/16であることがわかります
ip -4 -o a | grep docker0 | awk '{print $4}'
Pulseaudio tcpモジュールをロードし、docker ipへの接続を認証します:
Pulse_MODULE_ID=$(pactl load-module module-native-protocol-tcp port=$Pulse_PORT auth-ip-acl=172.17.42.1/16)
Dockerの実行時に、環境変数Pulse_SERVERを作成します
docker run -e Pulse_SERVER=tcp:172.17.42.1:$Pulse_PORT yourimage
その後、tcpモジュールをアンロードします。 (注:不明な理由により、このモジュールをアンロードすると、ホストのpulseaudioデーモンが停止する場合があります):
pactl unload-module $Pulse_MODULE_ID