---
# System prepended metadata

title: Docker (using Docker)

---

# Docker (using Docker)

## 3章
debianのイメージをダウンロードした後、dockerはそのイメージを実行中のコンテナに変え、その中で指定されたコマンドである`echo "helloworld"`を実行

```
$docker run debian echo "helloworld"
Unable to find image 'debian:latest' locally
latest: Pulling from library/debian
4a56a430b2ba: Pull complete
Digest: sha256:e25b64a9cf82c72080074d6b1bba7329cdd752d51574971fd37731ed164f3345
Status: Downloaded newer image for debian:latest
helloworld
```

dockerに対してtty付きのインタラクティブセッションを要求。
/bin/bashコマンドによりbashシェルを立ち上げ。シェルを終了すると、コンテナも停止。
**コンテナが動作するのは、そのコンテナのメインプロセスが動作している間**だけ
```
$docker run -i -t debian /bin/bash
root@4c32199f8d09:/# echo "helloworld"
helloworld
root@4c32199f8d09:/# exit
exit
```



```
 -i, --interactive                    Keep STDIN open even if not attached
      --ip string                      IPv4 address (e.g., 172.30.100.104)
      --ip6 string                     IPv6 address (e.g., 2001:db8::33)
      --ipc string                     IPC mode to use
      --isolation string               Container isolation technology
      --kernel-memory bytes            Kernel memory limit

-t, --tty                             Allocate a pseudo-TTY
      --ulimit ulimit                  Ulimit options (default [])
```
`docker inspect (image-NAME or id etc...)`のようにコンテナの名前やIDをつけて実行すれば、指定したコンテナのさらに詳しい情報がわかる

`docker diff NAME`で実行中のコンテナで変更されたファイルのリストを表示できる。

`docker logs NAME`でそのコンテナ内で起きた事の全リストが返される。

壊したコンテナのシェルから抜けると、コンテナも停止。
```
docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
```

`docker ps -a`で停止した（終了した）もの含めた全てのコンテナのリストがでる。

終了したコンテナは`docker start`で再起動できる。

停止したコンテナを一括削除
```
$docker rm -v $(docker ps -aq -f status=exited)
c342da3e33e7
ea22dc95b763
4c32199f8d09
f5a0d114dae1
e38835607e6a
```


DockerFileがあるdirで`docker build`を実行
```
 -t, --tag list                Name and optionally a tag in the 'name:tag' format
      --target string           Set the target build stage to build.
      --ulimit ulimit           Ulimit options (default [])
```

```
$docker build -t test/cowsay-dockerfile .
Sending build context to Docker daemon  2.048kB
Step 1/2 : FROM debian:wheezy
```

`ENTRYPOINT`命令は、`docker run`に渡される任意の引数を扱う実行ファイルを指定する。

`COPY`命令は、ファイルをホストからイメージのファイルシステムにコピーするだけの命令。cpによく似ており、第一引数はホスト上のファイル、第二引数はコピー先のパス

```
$docker pull redis

$docker run --name myredis -d redis
```
でRedisのコンテナをバックグラウンド実行

docker logsを使ってコンテナからの出力を見れる。
DBのアプリケーションがないため、ツールのredis-cliを使う。
そのため、redis-cliを動作させる為の新たなコンテナを立ち上げ、2つのコンテナをリンクさせる。
```
$docker run --rm -it --link myredis:redis redis /bin/bash
root@1c53bc25fcdc:/data# redis-cli -h redis -p 6379
redis:6379> ping
PONG
redis:6379> set "abc" 123
OK
redis:6379> get "abc"
"123"
redis:6379> exit
root@1c53bc25fcdc:/data# exit
exit

```

`--link`コマンドを使うことで、コンテナをネットワークで接続できる。

`--link myredis:redis`という引数で、新たなコンテナを既存の"myredis"コンテナに接続するよう支持。
Dockerはその為に新しいコンテナの/etc/hostsに"redis"というエントリをセットアップし、そのエントリが"myredis"のIPアドレスを指すようにする。
これでRedisのコンテナのIPアドレスを渡したり、調べたりすることなく`redis-cli`で"redis"というホスト名を使えばいいだけとなる。
```
root@28eb77979812:/data# cat /etc/hosts
127.0.0.1	localhost
::1	localhost ip6-localhost ip6-loopback
fe00::0	ip6-localnet
ff00::0	ip6-mcastprefix
ff02::1	ip6-allnodes
ff02::2	ip6-allrouters
172.17.0.2	redis 7bb881666fd8 myredis
172.17.0.3	28eb77979812
```

**ボリューム**によって、コンテナとホスト、あるいは他のコンテナ間で簡単に共有できる何か。ホストに直接マウントされるファイルもしくはディレクトリ。
即ち、ボリュームは他のコンテナと共有でき、全ての変更は直接ホストのファイルシステムに対して行われる。

`VOLUME`命令で、もしくはdocker runで-vフラグを指定することで実現
```
VOLUME /data
$docker run -v /data test/webserver
```
```
$docker run --rm -it --link myredis:redis redis /bin/bash
root@79c61a4274a7:/data# redis-cli -h redis -p 6379
redis:6379> set "persistence " "test"
OK
redis:6379> save
OK
redis:6379> exit
root@79c61a4274a7:/data# exit
exit
$docker run --rm --volumes-from myredis -v $(pwd)/backup:/backup debian cp /data/dump.rdb /backup/
$ls backup
dump.rdb
```
ホスト上の既知のディレクトリをマウントするのに、`-v`という引数を用い、新しいコンテナをRedisのDBのフォルダに接続する為に--volume-from を使った。

## 4章

docker buildコマンドにはDockerfile と ビルドコンテキスト(必須ではない)が必要。
ビルドコンテキストは、DockerfileのADD, COPY命令から参照できるローカルファイルやディレクトリの集合。通常はディレクトリへのパスとして指定。
`$docker build -t test/cowsay-dockerfile .`の場合、ビルドコンテキストをカレントのワーキングディレクトリである`.`に設定。ビルドコンテキストは、このパスの配下にある全てのファイルとディレクトリで構成され、ビルドプロセスの一部としてDockerデーモンに送られる。

コンテキスト内のDockerfileの場所は、-fの引数で指定可能

### イメージのレイヤ
Dockerfile中のそれぞれの命令は、新しいイメージの**レイヤ**を生成する。
イメージを構成する全レイヤはdocker historyコマンドで見れる。

ビルドに失敗した場合、直掩のレイヤを起動すると非常に役立つ。
```
docker history redis:latest
IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
63130206b0fa        9 days ago          /bin/sh -c #(nop)  CMD ["redis-server"]         0B
<missing>           9 days ago          /bin/sh -c #(nop)  EXPOSE 6379                  0B
<missing>           9 days ago          /bin/sh -c #(nop)  ENTRYPOINT ["docker-entry…   0B
<missing>           9 days ago          /bin/sh -c #(nop) COPY file:df205a0ef6e6df89…   374B
<missing>           9 days ago          /bin/sh -c #(nop) WORKDIR /data                 0B
<missing>           9 days ago          /bin/sh -c #(nop)  VOLUME [/data]               0B
<missing>           9 days ago          /bin/sh -c mkdir /data && chown redis:redis …   0B
<missing>           9 days ago          /bin/sh -c set -eux;   savedAptMark="$(apt-m…   24.6MB
<missing>           9 days ago          /bin/sh -c #(nop)  ENV REDIS_DOWNLOAD_SHA=21…   0B
<missing>           9 days ago          /bin/sh -c #(nop)  ENV REDIS_DOWNLOAD_URL=ht…   0B
<missing>           9 days ago          /bin/sh -c #(nop)  ENV REDIS_VERSION=5.0.5      0B
<missing>           9 days ago          /bin/sh -c set -eux;  savedAptMark="$(apt-ma…   4.04MB
<missing>           9 days ago          /bin/sh -c #(nop)  ENV GOSU_VERSION=1.11        0B
<missing>           9 days ago          /bin/sh -c groupadd -r -g 999 redis && usera…   329kB
<missing>           10 days ago         /bin/sh -c #(nop)  CMD ["bash"]                 0B
<missing>           10 days ago         /bin/sh -c #(nop) ADD file:1901172d265456090…   69.2MB
```
例として次のDockerfileをビルドする。
```
FROM busybox:latest

RUN echo "This should work"
RUN /bin/bash -c echo "This won't"
```

```
 docker build -t echotest .
Sending build context to Docker daemon  2.048kB
Step 1/3 : FROM busybox:latest
latest: Pulling from library/busybox
7c9d20b9b6cd: Pull complete
Digest: sha256:fe301db49df08c384001ed752dff6d52b4305a73a7f608f21528048e8a08b51e
Status: Downloaded newer image for busybox:latest
 ---> 19485c79a9bb
Step 2/3 : RUN echo "This should work"
 ---> Running in 3265de6f5e3e // 1
This should work
Removing intermediate container 3265de6f5e3e // 2
 ---> ed5e5aeb5e97 // 3
Step 3/3 : RUN /bin/bash -c echo "This won't"
 ---> Running in 26ea24307007
/bin/sh: /bin/bash: not found
The command '/bin/sh -c /bin/bash -c echo "This won't"' returned a non-zero code: 127
```

- 1: 命令を実行する為にDockerが起動した一時的な**コンテナ**ID
- 2: 一時コンテナの削除
- 3: コンテナから作成されたイメージのID


### 外界とコンテナの接続

コンテナ内でWebサーバを動作させているとする。
外部からアクセスできるようにするには、`-p`, `-P`コマンドでポートを公開することで出来る。
このコマンドは、ホストのポートをコンテナにフォワードする。

`docker run -d -p 8000:80 nginx`の`-p 8000:80`という引数は、Dockerに対して干すおtの8000番ポートをコンテナの80番ポートにフォワードするように指示する。