Dockerについて調べてみたのでめもめも

# What is docker?

- 仮想環境を構築できる仕組み
- 構築した環境を公開するのが容易。また公開された環境を利用するのも同様に容易
- 簡単に生成できて簡単に破棄できるので、Immutable Infrastructureに向いている
- LXC技術を用いているため、仮想環境の一種ではあるが、仮想機械環境ではない

# How to Install

## on Ubuntu

aptでインストール可能。

```shell-session
# apt-get install docker
```

## on MacOS X

* MacOS X上では直接dockerを起動できない
* [boot2docker](https://github.com/boot2docker/boot2docker)を用いる
    * 別途VirtualBoxが必要
    * 仮想環境経由でdockerを操作可能とする
    * Vagrant likeに操作できる
    * ちょっとインチキな感じがしないでもないが、自分でVirtualBox上にLinux構築するよりは簡単。起動も多少なりとも早いし

brewでインストールする。

```shell-session
$ brew install boot2docker docker
$ brew info boot2docker docker
boot2docker: stable 1.1.0 (bottled), HEAD
...
docker: stable 1.1.0 (bottled)
...
```

## How to boot

boot2dockerの環境を構築。
最初は起動イメージがダウンロードされる。

```shell-session
$ boot2docker download
2014/07/10 10:46:46 Downloading boot2docker ISO image...
2014/07/10 10:46:47 Latest release is v1.1.0
2014/07/10 10:48:12 Success: downloaded https://github.com/boot2docker/boot2docker/releases/download/v1.1.0/boot2docker.iso
        to /Users/uchihara/.boot2docker/boot2docker.iso
```

環境を初期化。

```shell-session
$ boot2docker init
2014/07/10 10:48:19 Creating VM boot2docker-vm...
2014/07/10 10:48:20 Apply interim patch to VM boot2docker-vm (https://www.virtualbox.org/ticket/12748)
2014/07/10 10:48:20 Setting NIC #1 to use NAT network...
2014/07/10 10:48:20 Port forwarding [ssh] tcp://127.0.0.1:2022 --> :22
2014/07/10 10:48:20 Port forwarding [docker] tcp://127.0.0.1:2375 --> :2375
2014/07/10 10:48:20 Setting NIC #2 to use host-only network "vboxnet1"...
2014/07/10 10:48:20 Setting VM storage...
2014/07/10 10:48:27 Done. Type `boot2docker up` to start the VM.
```

起動。

```shell-session
$ boot2docker up
2014/07/10 10:49:43 Waiting for VM to be started...

2014/07/10 10:49:43 Started.
2014/07/10 10:49:43 To connect the Docker client to the Docker daemon, please set:
2014/07/10 10:49:43     export DOCKER_HOST=tcp://192.168.59.103:2375
```

確認。

```shell-session
$ boot2docker status
running
```

これでdockerによる操作が可能となる。その際環境変数で接続先を指定する。

```shell-session
$ export DOCKER_HOST=tcp://192.168.59.103:2375
$ docker version
Client version: 1.1.0
Client API version: 1.13
Go version (client): go1.3
Git commit (client): 79812e3
Server version: 1.1.0
Server API version: 1.13
Go version (server): go1.2.1
Git commit (server): 79812000
```

# How to Use

## とりあえずubuntu

以下で起動できる。
初回はイメージのダウンロードが必要。

```shell-session
$ docker run -i -t ubuntu /bin/bash
Unable to find image 'ubuntu' locally
Pulling repository ubuntu
e54ca5efa2e9: Pulling image (latest) from ubuntu, endpoint: https://cdn-registry
e54ca5efa2e9: Download complete 
511136ea3c5a: Download complete 
d7ac5e4f1812: Download complete 
2f4b4d6a4a06: Download complete 
83ff768040a0: Download complete 
6c37f792ddac: Download complete 
root@4dcceaa5f24b:/# ls
bin   dev  home  lib64  mnt  proc  run   srv  tmp  var
boot  etc  lib   media  opt  root  sbin  sys  usr
```

この状態でdockerのインスタンスを一覧できる。

```shell-session
$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
4dcceaa5f24b        ubuntu:latest       /bin/bash           15 hours ago        Up About an hour                        boring_euclid       
```

ファイルを作成してみる。

```shell-session
root@4dcceaa5f24b:/# touch file
root@4dcceaa5f24b:/# ls -l file
-rw-r--r--   1 root root    0 Jul 10 05:06 file
```


shellを抜けてみる。dockerも終了する。

```shell-session
root@4dcceaa5f24b:/# exit
$ 
```

一覧からも消える。

```shell-session
$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
```

## 別コンテナを起動

もう一度起動する。
今度は起動が早い。
id的なものが変わっているのに注意。

```shell-session
$ docker run -i -t ubuntu /bin/bash
root@42412eac21e9:/# 
```

さっき作ったはずのファイルは消えている。
別の環境が立ち上がっていることが分かる。

```shell-session
root@42412eac21e9:/# ls -l file
ls: cannot access file: No such file or directory
```

さっきの環境は消えてしまったわけではない。
``docker ps``はコンテナを一覧するコマンドだが、起動中に限らず全てのコンテナを含めるには``-a``オプションを付ける。

```shell-session
$ docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                     PORTS               NAMES
42412eac21e9        ubuntu:latest       /bin/bash           About an hour ago   Exited (2) 4 seconds ago                       nostalgic_perlman   
4dcceaa5f24b        ubuntu:latest       /bin/bash           4 hours ago         Exited (0) 3 hours ago                         drunk_mccarthy      
```

## 指定コンテナの再開

現在は停止中になっているため、再開してattachする。
attach直後はプロンプトの出力がされないため一瞬固まったかと思うので注意。
Enter押下でプロンプトが再表示されるが、その際にうっかり妙なコマンドを実行してしまうことがないようCtrl+Lがオススメ。

```shell-session
$ docker start 4dcceaa5f24b
4dcceaa5f24b
$ docker attach 4dcceaa5f24b
root@4dcceaa5f24b:/#
root@4dcceaa5f24b:/# ls -l file
-rw-r--r-- 1 root root 0 Jul 10 05:06 file
```

## コンテナの保存

``commit``でコンテナイメージを保存する。

```shell-session
$ docker commit 881448280ac4 uchihara/test1
9be9d854b181d6b72e2cbeffbd1d68e7f0994a180d9d9e8a71844c4cb88bb361
```

``images``でコンテナイメージを一覧する。

```shell-session
$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
uchihara/test1      latest              9be9d854b181        3 days ago          366.9 MB
```

コンテナイメージをアップロードするには事前に[Docker Index](https://hub.docker.com/)にアカウントを作成しておく必要がある。

```shell-session
$ docker login
Username: uchihara
Password: 
Email: ***
Login Succeeded
```

``push``でアップロード。

```shell-session
$ docker push uchihara/test1
The push refers to a repository [uchihara/test1] (len: 1)
Sending image list
Pushing repository uchihara/test1 (1 tags)
511136ea3c5a: Image already pushed, skipping 
d7ac5e4f1812: Image already pushed, skipping 
2f4b4d6a4a06: Image already pushed, skipping 
83ff768040a0: Image already pushed, skipping 
6c37f792ddac: Image already pushed, skipping 
e54ca5efa2e9: Image already pushed, skipping 
9be9d854b181: Image successfully pushed 
Pushing tag for rev [9be9d854b181] on {https://registry-1.docker.io/v1/repositories/uchihara/test1/tags/latest}
```

## Dockerfile

Dockerfileを使ってコンテナ構築ができる。

```shell-session
$ mkdir test1 && cd test1
$ cat >Dockerfile <<EOF
FROM ubuntu
RUN apt-get install -y hello
EOF
$ docker build -t uchihara/hello .
```

Dockerfileを元に構築されたコンテナで実行できる。

```shell-session
$ docker run -t uchihara/hello /usr/bin/hello
Hello, world!
```