Docker 内で GLFW のプログラムを動かすサンプル

はじめに

Docker の利用は CLI やサーバーサイドの利用が主なのかなと思っていましたが GUI のプログラムもある程度は動かせるようです。

軽いゲームなどを作る場合も使えるかもしれません。

実験用に GLFW のデモアプリを動かす Docker イメージを作ってみました。

Dockerfile などはここのリポジトリに置きました。

github.com

マウントしたり特権コンテナにしたりという設定があるため docker-compose を使っています。

Docker での GUI

以下のページなどを参考にさせてもらいました。

docker/Tutorials/GUI - ROS Wiki

https://unskilled.site/dockerコンテナの中でguiアプリケーションを起動させる/

https://tail-island.github.io/programming/2017/07/11/docker-for-development-container-on-linux.htmltail-island.github.io

medium.com

kunst1080.hatenablog.com

いくつか方法があるようです。

  • X11 ソケットを共有する
    • ホストの X サーバーとコンテナの X クライアントがソケット通信
  • コンテナで X サーバーを動かす
    • コンテナで X サーバーも X クライアントも動かす
  • ssh を使った X11 forwarding
    • コンテナで ssh サーバーを動かす
  • VNC を使う
    • コンテナで VNC サーバーを動かす

ホスト側も X ウィンドウシステムの場合は上の二つの方法が使えそうです。

自分ではホストも Ubuntu などで動かすと思うので一番簡単そうな X11 ソケットを共有する方法を試してみました。

Docker イメージ

前に作った haskell 用のイメージを元にして作っています。

開発用として使う想定なので他の言語ではそれぞれの開発環境が入ったイメージを元にして必要なパッケージをいれることになると思います。

FROM tkaaad97/haskell-docker:8.2.2

# install dev tools
RUN apt-get update && \
    apt-get install -y --no-install-recommends \
        make \
        pkgconf \
        xz-utils \
        xorg-dev \
        libgl1-mesa-dev \
        libglu1-mesa-dev \
        libxrandr-dev \
        libxinerama-dev \
        libxcursor-dev \
        libxi-dev \
        libxxf86vm-dev

WORKDIR /app/

ENTRYPOINT []
CMD ["bash"]

下は docker-compose 設定ファイルです。

/tmp/.X11-unix:/tmp/.X11-unix:rw の部分で X11 ソケットをマウントして共有しています。

command で GLFW-b-demo のパッケージをインストールして起動しています。

version: "2"
services:
  app:
    build: .
    command: bash -c 'stack install GLFW-b-demo && /root/.local/bin/GLFW-b-demo'
    working_dir: /app
    privileged: true
    environment:
      - DISPLAY=${DISPLAY}
    volumes:
      - .:/app
      - .stack:/root/.stack
      - /tmp/.X11-unix:/tmp/.X11-unix:rw

xhost

コンテナとホストで X11 ソケット共有して通信する必要があるのですが コンテナ上のユーザーとホスト側で接続しているユーザーが 違う場合にそのままでは通信が許可されません。 この場合に xhost を使って許可することができます。

xhost local:

これを実行するとローカルの接続であればユーザーが違っても許可されます。

ただしあまり安全な方法では無いらしくコンテナのユーザーとホストのユーザーを合わせる方法なども紹介されていました。

スクリーンショット

以下のようにデモアプリが表示されました。

f:id:tkaaad97:20180902224447p:plain