初心者のDocker事始め（Dockerfile編

# やること

* [初心者のDocker事始め](https://qiita.com/s-yoshida/items/928fc0ad7282ed62def2)と同じことをDockerfileを使って行う。
* その上で、Dockerfileを何となく雰囲気で理解する。

# 始める前の理解

「Dockerfile＝コンテナの構成を明記したファイル」的な感じでOKです。って言っても「で、結局何に使うの？」となりそうなので、「Dockerイメージを作るためのファイル」ってな感じでOKです。

# Dockerfileの書式と命令

Dockerfileの書式は非常にシンプルです。

```sh
# コメント
命令 引数
```

例：

```sh
RUN echo 'Hello world!!'
```

命令はDockerfileリファレンスに書いてあるので参照ください。

# Nginxのイメージを作成してみる

nginx:latestのイメージをベースに新しくイメージを作ってみます。vimが入ってない場合は適当に作成してください。

```sh
$ vim Dockerfile
FROM nginx
RUN apt-get update -y
RUN apt-get install -y vim
EXPOSE 80
$ docker build -t sample/nginx .
```

<details><summary>インストールログ</summary>
Sending build context to Docker daemon  2.048kB  
Step 1/4 : FROM nginx  
latest: Pulling from library/nginx  
27833a3ba0a5: Pull complete  
ea005e36e544: Pull complete  
d172c7f0578d: Pull complete  
Digest: sha256:e71b1bf4281f25533cf15e6e5f9be4dac74d2328152edf7ecde23abc54e16c1c  
Status: Downloaded newer image for nginx:latest  
 ---> 27a188018e18  
Step 2/4 : RUN apt-get update  
 ---> Running in c2ec20e68c82  
Get:1 http://security-cdn.debian.org/debian-security stretch/updates InRelease [94.3 kB]  
Ign:2 http://cdn-fastly.deb.debian.org/debian stretch InRelease  
Get:3 http://cdn-fastly.deb.debian.org/debian stretch-updates InRelease [91.0 kB]  
Get:4 http://security-cdn.debian.org/debian-security stretch/updates/main amd64 Packages [485 kB]  
Get:5 http://cdn-fastly.deb.debian.org/debian stretch Release [118 kB]  
Get:6 http://cdn-fastly.deb.debian.org/debian stretch Release.gpg [2434 B]  
Get:7 http://cdn-fastly.deb.debian.org/debian stretch-updates/main amd64 Packages [11.1 kB]  
Get:8 http://cdn-fastly.deb.debian.org/debian stretch/main amd64 Packages [7082 kB]  
Fetched 7884 kB in 3s (2056 kB/s)  
Reading package lists...  
Removing intermediate container c2ec20e68c82  
 ---> 391603069f19  
Step 3/4 : RUN apt-get install -y vim  
 ---> Running in daf96b852dec  
Reading package lists...  
Building dependency tree...  
Reading state information...  
The following additional packages will be installed:  
  libgpm2 vim-common vim-runtime xxd  
Suggested packages:  
  gpm ctags vim-doc vim-scripts  
The following NEW packages will be installed:  
  libgpm2 vim vim-common vim-runtime xxd  
0 upgraded, 5 newly installed, 0 to remove and 5 not upgraded.  
Need to get 6766 kB of archives.  
After this operation, 31.2 MB of additional disk space will be used.  
Get:1 http://cdn-fastly.deb.debian.org/debian stretch/main amd64 xxd amd64 2:8.0.0197-4+deb9u1 [132 kB]  
Get:2 http://cdn-fastly.deb.debian.org/debian stretch/main amd64 vim-common all 2:8.0.0197-4+deb9u1 [159 kB]  
Get:3 http://cdn-fastly.deb.debian.org/debian stretch/main amd64 libgpm2 amd64 1.20.4-6.2+b1 [34.2 kB]  
Get:4 http://cdn-fastly.deb.debian.org/debian stretch/main amd64 vim-runtime all 2:8.0.0197-4+deb9u1 [5407 kB]  
Get:5 http://cdn-fastly.deb.debian.org/debian stretch/main amd64 vim amd64 2:8.0.0197-4+deb9u1 [1034 kB]  
debconf: delaying package configuration, since apt-utils is not installed  
Fetched 6766 kB in 1s (4189 kB/s)  
Selecting previously unselected package xxd.  
(Reading database ... 7027 files and directories currently installed.)  
Preparing to unpack .../xxd_2%3a8.0.0197-4+deb9u1_amd64.deb ...  
Unpacking xxd (2:8.0.0197-4+deb9u1) ...  
Selecting previously unselected package vim-common.  
Preparing to unpack .../vim-common_2%3a8.0.0197-4+deb9u1_all.deb ...  
Unpacking vim-common (2:8.0.0197-4+deb9u1) ...  
Selecting previously unselected package libgpm2:amd64.  
Preparing to unpack .../libgpm2_1.20.4-6.2+b1_amd64.deb ...  
Unpacking libgpm2:amd64 (1.20.4-6.2+b1) ...  
Selecting previously unselected package vim-runtime.  
Preparing to unpack .../vim-runtime_2%3a8.0.0197-4+deb9u1_all.deb ...  
Adding 'diversion of /usr/share/vim/vim80/doc/help.txt to /usr/share/vim/vim80/doc/help.txt.vim-tiny by vim-runtime'  
Adding 'diversion of /usr/share/vim/vim80/doc/tags to /usr/share/vim/vim80/doc/tags.vim-tiny by vim-runtime'  
Unpacking vim-runtime (2:8.0.0197-4+deb9u1) ...  
Selecting previously unselected package vim.  
Preparing to unpack .../vim_2%3a8.0.0197-4+deb9u1_amd64.deb ...  
Unpacking vim (2:8.0.0197-4+deb9u1) ...  
Setting up xxd (2:8.0.0197-4+deb9u1) ...  
Setting up libgpm2:amd64 (1.20.4-6.2+b1) ...  
Processing triggers for libc-bin (2.24-11+deb9u4) ...  
Setting up vim-common (2:8.0.0197-4+deb9u1) ...  
Setting up vim-runtime (2:8.0.0197-4+deb9u1) ...  
Setting up vim (2:8.0.0197-4+deb9u1) ...  
update-alternatives: using /usr/bin/vim.basic to provide /usr/bin/vim (vim) in auto mode  
update-alternatives: using /usr/bin/vim.basic to provide /usr/bin/vimdiff (vimdiff) in auto mode  
update-alternatives: using /usr/bin/vim.basic to provide /usr/bin/rvim (rvim) in auto mode  
update-alternatives: using /usr/bin/vim.basic to provide /usr/bin/rview (rview) in auto mode  
update-alternatives: using /usr/bin/vim.basic to provide /usr/bin/vi (vi) in auto mode  
update-alternatives: warning: skip creation of /usr/share/man/fr/man1/vi.1.gz because associated file /usr/share/man/fr/man1/vim.1.gz (of link group vi) doesn't exist  
update-alternatives: warning: skip creation of /usr/share/man/it/man1/vi.1.gz because associated file /usr/share/man/it/man1/vim.1.gz (of link group vi) doesn't exist  
update-alternatives: warning: skip creation of /usr/share/man/pl/man1/vi.1.gz because associated file /usr/share/man/pl/man1/vim.1.gz (of link group vi) doesn't exist  
update-alternatives: warning: skip creation of /usr/share/man/ru/man1/vi.1.gz because associated file /usr/share/man/ru/man1/vim.1.gz (of link group vi) doesn't exist  
update-alternatives: warning: skip creation of /usr/share/man/ja/man1/vi.1.gz because associated file /usr/share/man/ja/man1/vim.1.gz (of link group vi) doesn't exist  
update-alternatives: warning: skip creation of /usr/share/man/man1/vi.1.gz because associated file /usr/share/man/man1/vim.1.gz (of link group vi) doesn't exist  
update-alternatives: using /usr/bin/vim.basic to provide /usr/bin/view (view) in auto mode  
update-alternatives: warning: skip creation of /usr/share/man/fr/man1/view.1.gz because associated file /usr/share/man/fr/man1/vim.1.gz (of link group view) doesn't exist  
update-alternatives: warning: skip creation of /usr/share/man/it/man1/view.1.gz because associated file /usr/share/man/it/man1/vim.1.gz (of link group view) doesn't exist  
update-alternatives: warning: skip creation of /usr/share/man/pl/man1/view.1.gz because associated file /usr/share/man/pl/man1/vim.1.gz (of link group view) doesn't exist  
update-alternatives: warning: skip creation of /usr/share/man/ru/man1/view.1.gz because associated file /usr/share/man/ru/man1/vim.1.gz (of link group view) doesn't exist  
update-alternatives: warning: skip creation of /usr/share/man/ja/man1/view.1.gz because associated file /usr/share/man/ja/man1/vim.1.gz (of link group view) doesn't exist  
update-alternatives: warning: skip creation of /usr/share/man/man1/view.1.gz because associated file /usr/share/man/man1/vim.1.gz (of link group view) doesn't exist  
update-alternatives: using /usr/bin/vim.basic to provide /usr/bin/ex (ex) in auto mode  
update-alternatives: warning: skip creation of /usr/share/man/fr/man1/ex.1.gz because associated file /usr/share/man/fr/man1/vim.1.gz (of link group ex) doesn't exist  
update-alternatives: warning: skip creation of /usr/share/man/it/man1/ex.1.gz because associated file /usr/share/man/it/man1/vim.1.gz (of link group ex) doesn't exist  
update-alternatives: warning: skip creation of /usr/share/man/pl/man1/ex.1.gz because associated file /usr/share/man/pl/man1/vim.1.gz (of link group ex) doesn't exist  
update-alternatives: warning: skip creation of /usr/share/man/ru/man1/ex.1.gz because associated file /usr/share/man/ru/man1/vim.1.gz (of link group ex) doesn't exist  
update-alternatives: warning: skip creation of /usr/share/man/ja/man1/ex.1.gz because associated file /usr/share/man/ja/man1/vim.1.gz (of link group ex) doesn't exist  
update-alternatives: warning: skip creation of /usr/share/man/man1/ex.1.gz because associated file /usr/share/man/man1/vim.1.gz (of link group ex) doesn't exist  
update-alternatives: using /usr/bin/vim.basic to provide /usr/bin/editor (editor) in auto mode  
update-alternatives: warning: skip creation of /usr/share/man/fr/man1/editor.1.gz because associated file /usr/share/man/fr/man1/vim.1.gz (of link group editor) doesn't exist  
update-alternatives: warning: skip creation of /usr/share/man/it/man1/editor.1.gz because associated file /usr/share/man/it/man1/vim.1.gz (of link group editor) doesn't exist  
update-alternatives: warning: skip creation of /usr/share/man/pl/man1/editor.1.gz because associated file /usr/share/man/pl/man1/vim.1.gz (of link group editor) doesn't exist  
update-alternatives: warning: skip creation of /usr/share/man/ru/man1/editor.1.gz because associated file /usr/share/man/ru/man1/vim.1.gz (of link group editor) doesn't exist  
update-alternatives: warning: skip creation of /usr/share/man/ja/man1/editor.1.gz because associated file /usr/share/man/ja/man1/vim.1.gz (of link group editor) doesn't exist  
update-alternatives: warning: skip creation of /usr/share/man/man1/editor.1.gz because associated file /usr/share/man/man1/vim.1.gz (of link group editor) doesn't exist  
Removing intermediate container daf96b852dec  
 ---> fb4d084d4ad7  
Step 4/4 : EXPOSE 80  
 ---> Running in b2a581711062  
Removing intermediate container b2a581711062  
 ---> a37e2ae89839  
Successfully built a37e2ae89839  
Successfully tagged sample/nginx:latest
</details>

```sh
$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
sample/nginx        latest              a37e2ae89839        5 minutes ago       157MB
nginx               latest              27a188018e18        12 days ago         109MB
```

> FROM nginx

imageを作成する時のベースになるイメージを記述します。WindowsとかLinuxを使う時に素のままではなくアプリをインストールしたり設定を変更すると思いますが、その「WindowsとかLinux」みたいな感じです。

> RUN apt-get update -y
> RUN apt-get install -y vim

Nginxのイメージにはvimが入っていないのでインストールします。この他にもRUNコマンドを使って様々なカスタマイズが可能です。

> EXPOSE 80

接続用リッスンポート設定です。

# 作成したイメージからコンテナを作成する

```sh
$ docker run -d -p 8080:80 --name test-webserver sample/nginx
$ # docker exec -it test-webserver /bin/bash
$ # vim --help
VIM - Vi IMproved 8.0 (2016 Sep 12, compiled Sep 30 2017 18:21:38)
:
:
$ # exit
$ docker stop test-webserver
```

想定通りvimがインストールされてますね。
一旦コンテナとイメージを削除しておきます。

# ディレクトリをマウントする

ディレクトリのマウントには`VOLUME`命令を利用します。ただし、`docker run`の時のようにホストOS側のディレクトリは指定できません。Dockerfileを以下のように書き換えます。

```txt
FROM nginx
RUN echo "Hello, World" > /usr/share/nginx/html/hello.html
EXPOSE 80
VOLUME /usr/share/nginx/html
```

書き換えたら`docker build`&`docker run`してホストOSのどこが共有ディレクトリになっているのか調べます。

```sh
$ docker build -t sample/nginx .
$ docker run -d -p 8080:80 --name test-webserver sample/nginx
$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS              PORTS                  NAMES
16e9545fffc3        sample/nginx        "nginx -g 'daemon of…"   About a minute ago   Up About a minute   0.0.0.0:8080->80/tcp   test-webserver
$ docker inspect 16e9545fffc3
:
:
"Mounts": [
    {
        "Type": "volume",
        "Name": "043f6045abb2ad6005675850f9d2b71e0e6ad5bd1f8fe33b526aa56daeab6479",
        "Source": "/var/lib/docker/volumes/043f6045abb2ad6005675850f9d2b71e0e6ad5bd1f8fe33b526aa56daeab6479/_data",
        "Destination": "/usr/share/nginx/html",
        "Driver": "local",
        "Mode": "",
        "RW": true,
        "Propagation": ""
    }
],
:
:
```

`/var/lib/docker/volumes/043f6045abb2ad6005675850f9d2b71e0e6ad5bd1f8fe33b526aa56daeab6479/_data`がマウントされていることがわかります。が、そんなディレクトリは無い(´・ω・｀)
[Docker for Macのvolumesの場所](https://qiita.com/uni-3/items/9e912d0d8aa87a398cfc)を参考にしながら進めて確認できた...けど、これじゃ使い勝手が悪い。とは言え`docker run`する時に都度都度設定するのも面倒。さて、どうしたものか。

# 終わり

ってことで次回はdocker-compose。