Help us understand the problem. What is going on with this article?

dockerでデスクトップ環境(GUI)を構築する

More than 1 year has passed since last update.

はじめに

私はArch Linuxを使っているのですが、Ubuntuを触りたいときが稀にあります。Virtual BoxではOSのインストール作業、起動停止の遅さやメモリの圧迫などが気になります。なので、dockerでデスクトップ環境を構築する方法を模索しました。

2018-12-16-161114_1366x768_scrot.png

記事の中程にDockerfileを載せています。

Xephyr

dockerでGUIを使う方法はいくつかありますが、ホストがLinuxなので手軽にホストのX serverで描画します。Xephyr は X アプリケーションとして実行されるネストされた X serverです。
ubuntuならapt install xserver-xephyr、arch linuxならpacman -S xorg-server-xephyrでインストールできます。
Xephyr -resizeable :1で可変ウィンドウでディスプレイ番号1のX serverを起動します。
イメージ作成時あるいはコンテナ起動時に環境変数でディスプレイ番号を指定します。
-e DISPLAY=:1 ENV DISPLAY=:1

サウンド

音の出力はホストのpulse audioのサーバーを使います。コンテナ起動時にホストのソケットファイルを共有します。cookieによる認証を行っているのでそれも共有しておきます。
-v /run/user/$UID/pulse/native:/tmp/pulse/native
-v $HOME/.config/pulse/cookie:/tmp/pulse/cookie

環境変数でpathを指定します。

ENV PULSE_SERVER=unix:/tmp/pulse/native \
    PULSE_COOKIE=/tmp/pulse/cookie

タイムゾーン

tzdataをインストール時にタイムゾーンを聞かれてビルドが止まるので、apt installする前にexport DEBIAN_FRONTEND=noninteractiveを実行しておきます。
ENV TZ=Asia/Tokyoで指定します。

日本語入力

ENV GTK_IM_MODULE=fcitx \
    QT_IM_MODULE=fcitx \
    XMODIFIERS=@im=fcitx \
    DefalutIMModule=fcitx

デスクトップ環境やウィンドウマネージャの設定ファイルで、起動時に実行するコマンドを指定します。jwmの場合は下記です。

~/.jwmrc
<JWM>
  ...
  <StartupCommand>
    fcitx-autostart
    fcitx-imlist -e fcitx-keyboard-jp
    fcitx-imlist -s fcitx-keyboard-jp,mozc,fcitx-keyboard-us
  </StartupCommand>
  ...
</JWM>

ユーザの作成

UIDはホストのUIDに合わせます。サウンド出力のときに使用するcookieを参照できるようにするためです。
--build-arg DOCKER_UID=$(id -u)

ARG DOCKER_USER=docker
ARG DOCKER_UID=1000
ARG DOCKER_PASSWORD=docker
RUN useradd -m --uid ${DOCKER_UID} --groups sudo --shell /bin/bash ${DOCKER_USER} \
      && echo ${DOCKER_USER}:${DOCKER_PASSWORD} | chpasswd

デスクトップ環境,ウィンドウマネージャ

  • jwmというスタック型ウィンドウマネージャをインストールします。jwmはタスクバーが予めあり、設定ファイルが分かりやすく、非常に軽量です。画面をクリックするとmenuが出ます。
  • 注意点としてキーバインドが重複するとホストが優先されます。ctrlとshiftを同時に押すことで、キーバインドとマウスカーソルのスコープをjwm(ネストしているX server)だけに限定できます。

Dockerfile

FROM ubuntu:latest

# 使っていない値を指定する
ENV DISPLAY=:1

# ミラーの変更
RUN sed -i 's@archive.ubuntu.com@ftp.jaist.ac.jp/pub/Linux@' \
      /etc/apt/sources.list

RUN export DEBIAN_FRONTEND=noninteractive \
    && apt update \
    && apt install -y x11-xserver-utils \
                      xinit \
                      tzdata \
                      language-pack-ja-base \
                      language-pack-ja \
                      sudo \
                      jwm \
                      lxterminal \
                      alsa-utils \
                      pulseaudio \
                      fonts-ipafont-gothic \
                      dbus-x11 \
                      fcitx-mozc \
                      fcitx-imlist \
                      vim-gtk3 \
                      libcurl4 \
                      epiphany-browser \
                      curl \
                      feh

# google-chrome
RUN curl -O https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb \
      && apt install -y ./google-chrome-stable_current_amd64.deb \
      && rm google-chrome-stable_current_amd64.deb
# 音
ENV PULSE_SERVER=unix:/tmp/pulse/native \
    PULSE_COOKIE=/tmp/pulse/cookie

# 日本語
RUN locale-gen ja_JP.UTF-8
ENV LANG=ja_JP.UTF-8

# タイムゾーン
ENV TZ=Asia/Tokyo

# 日本語入力
ENV GTK_IM_MODULE=fcitx \
    QT_IM_MODULE=fcitx \
    XMODIFIERS=@im=fcitx \
    DefalutIMModule=fcitx

# docker内で使うユーザを作成する。
# ホストと同じUIDにする。
# ホストのpulseaudioのcookieを触るときに、permision deniedにならない。
ARG DOCKER_UID=1000
ARG DOCKER_USER=docker
ARG DOCKER_PASSWORD=docker
RUN useradd -m \
  --uid ${DOCKER_UID} --groups sudo --shell /bin/bash ${DOCKER_USER} \
  && echo ${DOCKER_USER}:${DOCKER_PASSWORD} | chpasswd

WORKDIR /home/${DOCKER_USER}

# jwm(window manager), lxterminal(terminal), bashの設定
RUN curl -L \
  https://raw.githubusercontent.com/tayusa/dotfiles/master/etc/jwmrc \
  -o ./.jwmrc \
  && mkdir -p ./.config/lxterminal \
  && curl -L \
  https://raw.githubusercontent.com/tayusa/dotfiles/master/terminal/lxterminal/lxterminal.conf \
  -o ./.config/lxterminal/lxterminal.conf \
  && curl -L \
  https://raw.githubusercontent.com/tayusa/dotfiles/master/etc/bashrc \
  -o ./.bashrc

RUN chown -R ${DOCKER_USER} ./

USER ${DOCKER_USER}

CMD jwm

インストールするパッケージ一覧

パッケージ名 概要
x11-xserver-utils X window system (GUI)
xinit X window system (GUI)
tzdata TimeZone
language-pack-ja-base 日本語
language-pack-ja 日本語
sudo
jwm 軽量なスタック型 window manger
lxterminal ターミナル
alsa-utils
pulseaudio
fonts-ipafont-gothic 日本語フォント
dbus-x11 Xクライアントの通信。日本語入力するのに必要。
fcitx-mozc 日本語入力
fcitx-imlist fcitxの設定をコマンドで行うために必要
vim-gtk3 エディタ
libcurl4 ブラウザの依存パッケージ
epiphany-browser ブラウザ
curl ファイルダウンロード用

作成・起動

argを指定しないと uid=1000,user=docker,password=docker になります。

docker build \
    -t ubuntu-jwm \
    --build-arg DOCKER_UID=$(id -u) \
    --build-arg DOCKER_USER='ユーザ名' \
    --build-arg DOCKER_PASSWORD='パスワード' .

環境変数DISPLAYを:1にした場合は、Xephyr -resizeable :1を実行後にdocker runを実行します。

docker run \
    -v /tmp/.X11-unix/:/tmp/.X11-unix/ \
    -v /run/user/$UID/pulse/native:/tmp/pulse/native \
    -v $HOME/.config/pulse/cookie:/tmp/pulse/cookie \
    -it --rm ubuntu-jwm

dockerの起動を楽にする

毎回、コマンドを打ってdockerを起動するのは辛いので関数を書きます。

function jwm() {
  docker info &> /dev/null \
    || { echo 'Is the docker daemon running?'; return; }
  local -r display=1
  [[ -e "/tmp/.X11-unix/X${display}" ]] \
    || Xephyr -wr -resizeable ":${display}" &> /dev/null &
  docker run \
    -v /tmp/.X11-unix/:/tmp/.X11-unix/ \
    -v /run/user/$UID/pulse/native:/tmp/pulse/native \
    -v $HOME/.config/pulse/cookie:/tmp/pulse/cookie \
    -it --rm ubuntu-jwm &> /dev/null
  pkill Xephyr
}
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away