そもそも端末で操作するDockerでどうやってGUIを起動するのか?
その方法にはいくつかの方法があります。
- X11転送を行うSSH
- VNC
- X11ソケットをコンテナと共有
参考記事では、X11ソケットをコンテナと共有して実現しています。
起動するGUIアプリケーションはNetBeansとEclipse、
IntelliJ IDEAが使えるようになっています。
参考記事の通りに、Firefoxを実行するDockerfileを参考に、
実際の仕組みを確認しながらイメージを構築してみます。
ファイル名はDockerfile
にしてください。
FROM ubuntu:14.04
RUN apt-get update && apt-get install -y firefox
# Replace 1000 with your user / group id
RUN export uid=1000 gid=1000 && \
mkdir -p /home/developer && \
echo "developer:x:${uid}:${gid}:Developer,,,:/home/developer:/bin/bash" >> /etc/passwd && \
echo "developer:x:${uid}:" >> /etc/group && \
echo "developer ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/developer && \
chmod 0440 /etc/sudoers.d/developer && \
chown ${uid}:${gid} -R /home/developer
USER developer
ENV HOME /home/developer
CMD /user/bin/firefox
Dockerfileの記述を1つずつ確認してみます。
FROMキーワード
FROM
では、ベースにするDockerイメージを指定します。
ここでは、Ubuntu14.04の公式イメージをベースを指定しています。
RUNキーワード
RUN
に続くコマンドをコンテナ内で実行させます。
ここではapt-getを使って、firefoxをインストールしています。
対話にはなりませんので、-y
オプションを必要とします。
コンテナを実行する為のUNIXユーザを作成・設定しています。
export
でuidとgidの設定
mkdir -p
でHOMEディレクトリを作成
/etc/passwd
、/etc/group
を直接追加してユーザを追加
/etc/sudoers.d/developer
を作成してsudo権限を得る
USERキーワード
コンテナを実行するユーザの指定をしています。
上記で作成したUNIXユーザ(developer)を指定します。
ENVキーワード
環境変数
$HOME
を設定しています。
CMDキーワード
最後にインストールしたfirefoxを端末から実行しています。
ここまで見るとわかると思いますが、
DockerfileではGUIアプリケーションをインストールして実行する記述のみで、
X11ソケットをコンテナと共有するような設定はなさそうです。
Dockerfileができたら、イメージをビルドして構築します。
$ docker build -t firefox .
ビルドが完了したら、次に構築したイメージからコンテナを起動します。
docker run --rm \
-e DISPLAY=$DISPLAY \
-v /tmp/.X11-unix:/tmp/.X11-unix \
firefox
docker run
コマンドを実行すると、
コンテナ内部で起動されたfirefoxが立ち上がるはずです。
/etc/passwd
へアクセスすると、
コンテナ内部で実行できている事を確認できます。
さて、docker run
コマンドを見てみると、
いくつかのオプションでX11ソケットを共有する設定が見られます。
docker run
コマンドのオプションは、
docker run --help
を実行する- Docker run referenceを見る
のどちらかで確認する事ができます。
rmオプション
コンテナが停止するときに削除します。
docker run
は、実行する度に新しいコンテナを作りますので、
--rm
オプションを指定して、コンテナの停止時に削除するようにします。
--rm
オプションが無いと、停止したコンテナが残り続けるので、
新しいコンテナが次々と作成されてしまいます。
eオプション
環境変数を設定します。
ここではホストOSが持っている環境変数$DISPLAYをそのまま利用しています。
vオプション
マウントするボリュームを指定します。
ここでX11ソケットをホストOSと共有する事により、
GUIアプリケーションの起動先をホストOSに設定しています。
ここまでで、DockerコンテナでGUIアプリケーションを 実行する仕組みがなんとなくわかってきました。
本来、リモートに存在しているようなサーバをGUI操作したい場合に、
X11転送をSSH経由で行う事がありますが、
Dockerコンテナがローカルである事を利用して、
ソケットそのものを共有してしまう方法を紹介しています。
- X11ソケット(/tmp/.X11-unix)をホストとコンテナで共有する
SSHによるX11転送に関しては、
豆知識:SSHのX11転送(X11 forwarding)機能を使って、遠距離linuxサーバーのGUIアプリケーションを操作する方法
このあたりを見ると、仕組みの理解が早まります。