とにかく Docker で X11 飛ばせる状態でコンテナを作る

このページは次のブログ記事「[とにかく Docker で X11 飛ばせる状態でコンテナを作るためのメモ - みんな重力のせい](https://log.mkuriki.com/docker-with-x11-settings/)」のコピーです。

------
これは最近 Docker を触り始めたので、X11 をすぐ使えるような使い方のメモです。色々と用語は正しくないかもしれません。

docker そのもののインストールは Docker の公式ドキュメントを参照しています。

* [Install Docker Engine on Debian - docker docs](https://docs.docker.com/engine/install/debian/)

# 環境
* コンテナ : Debian

# Docker コンテナを起動する

X11 が飛ばせる状態で起動するようにする。

```bash
# コンテナの初回起動 : Debian の場合
docker run --name 'Container_Name' -it --net host -e DISPLAY=$DISPLAY -v /home/$USER/.Xauthority:/root/.Xauthority -v /home/$USER:/home/$USER imagename

# コンテナの初回起動 : Ubuntu の場合
docker run --name 'Container_Name' -it --net host -e DISPLAY=$DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix -v /home/$USER:/home/$USER imagename
```

```bash:runオプション一覧
--name 'Container_Name' # Docker コンテナの名前を決めるオプション. 指定しないと勝手に名前がつけられる
-it # 仮想端末を使うオプション --interactive と --tty オプションの組み合わせらしい
--net host # host ネットワークを起動するオプション
-e DISPLAY=$DISPLAY # 環境変数にホストの DISPLAY を設定する
-v /tmp/.X11-unix:/tmp/.X11-unix # Ubuntu で X11 を利用するのに必要なマウント
-v /home/$USER:/home/$USER # 自分のホームディレクトリをマウントしとくと便利
```

`-e` オプションは環境変数を予め指定するだけなので、コンテナ起動した後にインタラクティブシェルを開いて変更することもできる。`ssh -X -C` などでネットワークを通じて X11 を飛ばすとき、接続状況に応じてホストの `$DISPLAY` の値が変わる場合があるので、コンテナ上でうまく X Window が表示できないときは `export` して設定を変える必要がある。

特に `-v` のオプションは一度コンテナを作ると後から変更できないので必要なものはすべてここでマウントする。書式は `-v [コンテナのマウントポイント]:[ホストのマウントしたいパス]` となる。

# コンテナを起動したら
最初は `root` でログインしているので、適当に `adduser` する。特に最初にマウントしたホームディレクトリと同じユーザ名にしておくと `/home/` 等の構成が同じになるので色々捗る。しかし Docker コンテナの上で走るシェルなのか、ホストマシンの上で走るシェルなのか区別がつきにくくなるので注意する。

# コンテナの表示方法
コンテナが起動中かどうか調べる。

```bash
# 起動中の Docker コンテナを表示
docker ps
# 停止しているコンテナもすべて表示
docker ps -a
```

# ログアウトした後にもう一度使うには
コンテナが起動してない場合は起動してから実行する。

```bash
# 'Container Name' のコンテナを起動 
docker start 'Container_Name'
```

```bash
# 起動済みのコンテナで bash をインタラクティブに起動
docker exec -it 'Container_Name' /bin/bash
# 起動済みのコンテナで zsh をインタラクティブに起動
docker exec -it 'Container_Name' /usr/bin/zsh
```

# コンテナの削除
コンテナを停めてから削除する。

```bash
# コンテナの停止
docker stop 'Container_name'
# コンテナの削除
docker stop 'Container_name'
```

# Dockerfile のビルド方法
```bash
# まずイメージをビルド
docker build -t 'Image_name':'tag_name' 'path_to_Dockerfile'
# ビルドしたイメージをファイル形式で保存
docker save 'Image_name' -o image_name.tar
```

## Dockerfile の例

```bash:Dockerfile
# set the base image
FROM debian

MAINTAINER Murahashi Kuriki
LABEL version="20210324"
LABEL description="Environment for Dennou Club Library (DCL)"

# update sources list
RUN apt clean
RUN apt update

# install basic apps, one per line for better caching
RUN apt install -qy vim
RUN apt install -qy emacs
RUN apt install -qy locales
RUN apt install -qy nano
RUN apt install -qy tmux
RUN apt install -qy wget
RUN apt install -qy zsh
RUN apt install -qy imagemagick

# install DCL packages from http://www.gfd-dennou.org/arch/cc-env/debian-dennou/index.htm
RUN apt install -qy debian-keyring
RUN echo "deb http://www.gfd-dennou.org/library/cc-env/Linux/debian-dennou buster main\ndeb-src http://www.gfd-dennou.org/library/cc-env/Linux/debian-dennou buster main" >> /etc/apt/sources.list
RUN gpg --keyring /usr/share/keyrings/debian-maintainers.gpg --export -a 891D7E07 | apt-key add -
RUN apt update
RUN apt install -qy gphys

# install for X11 test
RUN apt install -qy x11-apps

# cleanup
RUN apt -qy autoremove

# locales to UTF-8
ENV DEBIAN_FRONTEND noninteractive

RUN echo "ja_JP.UTF-8 UTF-8" > /etc/locale.gen && \
    locale-gen ja_JP.UTF-8 && \
    dpkg-reconfigure locales && \
    /usr/sbin/update-locale LANG=ja_JP.UTF-8

ENV LC_ALL ja_JP.UTF-8
```

# ビルドした Docker イメージの読み込み
```bash
docker load -i image_name.tar
```
# Docker イメージの削除
```bash
docker rmi 'image_name'
```


# 参考資料
* [【連載】世界一わかりみが深いコンテナ & Docker入門 〜 その2:Dockerってなに？ 〜  - SIOS TECK.LAB](https://tech-lab.sios.jp/archives/19073)
* [Dockerfileとdocker buildコマンドでDockerイメージの作成 - @IT](https://www.atmarkit.co.jp/ait/articles/1407/08/news031.html)
* [Docker コンテナ上で動く X11 アプリケーションのウィンドウをディスプレイに表示させる - Qiita](https://qiita.com/hoto17296/items/7c1ba10c1575c6c38105)
* [Docker イメージをファイルでやり取りする - CUBE SUGAR CONTAINER](https://blog.amedama.jp/entry/2017/11/01/204637)
* [Docker debian系のlocaleを日本語化する - Qiita](https://qiita.com/youtyan/items/ffc7ce5ef9d0818094ad)
* [Dockerイメージとコンテナの削除方法 - Qiita](https://qiita.com/tifa2chan/items/e9aa408244687a63a0ae)
* [Install Docker Engine on Debian - docker docs](https://docs.docker.com/engine/install/debian/)