Dockerを理解するまでの備忘録


# はじめに
Dockerを使ってTensorFlowをインストールする[記事](http://yaju3d.hatenablog.jp/entry/2016/04/07/011033)を書いたわけですが、そこに至るまでを備忘録として残しておきます。

# Dockerとは
Docker社（旧dotCloud社）が開発しているコンテナ型仮想化ソフトウェア(オープンソフトウェア)です。 Docker を使うことで一つのホストOSの上で仮想的に複数のOSを「軽快」に「簡単」に動作させることができるようになります。
コンテナを移動・実行するための必要なプログラム（デーモン）がDockerエンジンとなります。

## コンテナとは
簡単に言うとWebサーバーなどのアプリケーションの実行環境を抽象化する技術となります。

参照：[【Docker入門】コンテナ型仮想化技術Dockerを使ってみた](http://lab.sonicmoov.com/development/docker-tutorial/)

## ハードウェア仮想化とコンテナ型仮想化の違い
VMwareやVirtualBoxなどをハードウェア仮想化と呼びます。コンテナ型仮想化はハードウェア仮想化より、「起動が速い」、「処理が速い」、「軽い」といった特徴があります。
参照：[軽くて使いやすい仮想化技術 「Docker」の仕組み](https://codezine.jp/article/detail/7894)

### ハードウェア仮想化

* CPU、メモリ、ハードディスクなどのハードウェアを仮想化しているため、ハードウェアやOSの起動が必要となり、起動に分単位の時間を要します。
* OS上のアプリケーションを操作する場合、仮想化されたハードウェアおよびハイパーバイザーを経由して処理が行われるため、通常の物理マシンよりも処理に経由分のオーバーヘッドがかかります。
*  物理マシンと比較しても、メモリ、ファイルIOでは約2倍、CPUでは約5倍の時間がかかります。(参照記事のベンチマークより)

### コンテナ型仮想化

* コンテナ起動時にはOSはすでに起動しており、プロセスの起動のみ行うため、秒単位の時間で完了します。
*  カーネルを共有しているため、各プロセスが処理を行うのと同じ程度の時間しかかからず、オーバーヘッドがほとんどありません。
*  物理マシンと比較しても、パフォーマンスの劣化がほとんどありません。(参照記事のベンチマークより)

# Dockerファイルとは
プログラムのビルドでよく利用されるmakeツールの「Makefile」ファイルと同様に、Dockerコンテナーの構成内容をまとめて記述するシンプルなテキスト形式のファイルです。

# Dockerイメージとは
 コンテナを実行する時に必要な ファイルシステム • イメージ・レイヤ（層）の集合体でファイルの実体やメタ情報を含む。

 * レイヤには親子関係がある
 *  差分情報のみを記録する
 *  Read Only で書込みできない 共通するレイヤはイメージ間で共有できる
 *  ディスク容量の削減や高いポータビリティを実現する

DockerファイルをビルドすることでDockerイメージを作成できます。
また、Dockerイメージ自体を他の人と共有することが出来ます。
参照：[Dockerfileとdocker buildコマンドでDockerイメージの作成](http://www.atmarkit.co.jp/ait/articles/1407/08/news031.html)

# Docker Hubとは
Dockerを開発するDocker社が営利目的で開発・運営しているDockerイメージを共有するためのWebサービスで無料ですべての機能が利用可能です。Docker Hubを使うには[アカウント登録](http://www.atmarkit.co.jp/ait/articles/1408/26/news038.html)が必要となります。
参照：[Docker Hubの使い方とGitHubからのDockerイメージ自動ビルド](http://www.atmarkit.co.jp/ait/articles/1408/26/news038.html)

# Dockerのインストール
WindowsやMacユーザーならDockerのオフィシャルサイトの[Docker Toolbox](https://www.docker.com/products/docker-toolbox)からDocker Toolboxのインストーラを入手します。このインストーラにはVirtualBoxやGit for Windowsが同梱されてます。※64bit PCのみが対象となります。

Linuxユーザーの場合、下記コマンドでインストールします。

```bash
$ sudo yum install -y docker
```

# Dockerコマンド
Dockerを操作するためのコマンドの一覧サイト
[Docker コマンド](http://docs.docker.jp/engine/reference/commandline/)
[docker コマンド チートシート](http://qiita.com/voluntas/items/68c1fd04dd3d507d4083)
[Dockerコンテナとイメージの仕組みを視覚化してみた](https://fa-works.com/blog/visualizing-docker-containers-and-images)

# DockerファイルからDockerイメージ生成
実は、tensorflow.orgが公開している[Docker用TensorFlowイメージ](https://www.tensorflow.org/versions/r0.7/get_started/os_setup.html)がJupyter Notebookを使えるのか分からなかった為、下記サイトを先に試しました。
[JupyterでTensorFlowが使えるDockerイメージ - めもめも](http://enakai00.hatenablog.com/entry/2016/03/28/131157)

Docker Hub上にDockerイメージが公開されているのですが、アカウントを取ってないため、DockerファイルからDockerイメージを生成しました。

https://github.com/enakai00/jupyter_tensorflow
からDownload ZIPでダウンロードして、ダウンロードフォルダにjupyter_tensorflow-masterを展開。

「[docker build](http://www.atmarkit.co.jp/ait/articles/1407/08/news031.html)」コマンドの実行
 docker build [ -t ｛イメージ名｝ [ :｛タグ名｝ ] ] ｛Dockerfileのあるディレクトリ｝

```bash
$ docker build -t tensorenv /c/Users/(ユーザー名)/Downloads/jupyter_tensorflow-master

SECURITY WARNING: You are building a Docker image from Windows against a non-Win
dows Docker host. All files and directories added to build context will have '-r
wxr-xr-x' permissions. It is recommended to double check and reset permissions f
or sensitive files and directories.
```

# TensorFlowの実行

```bash
$ docker run -d -p 8888:8888 -p 6006:6006 -e PASSWORD="$PASSWORD" tensorenv
```

-e PASSWORD="\$PASSWORD" が無いとJupyter Notebookが起動した際にパスワード入力で何を入力しても、invalidエラーとなる。$PASSWORDは定義してなければ、空入力で行ける。

参照：[docker runの便利なオプション](http://qiita.com/umchifre/items/31d9533049c591569279)

# Jupyter Notebookの起動

Webブラウザで「http:192.168.99.100:8888/」と入力するとJupyter Notebookが起動されました。
※IPアドレスは、Dockerの動作確認した際のURLとなります。

# TensorBoradの実行
今でこそ、Jupyter NotebookにTerminalがあることが分かっているのですが、当初はTensorBoradを動かす方法が分からなかったです。

tensorboardコマンドを入力しても、そんなコマンドは無いってエラーになるし、Webブラウザで「http:192.168.99.100:6006/」と入力しても、「このサイトにアクセスできません」のエラーになるしね。

何かヒントが無いかとネットで「Tensorflow Docker」で検索した下記の動画をじっくり見ると
[Tensorflow: How to setup Tensorboard for Windows / Docker installation](https://www.youtube.com/watch?v=Wwnj8NayOcQ)
「docker exec」コマンドを使っていることを発見しました。

```bash
$ docker exec -it [コンテナID or コンテナ名] bash
```

参照：[コンテナに入りたい？それ docker exec でできるよ](http://qiita.com/yosisa/items/a5670e4da3ff22e9411a)

「docker exec」コマンドを実行後にコンテナに入ることができ、tensorboardコマンドを入力すると今度はエラーにならずに実行されました。

```bash
$ tensorboard --logdir=log 
```
これでWebブラウザで「http:192.168.99.100:6006/」と入力すると、TensorBoradが動いたんですね。思わずガッツポーズでした。

# Dockerイメージの削除

[Dockerイメージとコンテナの削除方法](http://qiita.com/tifa2chan/items/e9aa408244687a63a0ae)

```bash
$ docker rmi [イメージID]
```

[docker で使ってないイメージを全部消す時の Tips](http://qiita.com/rosylilly/items/3aca2c30eb9681628c34)

```bash
$ docker rmi --no-prune=true $(docker images -a -q)
```

# Dockerのファイルコピー
## コンテナからホストへのコピー
```bash
$ docker ps
#コンテナ名(NAME)を取得 例 cranky_murdock
$ docker cp [CONTAINER ID or NAME]:[コンテナコピー元ファイル] [ホストコピー先ファイル] 

$ docker cp cranky_murdock:/notebooks/shark-color.jpg /c/Users/(ユーザー名)
```

## ホストからコンテナへのコピー
Docker 1.8からホストからコンテナへのコピーも docker cp コマンドでサポートされるようになりました。

```bash
$ docker ps
#コンテナ名(NAME)を取得 例 cranky_murdock
$ docker cp [ホストコピー元ファイル] [CONTAINER ID or NAME]:[コンテナコピー先ファイル] 

$ docker cp /c/Users/(ユーザー名)/shark.jpg cranky_murdock:/notebooks
```
下記の方法でもコピーできる。

```bash
$ docker exec -i [CONTAINER ID or NAME] /bin/bash -c "cat >コンテナコピー先ファイル" <ホストコピー元ファイル
```
参照：[Copying files from host to docker container](http://stackoverflow.com/questions/22907231/copying-files-from-host-to-docker-container)

## ホストとファイル共有
docker cp コマンドでコンテナ間のファイルコピーをするよりも、ホストとファイル共有してしまえば、そのままアクセス出来るので楽です。
方法は、docker runにて"-v"オプションを使います。

ホスト側(C:\Users\(ユーザー名))の配下に「tensor_share」フォルダ(例)を作成したとします。

```bash
$ docker run -d -p 8888:8888 -p 6006:6006 -e PASSWORD="$PASSWORD" -v /c/Users/(ユーザー名)/tensor_share:/notebook tensorenv
```
PWDコマンドを使うとカレントディレクトリを取得できます。~~(自PCのMINGW64環境では使えなかったです)~~

```bash
$ echo $PWD
/c/Users/(ユーザー名)

$ docker run -d -p 8888:8888 -p 6006:6006 -e PASSWORD="$PASSWORD" -v $PWD/tensor_share:/notebook tensorenv
```
コンテナ側フォルダの「:/notebook」は、Dockerイメージの作成環境によって違うので注意が必要です。例 として「:/home/jovyan/work」というのもあります。

# 最後に
最終的にtensorflow.orgが公開している[Docker用TensorFlowイメージ](https://www.tensorflow.org/versions/r0.7/get_started/os_setup.html)でJupyterを使えることが確認できたので、下記サイトに記事を公開しました。

[WindowsユーザーがTensorFlowをインストールしてみた(Docker版)](http://yaju3d.hatenablog.jp/entry/2016/04/07/011033)

苦労したけど、Dockerについて仕組みや使い方を学ぶことが出来たので良かったです。