zukucode
主にWEB関連の情報を技術メモとして発信しています。

Docker コンテナ内のGUIアプリを起動してホスト側に表示する

Dockerのコンテナ内のGUIのアプリを起動してホスト側に表示する方法を紹介します。

ホスト側のOSはLinux Mintで確認しました。

Dockerファイルの作成

ベースイメージはUbuntuで動作確認用のアプリはシンプルなメモ帳のleafpadとします。

また、Docker コンテナ内に一般ユーザーを作成するで紹介した方法で、ホスト側の現在のユーザーと同じユーザーID(UID)のユーザーを作成し、そのユーザーでGUIアプリを実行するようにします。

そのようにしないと、GUIアプリを起動時に以下のエラーが発生してしまいます。

エラー
$ leafpad: Cannot open display: 

xhostの設定などで対処できるようですが、ここではホストユーザーと同じユーザーIDを作成する方法で確認します。

Dockerfile
FROM ubuntu

# 動作確認用のGUIアプリをインストール
RUN apt-get update \
    && apt-get install -y leafpad

# ユーザーを作成
ARG DOCKER_UID=1000
ARG DOCKER_USER=docker
ARG DOCKER_PASSWORD=docker
RUN useradd -m \
  --uid ${DOCKER_UID} --groups sudo ${DOCKER_USER} \
  && echo ${DOCKER_USER}:${DOCKER_PASSWORD} | chpasswd

USER ${DOCKER_USER}

WORKDIR /home/${DOCKER_USER}/app

docker-composeの設定

環境変数とボリュームに以下を追加します。

また、Docker ubuntuコンテナが終了してしまうのを防ぐ方法で紹介したように、コンテナを起動し続けるためttytrueに設定しています。

docker-compose.yml
version: '3'
services:
  app:
    build: ./docker/app
    tty: true
    environment:
      - DISPLAY=${DISPLAY}
    volumes:
      - /tmp/.X11-unix:/tmp/.X11-unix

設定内容の詳細な説明はX Window SystemX11などで検索するといろいろ出てきます。

X Window Systemのサーバーの指定

コンテナのDISPLAYという名前の環境変数に、ホスト側の同名の値を設定しています。

実際の値は以下のコマンドで確認できます。

$ printenv DISPLAY
:0

ホスト:ディスプレイ.スクリーンの形式で設定されています。ホストlocalhostの場合は省略でき、スクリーンが1番目のディスプレイの場合も省略できます。

そのため、:0というのは実際はlocalhost:0.0を意味します。

X Windows SystemのUNIXドメインソケットの共有

tmp/.X11-unixvolumesでホスト側とコンテナ側で共有することにより、ドメインソケットを共有します。

動作確認

まず、以下のコマンドでコンテナを起動します。

$ docker-compose up -d

次に、以下のコマンドでコンテナ内に入ります。

$ docker-compose exec app bash

コンテナ内のbashで以下のコマンドを実行し、leafpadを起動します。

$ leafpad

leafpadのアプリが画面に表示されればOKです。


関連記事