docker-machineでdockerのコンテナとイメージを理解するまでの流れ


- [2015/10/28] 非推奨になったboot2dockerをdocker-machineコマンドに置き換えました

## 環境

インストールは[DockerToolbox](https://www.docker.com/docker-toolbox)を利用します

- VirtualBox 5.0.8
- boot2docker 1.8.3

## 基礎知識

- コンテナとは、作業履歴のようなもので１接続で行った作業を１つのコンテナとして扱っている
- イメージに接続して作業しexitで抜けた場合、コンテナが生成されるだけでイメージは生成されない
- コンテナ（作業履歴）をコミットすると初めてイメージとして保存される
- つまり、何度作業してもコミットしなければいくらでもやり直せる

## 起動

### 初回起動

`アプリケーション` => `Docker` => `Docker Quickstart Terminal.app`

### 一度停止した後に起動する場合

```bash
docker-machine start default
```

## 停止

```bash
docker-machine stop default
```

## ハローワールド

```bash
docker run ubuntu /bin/echo hello
```

実行結果として以下のように最後に`hello`が出力されれば成功

```bash
Unable to find image 'ubuntu:latest' locally
latest: Pulling from library/ubuntu

c63fb41c2213: Pull complete
99fcaefe76ef: Pull complete
5a4526e952f0: Pull complete
1d073211c498: Pull complete
Digest: sha256:8b1bffa54d8a58395bae61ec32f1a70fc82a939e4a7179e6227eb79e4c3c56f6
Status: Downloaded newer image for ubuntu:latest
hello
```

## Dockerfileからイメージ作成

- Dockerfileはどこに作っても構いません

```bash
vi Dockerfile
```

```bash
FROM ubuntu
RUN apt-get update
```

## Dockerfileをビルド

- repo/sampleがリポジトリで、1.0がタグになります
- Dockerfileをビルドしても、その場にデータが生成される事はありません

```bash
docker build -t repo/sample:1.0 .
```

## イメージ一覧

```bash
docker images
```

helloworldに利用したubuntuと、今ビルドしたrepo/sampleのver1.0が表示されているのが確認できます

```bash
REPOSITORY            TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
repo/sample           1.0                 30244c6b9da6        54 seconds ago      209.2 MB
ubuntu                latest              1d073211c498        5 days ago          187.9 MB
```

## イメージに接続して作業を行う

```bash
docker run -it repo/sample:1.0 /bin/bash
```

`ls`してから`exit`する

## コンテナが作成されているのを確認

- 「-a」オプションは起動していないコンテナも表示

```bash
docker ps -a
```

helloworldのコンテナとrepo/sampleのコンテナが表示されている

```bash
CONTAINER ID        IMAGE                        COMMAND             CREATED             STATUS                        PORTS                                                                                    NAMES
e9f1d3582cf1        repo/sample:1.0              "/bin/bash"         25 seconds ago      Exited (0) 14 seconds ago                                                                                              suspicious_engelbart
9f0cb699701a        ubuntu                       "/bin/echo hello"   5 minutes ago       Exited (0) 5 minutes ago                                                                                               insane_almeida

```

## helloworldのコンテナを削除してみる

```bash
docker rm 9f0cb699701a
```

## コンテナとイメージの動作の違いを確認する

コンテナを起動してアタッチ（attach時はEnter2回押下）

```bash
docker start e9f1d3582cf1
docker attach e9f1d3582cf1
```

接続したコンテナでvimをインストールして、vimが起動できることを確認してexit

```bash
apt-get install vim -y
vim
exit
```

もう一度イメージに接続して`history`を確認してみると、何も作業されていない事になっている

```bash
docker run -it repo/sample:1.0 /bin/bash
```

今度はコンテナへ接続して`history`を確認するとvimのインストールは終わっている

```bash
docker start e9f1d3582cf1
docker attach e9f1d3582cf1
```

つまり、イメージに接続してもイメージ本体に作業履歴は残らず、コンテナとして作業履歴が保存され、コミットコマンドを流すまではイメージとして保存されない

## コミットしてイメージを作ってみる

```bash
docker commit e9f1d3582cf1 repo/sample:1.1
docker images
```

イメージ一覧から1.1のバージョンタグが付与されたイメージが追加されている

```bash
REPOSITORY            TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
repo/sample           1.1                 07c752365c8e        8 seconds ago       252.3 MB
repo/sample           1.0                 30244c6b9da6        12 minutes ago      209.2 MB
ubuntu                latest              1d073211c498        5 days ago          187.9 MB
```

コミットした1.1のイメージに接続して`history`を確認すると、先ほどコンテナで作業したvimのインストール履歴が確認できる

```bash
docker run -it repo/sample:1.1 /bin/bash
```

ここまでで基本操作が一通り完了です。コンテナとイメージを削除して綺麗にします。


## 非稼働コンテナ一括削除

```bash
docker rm `docker ps -a -q --filter 'status=exited'`
```

## イメージ一括削除

一気に消すことはなかなか無いので基本これは使いません

```bash
docker rmi $(docker images -q)
```

ここまでで一旦終了です。何度か繰り返して理解を深めましょう！

## チートシート


### イメージの詳細表示

```bash
docker inspect repo/sample:1.0
```

### 80番ポート待ち受けて起動

```bash
docker run -it -p 80:80 repo/sample:1.0 /bin/bash
```

### 複数Port空ける時

```bash
docker run -it -p 80:80 -p 443:443 repo/sample:1.0 /bin/bash
```

### IPを確認

```bash
docker-machine ip default
```

### 出力されたIPに対してWebで接続してみる

`http://192.168.99.100/`

- nginxやApacheが起動していないとアクセスできない


### イメージ削除

- イメージ削除できない場合、コンテナを先に削除する

```bash
docker rmi IMAGE_ID
```

### イメージ一括削除

一気に消すことはなかなか無いので基本これは使いません

```bash
docker rmi $(docker images -q)
```

### TAG未付与のイメージ一括削除

```bash
docker rmi `docker images -q --filter 'dangling=true'`
```

### 非稼働コンテナ一括削除

```bash
docker rm `docker ps -a -q --filter 'status=exited'`
```

### 起動中コンテナの一括停止

```bash
docker stop `docker ps -a -q --filter 'status=running'`
```

### コンテナからデータコピー

```bash
docker cp ddd629e6073f:/hoge/foo .
```

### コミット

```bash
docker commit 1b2045b4df98 repo/sample:1.1
```

### コミットしたイメージに接続

```bash
docker run -it repo/sample:1.1 /bin/bash
```