2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【2022年版】Docker+GLFWでOpenGLプログラミング環境構築

Last updated at Posted at 2022-07-18

はじめに

 本記事では、Dockerコンテナ上でグラフィックスプログラミングを行える環境の構築を説明していきます。といってもグラフィックスプログラミングにおいて、依存するライブラリは非常に少ないですしセットアップが面倒なものでは無いので、わざわざDocker上でやるようなものではないですが、ロマンということで。需要はなさそうですが書いていきます。
今回の記事で使うファイルはすべてここに置きました。

対象読者

  • あらゆるプログラミングを仮想化された環境で行いたい方
  • OpenGLを使うようなシミュレーション系の研究で実験環境の移行や引き継ぎを楽にしたい方

想定環境

  • Linux
  • Docker導入済み
  • NVIDIAグラフィックスドライバー導入済み

手順

  1. Dockerfile
  2. Docker上のX11アプリをホストで表示させられるようにする
  3. NVIDIA container toolkit の導入
  4. DockerでのGPU利用

Dockerfile

FROM python:3.10-slim-buster

ARG UID
ARG GID
ARG USERNAME
ARG GROUPNAME

RUN apt update && apt upgrade -y
RUN apt install libglfw3-dev python3-pip -y

RUN mkdir -p /opt/app

COPY main.py /opt/app

RUN groupadd -g $GID $GROUPNAME
RUN useradd -m -u $UID -g $GID $USERNAME

RUN chown $USERNAME:$GROUPNAME -R /opt/app
USER $USERNAME

RUN pip install glfw PyOpenGL numpy

WORKDIR /opt/app
ENTRYPOINT ["/bin/bash"]

以上のDockerfileで記述されたコンテナを使って、OpenGLの動作確認を行います。

Docker上のX11アプリをホストで表示させられるようにする

 通常LinuxのGUIはX window systemにより実現されます。X window systemはXサーバとXクライアントからなるウィンドウシステムでソケット通信を通じてUIの描画を行います。Xクライアントが何を描画したいかを決め、Xサーバに描画を依頼することでGUIが実現できるわけです。今回の場合Dockerコンテナ上でXクライアントが動作し、ホストのXサーバが画面の表示やマウス・キーボード入力などを受け付ける形と成ります。
 XサーバとXクライアントのやり取りはソケット通信を通じて行われることを述べましたが、同じコンピュータ内にXサーバとXクライアントが並立している場合には、ソケットファイルが使われます。このやり取りに使われるソケットファイルは/tmp/.unix-X11内に存在しています。つまり、この/tmp/.unix-X11をコンテナ上にマウントしてやれば、コンテナ上のXアプリをホストに表示できるようになるはずです。ただこれだけでは、ウィンドウを表示することができません。なぜならXクライアントが接続するXサーバがされていないのに加え、Xクライアントを動かしているユーザーがXサーバに認証されていないからです。これを解決するためには以下のようにする必要があります。

  • イメージビルド時
$ docker build -t gl \
        --build-arg UID=$(id -u)\
        --build-arg GID=$(id -g)\
        --build-arg USERNAME=$(id -un)\
        --build-arg GROUPNAME=$(id -gn) .

ビルド時にコンテナのユーザーIDとグループIDをホストのものに指定しています。こうすることで既に認証されているホストのユーザーIDとコンテナのユーザーIDが一致するので、前述の問題を解決することができます。

  • コンテナ起動時
$ docker run -it --rm \
        --hostname=gltest \
        -e DISPLAY=$DISPLAY \
        -v /tmp/.X11-unix:/tmp/.X11-unix \
        gl

起動時にDISPLAYの指定と/tmp/.X11-unixのマウントをしています。前者に関してはホストのDISPLAYを指定することでホストにウィンドウが表示されるようにしています。

NVIDIA container toolkit の導入

公式のページにおおよその内容が乗っていますが、少しだけ内容が変わります。

$ distribution=$(. /etc/os-release;echo $ID$VERSION_ID) \
      && curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg \
      && curl -s -L https://nvidia.github.io/libnvidia-container/$distribution/libnvidia-container.list | \
            sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | \
            sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list
$ sudo apt update
$ sudo apt install nvidia-container-runtime -y

これでコンテナからNVIDIAのGPUが見えるようになります。

DockerでのGPU利用

$ docker run -it --rm \
        --gpus all \
        --hostname=gltest \
        -e DISPLAY=$DISPLAY \
        -e NVIDIA_DRIVER_CAPABILITIES=all \
        -v /tmp/.X11-unix:/tmp/.X11-unix \
        gl

コンテナ起動時に--gpusによりコンテナで使いたいGPUの指定を行い、NVIDIA_DRIVER_CAPABILITIESをallと指定することで、GPUによる計算やグラフィックス、GUIへの出力などすべての機能が使えるようになります。

こうして起動したコンテナ上でサンプルアプリケーションを実行してみると、ホスト上で以下のようにウィンドウを表示することができます。
Screenshot from 2022-07-19 06-49-24.png

まとめ

 本記事ではDockerコンテナ内でOpenGLを用いたGUIアプリケーションを起動する方法を解説していきました。これに加えて、vscodeの拡張も使って開発を行っていけばホストで開発していくのと遜色ない利便性が得られると思います。シミュレーション系の研究をやっている方であれば環境を自由に作ったり消したりできて便利なので、非常にオススメです。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?