DockerでOpenGL開発環境
はじめに
この記事ではDockerでOpenGLを使ったプログラミングができる環境を構築する方法を説明していきます。今回作成する環境はGUIアプリを表示するための環境としても使用可能です。
なぜDocker
Dockerを使うことで、OpenGL開発環境の構築において環境依存の問題を軽減し、異なるシステム間でも同一の環境を簡単に再現可能にします。これにより、開発者間での動作の一貫性を保つことで、効率的に共同開発することができます。また、初心者の方のトラブルを解決しやすくすることができます。
本題
Dockefile
FROM debian:bookworm
RUN apt-get update && \
apt-get install -y x11-apps \
mesa-utils \
git \
g++ && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
compose.yml
services:
app:
build:
context: .
dockerfile: Dockerfile
tty: true
network_mode: "host"
user: ${USER_ID}:${GROUP_ID}
environment:
DISPLAY: $DISPLAY
volumes:
- type: bind
source: /tmp/.X11-unix
target: /tmp/.X11-unix
- type: bind
source: .
target: /app
working_dir: /app
実行方法
下記のコマンドを実行することでコンテナを建てることができます。
$ USER_ID="$(id -u)" GROUP_ID="$(id -g)" docker compose up -d
動作確認
$ docker compose exec app /bin/bash
$ xeyes
$ glxgears
すべて動作するか、fpsは60近くで推移するか確認してください
$ glxinfo | grep OpenGL
OpenGL vendor string: X.Org
OpenGL core profile version string: 4.5 (Core Profile) Mesa 22.3.6
OpenGL core profile shading language version string: 4.50
OpenGL core profile context flags: (none)
OpenGL core profile profile mask: core profile
OpenGL core profile extensions:
OpenGL version string: 4.5 (Compatibility Profile) Mesa 22.3.6
OpenGL shading language version string: 4.50
使われているMesaのバージョン、使用可能なOpenGLのバージョンを確認することができます。
Mesaのバージョンが低いと使用可能なOpenGLのバージョンも下がります。
debian:bookworm, debian:bullseyeでは、OpenGL 4.5まで使用可能でした。(環境によって変化するかもしれません)
解説
- 仕組みや環境について詳しく知りたい人
- エラーが出た人
- なにかうまく行かない点がある人
上記の人向けに各ファイルについて解説していきます。
Dockefile
FROM debian:bookworm-slim
今回はX11を使っていてMesa 22を使っているdebian:bookwormをベースイメージにしました。
RUN apt-get update && \
apt-get install -y x11-apps \
mesa-utils \
git \
g++ && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
OpenGLの動作確認用にmesa-utilsを、C++環境用にg++をインストールしています。
compose.yml
user: ${USER_ID}:${GROUP_ID}
Xサーバーと通信するためには認証されたユーザーでなければならないので、UIDとGIDをコンテナ作成時に渡すようにしています。
関連するエラー
$ xeyes
Authorization required, but no authorization protocol specified
Error: Can't open display: :0
Xサーバーに接続するのに失敗しています。Docker内のUID,GIDがローカルの認証されたUID,GIDと一致しているか確認してください。
$ xhost
access control enabled, only authorized clients can connect
...:...:username
$ id username
uid=xxx(username) gid=yyy
$ id
uid=xxx gid=yyy
一致していない場合、docker compose up
時にUSER_ID,GROUP_IDを設定していない、間違った値を設定していると思われます。記事上方の実行方法を確認し、コマンドが間違っていないか確認してください。
xhostで許可されたホストが存在しない場合xhost +si:localuser:username
するなどして、xhostで許可する必要があります。
environment, volumes
environment:
DISPLAY: $DISPLAY
volumes:
- type: bind
source: /tmp/.X11-unix
target: /tmp/.X11-unix
ローカルのXサーバーのソケットとどのソケットに接続するかの情報をコンテナに渡しています。
ローカルのソケットを渡しているので、GUIが表示されるようになります。
コンテナの起動方法について
$ USER_ID="$(id -u)" GROUP_ID="$(id -g)" docker compose up -d
USER_IDとGROUP_IDを外部から渡して起動するようにしています。セキュリティの問題があるので、composeファイルに書くのではなく、環境変数にしています。また、環境変数名をUIDではなくUSER_IDとすることで、bashに設定されているUIDと変数名がかぶらないようにしてあります。
なお今回はUSER_ID="$(id -u)"
としているので、USER_ID=$UID
と同じ意味です。
おわりに
DockerでGUIを表示するにあたって、XサーバーやUID,GIDなどLinuxがどのようにしてGUIを表示しているか理解する必要があると感じました。私も今回この記事を作成するにあたって、Linuxについてより詳しくなれたと感じました。もしこの記事に間違いがあったり、GUIが表示されないなどありましたら、コメントしてくださると助かります。
Discussion