MacにDocker - Dockerfile

[MacにDocker](http://qiita.com/sakasa/items/d32f2cab50a597b5eb50)
ここの子ページ的な
※どんどんMacが関係なくなっていきます。。

#Dockerfileって
インフラの構成管理を記述したファイルです。
DockerfileをもとにしてDockerの「イメージ」を作成することができます。
参考
http://www.atmarkit.co.jp/ait/articles/1407/08/news031.html

#Dockerfileの基本
##基本構成
「Docker」という名前のテキストファイルで作成します。（拡張子なし）
ファイル名は「Dockerfile」以外にすることも可能です。（その場合、イメージ生成時にファイル名を指定する）

###基本構文

```text:Dockerfileの基本構文
命令 引数
```
「命令」は慣例的に大文字で書くことになっているようです（小文字でも大丈夫らしい）

###コメント
Dockerfile内のコメントは先頭に「#」をつけます

```
# コメント
命令 引数    #　コメント（命令の後ろに書くこともできる）
```

##ファイルの作成

**FROM命令（必須項目）：ベースイメージの記述**

生成するイメージのもととなるDockerイメージを記述します。

```text:centos7をベースイメージにする場合
FROM centos:7
```
タグを省略した場合、最新バージョン（latest）がベースイメージに適用されます。

**MAINTAINER命令：作成者**

Dockerfileの作成者を記述します。

```
MAINTAINER [なまえ email etc...]
```

##Dockerイメージの作成

`docker build`コメンドを使ってイメージを作成します。


```text:docker_buildコマンド構文
docker build -t [生成するイメージ名]:[タグ] [-f　Dockerfile名] [Dockerfileのパス]
```

`-f Dockerfile名`は省略可

**centos7をベースイメージにしたDockerイメージを生成**

任意のディレクトリにDockerfileを作成

```bash:
$ mkdir docker_newcentos && cd　$_
$ touch Dockerfile
```

```test:Dockerfileの内容
# ベースイメージ
FROM centos:7
```

このDockerfileからnewcentosという名前のイメージをタグ1.0で生成します。

```text:docker_build実行
$ docker build -t newcentos:1.0 .
```
※Dockerfileが同じディレクトリにない場合はパスの部分を変更してください

生成されたDockerイメージを確認

```bash:
$ docker images
REPOSITORY       TAG       IMAGE ID        CREATED         SIZE
〜〜
centos           7         980e0e4c79ec    9 weeks ago     196.8 MB　　　　#　指定したベースイメージ
newcentos        1.0       980e0e4c79ec    9 weeks ago     196.8 MB　　　　#　生成したイメージ
〜〜
```

#コマンド／デーモンの実行
##RUN命令：コマンドの実行
ベースイメージに対して、何らかのコメンドを実行するときにはRUN命令を使用します。

```text:RUN命令の構文
RUN [実行したいコマンド]
```

コマンドは以下の形式で記述することができます。

- Shell形式
- Exec形式

Exec形式を使用した場合、シェルを介さずコマンドを実行するため、$HOMEのような環境変数が使用できません。

**各記述の形式でRUN命令を記述**

```test:Dockerfileの内容
# ベースイメージ
FROM centos:7

# 作成者
MAINTAINER My name xxx@xxx.xxx

#RUN命令
RUN echo Shell形式
RUN ["echo", "Exec形式"]  # Exec形式はjson配列で指定（カンマ区切りで引数を渡す）
RUN ["/bin/bash", "-c", "echo 'Exec形式でbash実行'"]
```
```bash:docker_build実行
$ docker build -t newcentos .
Sending build context to Docker daemon 2.048 kB
Step 1 : FROM centos:7
 ---> 980e0e4c79ec
Step 2 : MAINTAINER My name xxx@xxx.xxx
 ---> Using cache
 ---> bc5fba1209df
Step 3 : RUN echo Shell形式
 ---> Running in 17060f88e995
Shell形式
 ---> e5adcb924e02
Removing intermediate container 17060f88e995
Step 4 : RUN echo Exec形式
 ---> Running in c31c94077774
Exec形式
 ---> 9dd3abe09173
Removing intermediate container c31c94077774
Step 5 : RUN /bin/bash -c echo 'Exec形式でbash実行'
 ---> Running in 90e956ce7581
Exec形式でbash実行
 ---> 78b707c8ad4e
Removing intermediate container 90e956ce7581
Successfully built 78b707c8ad4e
```

**Dockerイメージ生成時の実行コマンドの確認**
`docker history`コマンドを実行します。

```bash:docker_history
$ docker history newcentos
IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
78b707c8ad4e        3 minutes ago       /bin/bash -c echo 'Exec形式でbash実行'               0 B
9dd3abe09173        3 minutes ago       echo Exec形式                                     0 B
e5adcb924e02        3 minutes ago       /bin/sh -c echo Shell形式                         0 B
bc5fba1209df        5 minutes ago       /bin/sh -c #(nop)  MAINTAINER My name xxx@xxx   0 B
〜〜
```
新しいコマンドから順に表示されます。

##CMD命令：デーモンの実行
Dockerファイルで生成したイメージから起動したコンテナ内でコマンドを実行するときに使います。
Dockerfile内では1つだけ記述することができます。（複数記述した場合、最後のCMD命令のみ有効になります。）

```bash:CMD命令の構文
CMD [実行したいコマンド]
```

コマンドは以下の形式で記述することができます。

- Shell形式
- Exec形式
- ENTRYPOINT命令のパラメータとしての記述（後述）

**RUN命令でhttpdをインストールし、CMD命令でデーモン実行**

```text:Dockerfileの内容
# ベースイメージ
FROM centos:7

# 作成者
MAINTAINER My name xxx@xxx.xxx

# httpdインストール
RUN ["yum", "-y", "install", "httpd"]

# httpdデーモン実行
CMD ["/usr/sbin/httpd", "-D", "FOREGROUND"]
```
```bash:docker_build実行
$ docker build -t newcentos .
Sending build context to Docker daemon 2.048 kB
Step 1 : FROM centos:7
 ---> 980e0e4c79ec
Step 2 : MAINTAINER My name xxx@xxx.xxx
 ---> Using cache
 ---> bc5fba1209df
Step 3 : RUN yum -y install httpd
 〜〜キャッシュを使用しない場合、インストールの内容が表示〜〜
 ---> Using cache
 ---> 6040399c29cf
Step 4 : CMD /usr/sbin/httpd -D FOREGROUND
 ---> Running in 327b9d032b0b
 ---> c284aa940bea
Removing intermediate container 327b9d032b0b
Successfully built c284aa940bea
```
```bash:コンテナの起動
$ docker run -d -p 80:80 newcentos
$ docker ps -a
CONTAINER ID    IMAGE            COMMAND                  CREATED             STATUS         PORTS                  NAMES
0137e17bb071    newcentos        "/usr/sbin/httpd -D F"   16 seconds ago      Up 15 seconds  0.0.0.0:80->80/tcp     stoic_volhard
```
ブラウザで確認
***
<img width="1017" alt="スクリーンショット 2016-11-12 14.04.05.png" src="https://qiita-image-store.s3.amazonaws.com/0/81753/6fedaaf0-6414-df90-72d5-ad716179d0c5.png">
***

##ENTRYPOINT命令：デーモンの実行
Dockerファイルで生成したイメージからコンテナを起動するため`docker run`コマンドを実行したタイミングで実行されます。

```bash:ENTRYPOINT命令の構文
ENTRYPOINT [実行したいコマンド]
```

コマンドは以下の形式で記述することができます。

- Shell形式
- Exec形式

**CMD命令とENTRYPOINT命令の違い**

- CMD命令：`docker run`コマンド実行時に引数で指定したコマンドが優先実行される
- ENTRYPOINT命令：`docker run`コマンド実行時に引数でコマンドを渡しても、ENTRYPOINT命令のコマンドが優先して実行される

##ONBUILD命令：ビルド完了後に実行
DockerfileにONBUILD命令でコマンドを記述し生成したイメージを、他のDockerfileのベースイメージとして設定しビルドしたときに、実行されるコマンドを記述します。

```bash:ONBUILD命令の構文
ONBUILD [実行したいコマンド]
```

**イメージ生成時にローカル環境のファイルを配置する**

元にするDockerfileを作成

```text:Dockerfile.baseの内容
# ベースイメージ
FROM centos:7

# 作成者
MAINTAINER My name xxx@xxx.xxx

# httpdインストール
RUN ["yum", "-y", "install", "httpd"]

# index.htmlを配置
ONBUILD ADD index.html /var/www/html/

# httpdデーモン実行
CMD ["/usr/sbin/httpd", "-D", "FOREGROUND"]
```
```bash:docker_build実行
$ docker build -t newcentos-base -f Dockerfile.base .
Sending build context to Docker daemon 3.072 kB
Step 1 : FROM centos:7
 ---> 980e0e4c79ec
Step 2 : MAINTAINER My name xxx@xxx.xxx
 ---> Using cache
 ---> bc5fba1209df
Step 3 : RUN yum -y install httpd
 ---> Using cache
 ---> 6040399c29cf
Step 4 : ONBUILD add index.html /var/www/html/
 ---> Running in 8c9c43bcbc7d
 ---> 3bbb7f39a522
Removing intermediate container 8c9c43bcbc7d
Step 5 : CMD /usr/sbin/httpd -D FOREGROUND
 ---> Running in 0767db8d5e62
 ---> 81a773a4e983
Removing intermediate container 0767db8d5e62
Successfully built 81a773a4e983
```

index.htmlを用意する

```html:index.html
<h1>newcentos</h1>
```

newcentos-baseをベースイメージにしたDockerfileを作成


```text:Dockerfileの内容
# ベースイメージ
FROM newcentos-base
```
```bash:docker_build実行
$ docker build -t newcentos .
Sending build context to Docker daemon 4.096 kB
Step 1 : FROM newcentos-base
# Executing 1 build trigger...
Step 1 : ADD index.html /var/www/html/
 ---> 8aea3e8a06a7
Removing intermediate container bc5f65a9a0d7
Successfully built 8aea3e8a06a7
```
```bash:コンテナの起動
$ docker run -d -p 80:80 newcentos
$ docker ps -a
CONTAINER ID        IMAGE            COMMAND                  CREATED             STATUS                   PORTS                  NAMES
da982eaa44b1        newcentos        "/usr/sbin/httpd -D F"   7 seconds ago       Up 5 seconds             0.0.0.0:80->80/tcp     romantic_leavitt
```

ブラウザで確認
***
<img width="399" alt="スクリーンショット 2016-11-12 14.59.18.png" src="https://qiita-image-store.s3.amazonaws.com/0/81753/56e86168-a244-fef3-41ec-db25dd2ef810.png">
***

#環境／ネットワーク
##ENV命令：環境変数の設定

```text:ENV命令の構文
ENV [キー名] [値]
or
ENV [キー名]=[値] # 一度のENV命令で複数の値を設定できる
```
```text:ENV命令の例
ENV name "氏 名"
ENV nickname=にっくねーむ\
    age=17
```

##WORKDIR命令：作業ディレクトリの指定
Dockerfileに記述したコマンドをを実行する作業ディレクトリを指定します。
ENV命令で指定した環境変数を使用することもできます。

```text:WORKDIR命令の構文
WORKDIR [作業ディレクトリのパス]
```

Dockerfileに書かれた次の命令のコマンドを実行するための作業ディレクトリになります。

- RUN命令
- CMD命令
- ENTRYPOINT命令
- COPY命令
- ADD命令

##USER命令：ユーザの指定
イメージ実行やDockerfileの命令に書かれたコマンドを実行するユーザを指定します。
あらかじめRUN命令でユーザを作成する必要があります。

```text:USER命令の構文
USER [ユーザ名／ID]
```

Dockerfileに書かれた次の命令のコマンドを実行するためのユーザになります。

- RUN命令
- CMD命令
- ENTRYPOINT命令

##LABEL命令：ラベルの指定
イメージにバージョン情報やコメントなどの情報を設定できます。

```text:LABEL命令の構文
LABEL [キー名]=[値]
```
```text:LABEL命令の例
LABEL title="newcentos-image"
LABEL version="1.0"
```

##EXPOSE命令：ポートの設定
コンテナの公開ポートを指定します。

```text:EXPOSE命令の構文
EXPOSE [ポート番号]
```

#ファイルシステムの設定
##ADD命令：ファイル／ディレクトリの追加
イメージにホスト上のファイルやディレクトリを追加します。

```text:ADD命令の構文
ADD ホストのファイルパス Dockerイメージのファイルパス
```

##COPY命令：ファイルのコピー
イメージにホスト上のファイルをコピーします。

```text:COPY命令の構文
COPY ホストのファイルパス Dockerイメージのファイルパス
```

##VOLUME命令：ボリュームのマウント
イメージにボリュームを割り当てます。

```text:VOLUME命令の構文
VOLUME ["/マウントポイント"]
```

**ログ用コンテナとwebサーバコンテナを作成し、webサーバのログをログ用コンテナに保存**

ログ用イメージの作成〜コンテナ起動

```text:Dockerfile.logimage
# ベースイメージ
FROM centos:7

# 作成者
MAINTAINER My name xxx@xxx.xxx

# ボリュームの作成
RUN ["mkdir", "/var/log/httpd"]
VOLUME ["/var/log/httpd"]
```
```bash:docker_build実行
$ docker build -t newcentos-log -f Dockerfile.logimage .
Sending build context to Docker daemon  5.12 kB
Step 1 : FROM centos:7
 ---> 980e0e4c79ec
Step 2 : MAINTAINER My name xxx@xxx.xxx
 ---> Using cache
 ---> bc5fba1209df
Step 3 : RUN mkdir /var/log/httpd
 ---> Running in 37239b7c88b2
 ---> 0a5c5a2aa1b8
Removing intermediate container 37239b7c88b2
Step 4 : VOLUME /var/log/httpd
 ---> Running in 96c1136b865b
 ---> 55d7f7bc9378
Removing intermediate container 96c1136b865b
Successfully built 55d7f7bc9378
```
```bash:ログ用コンテナの起動
$ docker run -it --name log-container newcentos-log
$ docker ps -a
CONTAINER ID        IMAGE            COMMAND                  CREATED             STATUS                   PORTS                  NAMES
0b86062b4737        newcentos-log    "/bin/bash"              15 seconds ago      Up 13 seconds                                   log-container
```

webサーバ用イメージの作成〜コンテナ起動

```text:Dockerfile.webimage
# ベースイメージ
FROM centos:7

# 作成者
MAINTAINER My name xxx@xxx.xxx

# httpdインストール
RUN ["yum", "-y", "install", "httpd"]

# httpdデーモン実行
CMD ["/usr/sbin/httpd", "-D", "FOREGROUND"]
```
```bash:docker_build実行
$ docker build -t newcentos-web -f Dockerfile.webimage .
Sending build context to Docker daemon 6.144 kB
Step 1 : FROM centos:7
 ---> 980e0e4c79ec
Step 2 : MAINTAINER My name xxx@xxx.xxx
 ---> Using cache
 ---> bc5fba1209df
Step 3 : RUN yum -y install httpd
 ---> Using cache
 ---> 6040399c29cf
Step 4 : CMD /usr/sbin/httpd -D FOREGROUND
 ---> Using cache
 ---> c284aa940bea
Successfully built c284aa940bea
```
```bash:webサーバ用コンテナの起動
$ docker run -d --name web-container -p 80:80 --volumes-from log-container newcentos-web
$ docker ps -a
CONTAINER ID        IMAGE            COMMAND                  CREATED             STATUS                   PORTS                  NAMES
3ba08c15127c        newcentos-web    "/usr/sbin/httpd -D F"   6 seconds ago       Up 4 seconds             0.0.0.0:80->80/tcp     web-container
0b86062b4737        newcentos-log    "/bin/bash"              9 minutes ago       Up 9 minutes                                    log-container
```

ログの確認

```:ログコンテナで確認
[root@0b86062b4737 /]# cd /var/log/httpd/
[root@0b86062b4737 httpd]# ls
access_log  error_log
```