📤

すべてのGUIアプリをコンテナ上で動かす

2021/12/13に公開

背景

筆者は数年前にQubes OSというセキュリティに特化したLinux Distributionを利用していました。
https://www.qubes-os.org/
Qubes OS Architecture
出典:https://www.qubes-os.org/doc/architecture/
Xen上に用途別のVMがあり、セキュリティレベルに沿ってVM上のアプリを使い分けるという変わったOSでした。かなりヘビーな構成なので、もっとライトにdockerで実現出来ないかと考えていて実現できる方策を探っていました。

TOBE


▷上の画像のアプリはすべて別々のコンテナ内で動いています。

▷GNOMEランチャーからコンテナ上のアプリを起動できるようになります。

概要

docker上にアプリ毎のコンテナを作成し、ホストマシンから利用します。これを実現するには3つの課題がありそれぞれ別の記事で解説しているので、紹介しておきます。

GUIアプリを動かすための要素

画面

Dockerコンテナ上でGUIアプリを表示する

音声

Dockerコンテナ上のGUIアプリで音を出す

日本語入力

Dockerコンテナ上のGUIアプリで日本語入力する

ホストマシンのリソースを共通で利用することの注意点

この仕組みは、ホストマシンのX11ソケットやpulseaudioソケットなどを共有しているので、あるコンテナからホストの画面やクリップボードなどは見えてしまうことになり、強固なセキュリティを実現しているというわけではありません。どちらかというと各アプリが利用するストレージがそれぞれ分離されているため環境が汚染されないということのほうが大きなメリットです。

前提

dockerインストール済みのLinux

イメージ作成

基本は前述の過去記事を見ていただければ基本はわかってもらえると思います。
githubにいろいろなアプリ用のDockerfileを上げてるので参考にしてください。
https://github.com/ysuito/solider/tree/master/template

ビルド

ビルドは共通して下記コマンドを実行するだけです。

bash
docker build -t image_name .

起動コマンド

ものすごく長くなるので、Pythonプログラムでラップすれば使いやすくなります。

start_container.py
import subprocess
import sys
import os

home = os.environ['HOME']

base_command = [
  'docker', 'run',
  '--net=bridge',
  '--shm-size=4096m',
  '--rm',
  '-t',
  '-e', 'DISPLAY',
  '-e', 'XMODIFIERS',
  '-e', 'GTK_IM_MODULE',
  '-e', 'QT_IM_MODULE',
  '-e', 'DefalutIMModule=fcitx',
  '-e', 'PULSE_COOKIE=/tmp/pulse/cookie',
  '-e', 'PULSE_SERVER=unix:/tmp/pulse/native',
  '-e', 'DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus',
  '-v', '/run/user/1000/pulse/native:/tmp/pulse/native',
  '-v', os.path.join(home,'.config/pulse/cookie:/tmp/pulse/cookie:ro'),
  '-v', '/tmp/.X11-unix/X0:/tmp/.X11-unix/X0',
  '-v', '/run/user/1000/bus:/run/user/1000/bus',
  '-u', 'user',
]
command = []
command.extend(base_command)
command.extend(sys.argv[1:])
subprocess.Popen(command)
bash
python start_container.py image_name command

このようにすれば簡単に呼び出せるようになります。

GNOMEランチャーからの起動

毎回ターミナルからコマンドで起動するのは面倒なので、GNOMEランチャーに登録します。
~/.local/share/applicationsにdesktopファイルを作ります。

~/.local/share/applications/image_name.desktop
[Desktop Entry]
Type=Application
Name=IMAGE_NAME
MimeType=application/vnd.ms-htmlhelp;
Path=STARTUP_SCRIPT_PATH
Exec=bash -c \python3 start_container.py IMAGE_NAME COMMAND\
NoDisplay=false
Terminal=false
StartupNotify=true
Categories=Development;
Icon=IMAGE_ICON_PATH

IMAGE_NAME,COMMAND,STARTUP_SCRIPT_PATH,IMAGE_ICON_PATHを書き換えてください。
次にこの内容を登録します。

bash
update-desktop-database ~/.local/share/applications

Solider

肥大化するDockerfileやコマンドを毎回扱うのは現実的でないので、管理するプログラム作りました。私がよく使うアプリはテンプレート化してあります。よかったら参考にしてください。
https://github.com/ysuito/solider

Discussion