書籍「Dockerによるアプリケーション開発環境構築ガイド」part2 Dockerfile記述方法

# はじめに

以下の書籍の演習をやったので、そのまとめ。
Docker初心者でも実際に手を動かしながら、Dockerの概念や基本を学ぶことが出来るので良本だと思います。演習のホストOSはCentOS7で試しています。


書名：[Dockerによるアプリケーション開発環境構築ガイド](https://www.amazon.co.jp/Docker%E3%81%AB%E3%82%88%E3%82%8B%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E9%96%8B%E7%99%BA%E7%92%B0%E5%A2%83%E6%A7%8B%E7%AF%89%E3%82%AC%E3%82%A4%E3%83%89-%E6%AB%BB%E4%BA%95-%E6%B4%8B%E4%B8%80%E9%83%8E/dp/4839964580)
著者：櫻井 洋一郎, 村崎 大輔 (著)

### 関連
[[part1] part1 docker基本コマンド](https://qiita.com/s_szk/items/fa9512d0d5c28e7deaa3)
[[part3] Baseimage-dockerを使った1コンテナでの複数サービス管理](https://qiita.com/s_szk/items/09de0a16663e0c80babc)

#DockerfileによるDockerイメージの作成
`docker build`コマンドにより、Dockerfileで定義した一連の手続きを実行してイメージ作成できる

#####FROM ベースとなるDockerイメージの指定
*タグ名やdigest名を指定しない場合、latestというタグ名が使われる

```
[root@testvm Dockerfile]# cat from/Dockerfile_simple 
FROM ubuntu

RUN echo foo
RUN echo bar

[root@testvm Dockerfile]# docker build -f from/Dockerfile_simple -t build:from_simple .
Sending build context to Docker daemon  72.7 kB
Step 1/3 : FROM ubuntu
Trying to pull repository docker.io/library/ubuntu ... 
latest: Pulling from docker.io/library/ubuntu
7ddbc47eeb70: Pull complete 
c1bbdc448b72: Pull complete 
8c3b70e39044: Pull complete 
45d437916d57: Pull complete 
Digest: sha256:6e9f67fa63b0323e9a1e587fd71c561ba48a034504fb804fd26fd8800039835d
Status: Downloaded newer image for docker.io/ubuntu:latest
 ---> 775349758637
Step 2/3 : RUN echo foo
 ---> Running in d3c97cc0ca90

foo
 ---> aa90c50f3a31
Removing intermediate container d3c97cc0ca90
Step 3/3 : RUN echo bar
 ---> Running in b18878ac3caa

bar
 ---> 3129b3f87c7b
Removing intermediate container b18878ac3caa
Successfully built 3129b3f87c7b

[root@testvm Dockerfile]# docker images
REPOSITORY               TAG                 IMAGE ID            CREATED             SIZE
build                    from_simple         3129b3f87c7b        16 minutes ago      64.2 MB
sample/ubuntu_with_php   1_0                 351b1877a1a0        About an hour ago   206 MB
docker.io/ubuntu         16.04               5f2bf26e3524        3 weeks ago         123 MB
docker.io/ubuntu         latest              775349758637        3 weeks ago         64.2 MB
docker.io/hello-world    latest              fce289e99eb9        10 months ago       1.84 kB
```

#####digest名を指定したFROM
digest

- イメージの内容が完全に同一であることを保証したい場合に利用できる
- Dockerレジストリにpushされているものにしか付与されない

```
[root@testvm Dockerfile]# cat from/Dockerfile_digest 
FROM ubuntu@sha256:e27e9d7f7f28d67aa9e2d7540bdc2b33254b452ee8e60f388875e5b7d9b2b696

RUN echo foo
RUN echo bar
[root@testvm Dockerfile]# docker images --digests
REPOSITORY               TAG                 DIGEST                                                                    IMAGE ID            CREATED             SIZE
build                    from_simple         <none>                                                                    3129b3f87c7b        18 minutes ago      64.2 MB
sample/ubuntu_with_php   1_0                 <none>                                                                    351b1877a1a0        About an hour ago   206 MB
docker.io/ubuntu         16.04               sha256:bb5b48c7750a6a8775c74bcb601f7e5399135d0a06de004d000e05fd25c1a71c   5f2bf26e3524        3 weeks ago         123 MB
docker.io/ubuntu         latest              sha256:6e9f67fa63b0323e9a1e587fd71c561ba48a034504fb804fd26fd8800039835d   775349758637        3 weeks ago         64.2 MB
docker.io/hello-world    latest              sha256:4df8ca8a7e309c256d60d7971ea14c27672fc0d10c5f303856d7bc48f8cc17ff   fce289e99eb9        10 months ago       1.84 kB

[root@testvm Dockerfile]# docker images
REPOSITORY               TAG                 IMAGE ID            CREATED             SIZE
build                    from_digest         3129b3f87c7b        22 minutes ago      64.2 MB
build                    from_simple         3129b3f87c7b        22 minutes ago      64.2 MB
sample/ubuntu_with_php   1_0                 351b1877a1a0        About an hour ago   206 MB
docker.io/ubuntu         16.04               5f2bf26e3524        3 weeks ago         123 MB
docker.io/ubuntu         latest              775349758637        3 weeks ago         64.2 MB
docker.io/hello-world    latest              fce289e99eb9        10 months ago       1.84 kB
```

#####ENV 環境変数の指定
以下のどちらのファイルの書き方でも指定できる

```
[root@testvm Dockerfile]# cat env/Dockerfile_first 
FROM ubuntu

ENV myName John Doe
ENV myDog Rex The Dog
ENV myCat fluffy

RUN echo "$myName, $myDog, $myCat"
[root@testvm Dockerfile]# cat env/Dockerfile_second 
FROM ubuntu
ENV myName="John Doe" myDog=Rex\ The\ Dog \
    myCat=fluffy

RUN echo "$myName, $myDog, $myCat"
[root@testvm Dockerfile]# docker build -f env/Dockerfile_second -t build:env_second .
Sending build context to Docker daemon  72.7 kB
Step 1/3 : FROM ubuntu
 ---> 775349758637
Step 2/3 : ENV myName "John Doe" myDog Rex\ The\ Dog myCat fluffy
 ---> Running in 5477587e40c4
 ---> 6ae375f8167e
Removing intermediate container 5477587e40c4
Step 3/3 : RUN echo "$myName, $myDog, $myCat"
 ---> Running in 4132c1dc3898

John Doe, Rex The Dog, fluffy
 ---> d521daf65407
Removing intermediate container 4132c1dc3898
Successfully built d521daf65407
[root@testvm Dockerfile]# docker images
REPOSITORY               TAG                 IMAGE ID            CREATED             SIZE
build                    env_second          d521daf65407        6 seconds ago       64.2 MB
```

step3/3で環境変数が正しくechoできていることがわかる。
また`docker history`コマンドでイメージの履歴も確認できる。

```
[root@testvm Dockerfile]# docker history build:env_second 
IMAGE               CREATED              CREATED BY                                      SIZE                COMMENT
d521daf65407        About a minute ago   /bin/sh -c echo "$myName, $myDog, $myCat"       0 B                 
6ae375f8167e        About a minute ago   /bin/sh -c #(nop)  ENV myName=John Doe myD...   0 B                 
775349758637        3 weeks ago          /bin/sh -c #(nop)  CMD ["/bin/bash"]            0 B                 
<missing>           3 weeks ago          /bin/sh -c mkdir -p /run/systemd && echo '...   7 B                 
<missing>           3 weeks ago          /bin/sh -c set -xe   && echo '#!/bin/sh' >...   745 B               
<missing>           3 weeks ago          /bin/sh -c [ -z "$(apt-get indextargets)" ]     987 kB              
<missing>           3 weeks ago          /bin/sh -c #(nop) ADD file:a48a5dc1b9dbfc6...   63.2 MB   
```

##### LABEL メタデータの付与

```
[root@testvm Dockerfile]# cat label/Dockerfile 
FROM ubuntu:16.04
LABEL maintainer="Image maintainer team <hogehoge@example.com>" 
[root@testvm Dockerfile]# docker build -f label/Dockerfile -t build:label .
Sending build context to Docker daemon  72.7 kB
Step 1/2 : FROM ubuntu:16.04
 ---> 5f2bf26e3524
Step 2/2 : LABEL maintainer "Image maintainer team <hogehoge@example.com>"
 ---> Running in 9537e0b33209
 ---> 029aea12235a
Removing intermediate container 9537e0b33209
Successfully built 029aea12235a
```

`docker inspect`でイメージの詳細を確認できる

```
[root@testvm Dockerfile]# docker inspect build:label
[
    {
        "Id": "sha256:029aea12235a101dfd046e7824607026696caa70f0f3b082d72fbd95c5b0b51b",
        "RepoTags": [
            "build:label"
        ],
        "RepoDigests": [],
        "Parent": "sha256:5f2bf26e35249d8b47f002045c57b2ea9d8ba68704f45f3c209182a7a2a9ece5",
        "Comment": "",
        "Created": "2019-11-25T02:17:57.917903693Z",
        "Container": "9537e0b332090b0fec319cf6a76cee190a2ef94580d0796bdb2bcc4f1416c005",
        "ContainerConfig": {
            "Hostname": "9537e0b33209",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
            ],
            "Cmd": [
                "/bin/sh",
                "-c",
                "#(nop) ",
                "LABEL maintainer=Image maintainer team <hogehoge@example.com>"
            ],
            "ArgsEscaped": true,
            "Image": "sha256:5f2bf26e35249d8b47f002045c57b2ea9d8ba68704f45f3c209182a7a2a9ece5",
            "Volumes": null,
            "WorkingDir": "",
            "Entrypoint": null,
            "OnBuild": [],
            "Labels": {
                "maintainer": "Image maintainer team <hogehoge@example.com>"
            }
        },
        "DockerVersion": "1.13.1",
        "Author": "",
(以下省略)
```

#####RUN shellの実行

書き方は以下の２種類(1. shell form と 2. exec form)
1.の場合,/bin/sh -cで実行される
2.の場合,SHELLの値は関係無く、実行可能コマンドを直接実行する

```
[root@testvm Dockerfile]# cat run/Dockerfile 
FROM ubuntu:16.04

RUN echo $0
RUN ["sh", "-c", "echo $0"]
```

ubuntuでは/bin/bashがdashとなっており、()という表現を受け付けないため、以下のDockerfileではそれぞれ、成功・失敗する

```
[root@testvm Dockerfile]# cat run/shell/Dockerfile_success 
FROM ubuntu:16.04
RUN ["/bin/bash", "-c", "FOO=(`ls`); echo $FOO"]
[root@testvm Dockerfile]# 
[root@testvm Dockerfile]# cat run/shell/Dockerfile_with_error 
FROM ubuntu:16.04
RUN FOO=(`ls`); echo $FOO
```

また、1.と2.で環境変数の展開も異なる
 # 3のexec formではコマンドシェル経由ではなく、実行ファイルを直接実行されているため、環境変数は展開されない。

```
[root@testvm Dockerfile]# cat run/env/Dockerfile 
FROM ubuntu:16.04

# 1. set environment variable.
ENV HOGE hoge

# 2. echo by "shell form".
RUN echo $HOGE

# 3. echo by "exec form", without shell.
RUN ["echo", "$HOGE"]

# 4. echo by "exec form", with shell.
RUN ["/bin/sh", "-c", "echo $HOGE"]
[root@testvm Dockerfile]# docker build -f run/env/Dockerfile  -t build:run_env ./run/env/
Sending build context to Docker daemon 2.048 kB
Step 1/5 : FROM ubuntu:16.04
 ---> 5f2bf26e3524
Step 2/5 : ENV HOGE hoge
 ---> Running in a8da17cf3a87
 ---> 3580b7a865c6
Removing intermediate container a8da17cf3a87
Step 3/5 : RUN echo $HOGE
 ---> Running in b7c7dbb13af9

hoge
 ---> a1b63fac8a8e
Removing intermediate container b7c7dbb13af9
Step 4/5 : RUN echo $HOGE
 ---> Running in cb5081f725cf

$HOGE
 ---> 1e5e35162487
Removing intermediate container cb5081f725cf
Step 5/5 : RUN /bin/sh -c echo $HOGE
 ---> Running in 8447b4ad41ce

hoge
 ---> 425615fdbaec
Removing intermediate container 8447b4ad41ce
Successfully built 425615fdbaec
```

`docker history`コマンドで確認すると、# 3の箇所(IMAGE ID=1e5e35162487の部分)では/bin/sh -c 経由ではなく、直接コマンド実行されているのが分かる。

```
[root@testvm Dockerfile]# docker history build:run_env 
IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
425615fdbaec        5 minutes ago       /bin/sh -c echo $HOGE                           0 B                 
1e5e35162487        5 minutes ago       echo $HOGE                                      0 B                 
a1b63fac8a8e        5 minutes ago       /bin/sh -c echo $HOGE                           0 B                 
3580b7a865c6        5 minutes ago       /bin/sh -c #(nop)  ENV HOGE=hoge                0 B                 
5f2bf26e3524        3 weeks ago         /bin/sh -c #(nop)  CMD ["/bin/bash"]            0 B                 
<missing>           3 weeks ago         /bin/sh -c mkdir -p /run/systemd && echo '...   7 B                 
<missing>           3 weeks ago         /bin/sh -c set -xe   && echo '#!/bin/sh' >...   745 B               
<missing>           3 weeks ago         /bin/sh -c rm -rf /var/lib/apt/lists/*          0 B                 
<missing>           3 weeks ago         /bin/sh -c #(nop) ADD file:9511990749b593a...   123 MB    
```

#####SHELL [shell form]が利用された際に使用されるコマンドを指定

Linux：デフォルトは`/bin/sh`, `-c`
Windows：デフォルトは`cmd`, `\S`, `\C`

先ほどエラーになっていたDockerfileをSHELLコマンドでシェル指定することで、正しく実行できる

```
root@testvm Dockerfile]# cat shell/Dockerfile 
FROM ubuntu:16.04
SHELL ["/bin/bash", "-c"]
RUN FOO=(`ls`); echo $FOO
[root@testvm Dockerfile]# docker build -f shell/Dockerfile -t build:shell .
Sending build context to Docker daemon  72.7 kB
Step 1/3 : FROM ubuntu:16.04
 ---> 5f2bf26e3524
Step 2/3 : SHELL /bin/bash -c
 ---> Running in 119915db64d1
 ---> a3de822059a0
Removing intermediate container 119915db64d1
Step 3/3 : RUN FOO=(`ls`); echo $FOO
 ---> Running in d30fec3eada9

bin
 ---> 7dfba7eb3110
Removing intermediate container d30fec3eada9
Successfully built 7dfba7eb3110
```

#####WORKDIR 相対パスを指定した時のディレクトリを指定

複数回記述した場合はその都度ワークディレクトリが変わる

```
[root@testvm Dockerfile]# cat workdir/Dockerfile 
FROM ubuntu:16.04
WORKDIR /a
WORKDIR b
WORKDIR c
RUN pwd
[root@testvm Dockerfile]# docker build -f workdir/Dockerfile -t build:workdir .
Sending build context to Docker daemon  72.7 kB
Step 1/5 : FROM ubuntu:16.04
 ---> 5f2bf26e3524
Step 2/5 : WORKDIR /a
 ---> 7b584249016a
Removing intermediate container d8c9f332724e
Step 3/5 : WORKDIR b
 ---> 9c6281858297
Removing intermediate container 2c8f90abb159
Step 4/5 : WORKDIR c
 ---> 557de1101958
Removing intermediate container fae71b6ce31d
Step 5/5 : RUN pwd
 ---> Running in e52da7fd8e55

/a/b/c
 ---> d85bec60cbbd
Removing intermediate container e52da7fd8e55
Successfully built d85bec60cbbd
```

#####ADD ファイル、ディレクトリ、URLリソースなどをコンテナ上にコピー

`tar`でアーカイブしたファイルを展開した状態でコピーする。
Linuxコンテナの場合のみ、`--chown=<user>:<group>`のオプションが可能。

```
[root@testvm Dockerfile]# cat add/Dockerfile 
FROM ubuntu:16.04

# 1. Make work directory at first.
WORKDIR /add

# 2. Add normal file.
ADD ./files/not_archived_file .
RUN ls -al /add

# 3. Add remote resource to container.
ADD https://github.com/docker/docker-ce/blob/master/README.md .
RUN ls -al /add

# 4. Uncompress and unarchive tar files.
ADD ./files/tar_bzip2_file.tar.bzip2 ./files/tar_file.tar ./files/tar_file.tar ./files/tar_gz_file.tar.gz ./files/tar_xz_file.tar.xz ./
RUN ls -al /add

# 5. NOT unarchive compressed files.
ADD ./files/bzip2_file.bz2 ./files/gzip_file.gz ./files/xz_file.xz ./files/zip_file.zip ./
RUN ls -al /add

# 6. Add directory.
ADD ./files ./files
RUN ls -al /add/files
[root@testvm Dockerfile]# ll add/files/
total 32
-rw-r--r--. 1 root root   14 Mar 11  2018 bzip2_file.bz2
-rw-r--r--. 1 root root   30 Mar 11  2018 gzip_file.gz
-rw-r--r--. 1 root root    0 Mar 11  2018 not_archived_file
-rw-r--r--. 1 root root  396 Mar 11  2018 tar_bzip2_file.tar.bzip2
-rw-r--r--. 1 root root 2560 Mar 11  2018 tar_file.tar
-rw-r--r--. 1 root root  354 Mar 11  2018 tar_gz_file.tar.gz
-rw-r--r--. 1 root root  368 Mar 11  2018 tar_xz_file.tar.xz
-rw-r--r--. 1 root root   32 Mar 11  2018 xz_file.xz
-rw-r--r--. 1 root root  166 Mar 11  2018 zip_file.zip

[root@testvm Dockerfile]# docker build -f add/Dockerfile -t build:add ./add/
Sending build context to Docker daemon 13.82 kB
Step 1/12 : FROM ubuntu:16.04
 ---> 5f2bf26e3524
Step 2/12 : WORKDIR /add
 ---> Using cache
 ---> 440865d619ab
Step 3/12 : ADD ./files/not_archived_file .
 ---> e4bf598e3a12
Removing intermediate container 4bdea1d3d886
Step 4/12 : RUN ls -al /add
 ---> Running in faf4dd8b160d

total 0
drwxr-xr-x. 1 root root 31 Nov 25 05:05 .
drwxr-xr-x. 1 root root 17 Nov 25 05:05 ..
-rw-r--r--. 1 root root  0 Mar 11  2018 not_archived_file
 ---> 0015e1708251
Removing intermediate container faf4dd8b160d
Step 5/12 : ADD https://github.com/docker/docker-ce/blob/master/README.md .
Downloading 69.95 kB
 ---> 67462f31863f
Removing intermediate container a16cf375b2a1
Step 6/12 : RUN ls -al /add
 ---> Running in 94f495a81b87

total 72
drwxr-xr-x. 1 root root    23 Nov 25 05:05 .
drwxr-xr-x. 1 root root     6 Nov 25 05:05 ..
-rw-------. 1 root root 69950 Jan  1  1970 README.md
-rw-r--r--. 1 root root     0 Mar 11  2018 not_archived_file
 ---> 19d1c776bb1f
Removing intermediate container 94f495a81b87
Step 7/12 : ADD ./files/tar_bzip2_file.tar.bzip2 ./files/tar_file.tar ./files/tar_file.tar ./files/tar_gz_file.tar.gz ./files/tar_xz_file.tar.xz ./
 ---> da128d3f06eb
Removing intermediate container fd468212c260
Step 8/12 : RUN ls -al /add
 ---> Running in f1b7f3f6342d

total 88
drwxr-xr-x. 1 root root      166 Nov 25 05:05 .
drwxr-xr-x. 1 root root        6 Nov 25 05:05 ..
-rw-r--r--. 1  501 dialout   239 Feb 18  2018 ._tar_bzip2_file
-rw-r--r--. 1  501 dialout   239 Feb 18  2018 ._tar_file
-rw-r--r--. 1  501 dialout   239 Feb 18  2018 ._tar_gz_file
-rw-r--r--. 1  501 dialout   239 Feb 18  2018 ._tar_xz_file
-rw-------. 1 root root    69950 Jan  1  1970 README.md
-rw-r--r--. 1 root root        0 Mar 11  2018 not_archived_file
-rw-r--r--. 1  501 dialout     0 Feb 18  2018 tar_bzip2_file
-rw-r--r--. 1  501 dialout     0 Feb 18  2018 tar_file
-rw-r--r--. 1  501 dialout     0 Feb 18  2018 tar_gz_file
-rw-r--r--. 1  501 dialout     0 Feb 18  2018 tar_xz_file
 ---> 60f2893855fb
Removing intermediate container f1b7f3f6342d
Step 9/12 : ADD ./files/bzip2_file.bz2 ./files/gzip_file.gz ./files/xz_file.xz ./files/zip_file.zip ./
 ---> b9a584f7c670
Removing intermediate container 39c3bead5ed3
Step 10/12 : RUN ls -al /add
 ---> Running in 1c3c46862f65

total 104
drwxr-xr-x. 1 root root       86 Nov 25 05:05 .
drwxr-xr-x. 1 root root        6 Nov 25 05:05 ..
-rw-r--r--. 1  501 dialout   239 Feb 18  2018 ._tar_bzip2_file
-rw-r--r--. 1  501 dialout   239 Feb 18  2018 ._tar_file
-rw-r--r--. 1  501 dialout   239 Feb 18  2018 ._tar_gz_file
-rw-r--r--. 1  501 dialout   239 Feb 18  2018 ._tar_xz_file
-rw-------. 1 root root    69950 Jan  1  1970 README.md
-rw-r--r--. 1 root root       14 Mar 11  2018 bzip2_file.bz2
-rw-r--r--. 1 root root       30 Mar 11  2018 gzip_file.gz
-rw-r--r--. 1 root root        0 Mar 11  2018 not_archived_file
-rw-r--r--. 1  501 dialout     0 Feb 18  2018 tar_bzip2_file
-rw-r--r--. 1  501 dialout     0 Feb 18  2018 tar_file
-rw-r--r--. 1  501 dialout     0 Feb 18  2018 tar_gz_file
-rw-r--r--. 1  501 dialout     0 Feb 18  2018 tar_xz_file
-rw-r--r--. 1 root root       32 Mar 11  2018 xz_file.xz
-rw-r--r--. 1 root root      166 Mar 11  2018 zip_file.zip
 ---> cf451a8b0cbb
Removing intermediate container 1c3c46862f65
Step 11/12 : ADD ./files ./files
 ---> 76a5e5890369
Removing intermediate container 0a11f98e0b9e
Step 12/12 : RUN ls -al /add/files
 ---> Running in f64b9cb5af2d

total 32
drwxr-xr-x. 2 root root  215 Nov 25 05:05 .
drwxr-xr-x. 1 root root   19 Nov 25 05:05 ..
-rw-r--r--. 1 root root   14 Mar 11  2018 bzip2_file.bz2
-rw-r--r--. 1 root root   30 Mar 11  2018 gzip_file.gz
-rw-r--r--. 1 root root    0 Mar 11  2018 not_archived_file
-rw-r--r--. 1 root root  396 Mar 11  2018 tar_bzip2_file.tar.bzip2
-rw-r--r--. 1 root root 2560 Mar 11  2018 tar_file.tar
-rw-r--r--. 1 root root  354 Mar 11  2018 tar_gz_file.tar.gz
-rw-r--r--. 1 root root  368 Mar 11  2018 tar_xz_file.tar.xz
-rw-r--r--. 1 root root   32 Mar 11  2018 xz_file.xz
-rw-r--r--. 1 root root  166 Mar 11  2018 zip_file.zip
 ---> f1d67759af12
Removing intermediate container f64b9cb5af2d
Successfully built f1d67759af12
```

#####COPY ※ADDコマンドと同様

ADDコマンドとの違いは

- multi staging docker機能で作成した別のコンテナの中にあるファイルをコピーする
- URLリソースの指定不可
- tarでアーカイブしたファイルを展開しない

以下の例では、一つのDockerfile内で2つのイメージをベースに使い、イメージ間（コンテナ間）でファイルのコピーをしている

```
[root@testvm Dockerfile]# cat copy/Dockerfile 
# Use multi stage docker feature.
FROM busybox AS build_env

# 1. Make work directory at first.
WORKDIR /multistage

# 2. Copy
COPY ./files/multi_stage_docker_file .
RUN ls -al /multistage


# Second docker definition.
FROM ubuntu:16.04

# 3. Make work directory at first.
WORKDIR /copy

# 4. Copy normal file.
COPY ./files/not_archived_file .
RUN ls -al /copy

# 5. Copy normal file.
COPY --from=build_env /multistage/multi_stage_docker_file .
RUN ls -al /copy

# 6. NOT Uncompress and unarchive tar files.
COPY ./files/tar_bzip2_file.tar.bzip2 ./files/tar_file.tar ./files/tar_file.tar ./files/tar_gz_file.tar.gz ./files/tar_xz_file.tar.xz ./
RUN ls -al /copy

# 7. NOT unarchive compressed files.
COPY ./files/bzip2_file.bz2 ./files/gzip_file.gz ./files/xz_file.xz ./files/zip_file.zip ./
RUN ls -al /copy

# 8. Copy directory.
COPY ./files ./files
RUN ls -al /copy/files
[root@testvm Dockerfile]# ll copy/files/
total 32
-rw-r--r--. 1 root root   14 Mar 11  2018 bzip2_file.bz2
-rw-r--r--. 1 root root   30 Mar 11  2018 gzip_file.gz
-rw-r--r--. 1 root root    0 Mar 11  2018 multi_stage_docker_file
-rw-r--r--. 1 root root    0 Mar 11  2018 not_archived_file
-rw-r--r--. 1 root root  396 Mar 11  2018 tar_bzip2_file.tar.bzip2
-rw-r--r--. 1 root root 2560 Mar 11  2018 tar_file.tar
-rw-r--r--. 1 root root  354 Mar 11  2018 tar_gz_file.tar.gz
-rw-r--r--. 1 root root  368 Mar 11  2018 tar_xz_file.tar.xz
-rw-r--r--. 1 root root   32 Mar 11  2018 xz_file.xz
-rw-r--r--. 1 root root  166 Mar 11  2018 zip_file.zip

[root@testvm Dockerfile]# docker build -f copy/Dockerfile -t build:copy ./copy/
Sending build context to Docker daemon 14.34 kB
Step 1/16 : FROM busybox AS build_env
Error parsing reference: "busybox AS build_env" is not a valid repository/tag: invalid reference format
(buildでエラーが出たため以下省略)
```

#####EXPOSE コンテナが利用するポートの宣言（実行上、意味はない）
実際にコンテナの特定ポートにアクセスするためには、`docker run`コマンドでコンテナ作成の際に-pオプションによるホスト・コンテナ間のポート接続が必要

```
[root@testvm Dockerfile]# cat expose/Dockerfile 
FROM nginx

EXPOSE 443
```

#####ENTRYPOINT コンテナ起動時の実行コマンドを指定
RUNコマンドと同様に２種類（1.shell form, 2. exec form(推奨)）の書き方がある。
docker run実行時に引数が設定された場合、EXTRYPOINTのコマンドの引数となって実行される。
ENTRYPOINTを複数記述した場合は最後の記述のみ有効となる。

例えば、以下の通り1.shell formでは記述したコマンドはPID 1以外、 2.exec formで記述したコマンドはPID 1となる。
しかし、`docker stop`や`docker kill`ではPID 1のプロセスに対してSIGTERMやSIGKILLが送信されるため、実行した本来のコマンドがSIGNALを受信できないため、1.shell formは非推奨となっている。

#####~ENTRYPOINT実行コマンドのSIGNALのハンドリングについて~
下記のSIGNALを受け取るスクリプトを用意して動作確認する。
※3秒毎にrunning...と表示して、SIGTERMもしくは(SIGHUP/SIGINT/SIGQUIT)を受け取るとメッセージを表示する（SIGTERMの場合はそれに加えて終了する）

```
[root@testvm Dockerfile]# cat entrypoint/signal/sample.sh 
#!/bin/sh

trap_term_signal() {
    echo "trapped SIGTERM"
	exit 0
}

trap_some_signal() {
    echo "trapped 1 or 2 or 3 SIGNAL"
}

trap "trap_term_signal" TERM
trap "trap_some_signal" 1 2 3

while :
do
    echo "running..."
    sleep 3
done
```

 2.exec formの場合

```
[root@testvm Dockerfile]# cat entrypoint/signal/Dockerfile_exec 
FROM ubuntu:16.04

COPY sample.sh /sample.sh
ENTRYPOINT ["/sample.sh"]
[root@testvm Dockerfile]# docker build  -f entrypoint/signal/Dockerfile_exec -t build:entrypoint_signal_exec ./entrypoint/signal/
Sending build context to Docker daemon 4.096 kB
Step 1/3 : FROM ubuntu:16.04
 ---> 5f2bf26e3524
Step 2/3 : COPY sample.sh /sample.sh
 ---> 2a264ecbfe21
Removing intermediate container a4ba48b86e68
Step 3/3 : ENTRYPOINT /sample.sh
 ---> Running in 5c9871565f00
 ---> 17a857ae75e7
Removing intermediate container 5c9871565f00
Successfully built 17a857ae75e7
[root@testvm Dockerfile]# docker run --name entrypoint_signal_exec --rm -it build:entrypoint_signal_exec 
running...
running...
```

別のターミナルで以下を実行

```
[root@testvm ~]# docker kill -s SIGHUP entrypoint_signal_exec
entrypoint_signal_exec
```

すると、はじめのターミナル上で以下のように表示される。SIGHUPなので終了しない。

```
running...
trapped 1 or 2 or 3 SIGNAL
running...
running...
```

次に、以下の通り、`docker stop`でSIGTERMをコンテナに送信する

```
[root@testvm ~]# docker stop entrypoint_signal_exec
entrypoint_signal_exec
```

すると、はじめのターミナルで動作が終了する

```
running...
trapped SIGTERM
[root@testvm Dockerfile]# 
```

1.shell formの場合
同様にコンテナ起動＆SIGNAL送信すると以下のようになる

```
[root@testvm Dockerfile]# cat entrypoint/signal/Dockerfile_shell 
FROM ubuntu:16.04

COPY sample.sh /sample.sh
ENTRYPOINT /sample.sh
[root@testvm Dockerfile]# docker build  -f entrypoint/signal/Dockerfile_shell -t build:entrypoint_signal_shell ./entrypoint/signal/
Sending build context to Docker daemon 4.096 kB
Step 1/3 : FROM ubuntu:16.04
 ---> 5f2bf26e3524
Step 2/3 : COPY sample.sh /sample.sh
 ---> Using cache
 ---> 53543e654866
Step 3/3 : ENTRYPOINT /sample.sh
 ---> Running in aa143a231c49
 ---> e7872e3206a0
Removing intermediate container aa143a231c49
Successfully built e7872e3206a0
[root@testvm Dockerfile]# 
[root@testvm Dockerfile]# docker run --name entrypoint_signal_shell --rm -it build:entrypoint_signal_shell 
running...
```

この場合、別ターミナルで以下の通りSIGTERMを送信しても`running`のまま表示は変わらない。
これはshell formの場合はPID1のプロセスがsample.shではないため、SIGNALが届いていないことに起因する。

```
[root@testvm ~]# docker kill -s SIGHUP entrypoint_signal_shell 
entrypoint_signal_shell
```

以下のようにdocker stopを実行した場合は10秒ほど経った後にコンテナが停止し、`entrypoint_signal_shell`と表示される。
これはdocker stopの仕様によるものであり、
PID1のプロセスにSIGTERMを送信して10秒ほど反応が返らない場合、SIGKILLを送信し強制終了する。

```
[root@testvm ~]# docker stop entrypoint_signal_shell 
entrypoint_signal_shell
```

#####~ENTRYPOINTとRUNの違いについて~
RUN：イメージをbuild（作成）するために実際にコンテナでコマンドを実行する。
ENTRYPOINT：docker run（起動）する際にコマンドを実行する。つまり、動作しないコマンドでもbuildは成功してしまう。

#####CMD コンテナ起動時の実行コマンドを指定

※ENTRYPOINTとの違い：
docker runの際に実行されるデフォルトコマンドを指定するために使う
例えば以下のように使う

```
[root@testvm Dockerfile]# cat cmd/parameter/Dockerfile 
FROM ubuntu:16.04

ENTRYPOINT ["top"]
CMD ["-H"]
[root@testvm Dockerfile]# docker build  -f cmd/parameter/Dockerfile -t build:cmd_parameter ./cmd/parameter/
Sending build context to Docker daemon 2.048 kB
Step 1/3 : FROM ubuntu:16.04
 ---> 5f2bf26e3524
Step 2/3 : ENTRYPOINT top
 ---> Running in 72b1284dd07c
 ---> 86cfbe89f68e
Removing intermediate container 72b1284dd07c
Step 3/3 : CMD -H
 ---> Running in 9692599383c8
 ---> 332002a8f056
Removing intermediate container 9692599383c8
Successfully built 332002a8f056
[root@testvm Dockerfile]# docker run --rm -it build:cmd_parameter 

top - 07:13:27 up  9:25,  0 users,  load average: 0.07, 0.07, 0.06
Threads:   1 total,   1 running,   0 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.1 us,  0.2 sy,  0.0 ni, 99.6 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :   498736 total,    24964 free,   185872 used,   287900 buff/cache
KiB Swap:  2097148 total,  1986556 free,   110592 used.   264796 avail Mem 

  PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND                                                                                                     
    1 root      20   0   36692   1720   1256 R  6.2  0.3   0:00.04 top   
```

docker runの実行時に引数を与えると、CMDの内容を上書きできる。
以下ではbuild時の`-H`（スレッド単位での表示）を`-b`（バッチモード）で上書きしている。

```
[root@testvm Dockerfile]# docker run --rm -it build:cmd_parameter  -b
top - 07:21:13 up  9:32,  0 users,  load average: 0.01, 0.06, 0.05
Tasks:   1 total,   1 running,   0 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.1 us,  0.2 sy,  0.0 ni, 99.6 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :   498736 total,    24720 free,   183884 used,   290132 buff/cache
KiB Swap:  2097148 total,  1986556 free,   110592 used.   266728 avail Mem 

  PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND
    1 root      20   0   36520   1596   1236 R  0.0  0.3   0:00.02 top
```