DockerfileでDockerコンテナを構築する

DockerfileでDockerを実行したメモです。

Dockerfile

DockerはDockerfileというファイルに環境構築のコードを記述することができます。
Dockerfileを作成することで、常に同じ構成の環境を構築したり、
Dockerfileを配布することで各個人で共通の環境を構築したりすることが出来ます。

Dockerfile作成

Docker Machineを起動してログインします。
インストールなどは下記記事を参照。
pppurple.hatenablog.com

viでDockerfileを作成します。
「Dockerfile」という名前で拡張子なしで作成します。
これがDockerfileのデフォルトの名前のルールになっています。

FROMでベースイメージを指定します。
MAINTAINERで作成者の情報を指定します。
#を記述するとコメントになります。

$ vi Dockerfile
$ cat Dockerfile
# setting base image
FROM centos:centos7

# Author
MAINTAINER pppurple
Dockerfileのビルド

docker buildコマンドでDockerfileをビルドして、dockerイメージを作成します。
-tオプションで「イメージ名:タグ名」を指定します。今回は「sample:0.1」としました。
最後にDockerfileの場所を指定します。今回はカレントディレクトリなのでドットを指定します。

$ docker build -t sample:0.1 .
Sending build context to Docker daemon 2.048 kB
Step 1 : FROM centos:centos7
centos7: Pulling from library/centos
0653bff3c5cf: Pull complete
Digest: sha256:81e4f2f663eaa1bf46ff9be348396dd7053734b257ef4147d7133d6f25bbf7cf
Status: Downloaded newer image for centos:centos7
 ---> 05188b417f30
Step 2 : MAINTAINER pppurple
 ---> Running in b99657b88e9d
 ---> db0b765405cc
Removing intermediate container b99657b88e9d
Successfully built db0b765405cc

初回の実行ではベースイメージのcentosのイメージがローカルに存在しないので、ダウンロードされます。
2回目からはローカルにキャッシュされるため高速になります。
docker imagesで確認してみると、sampleというdockerイメージが作成されていることが分かります。

$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
sample              0.1                 db0b765405cc        40 seconds ago      196.8 MB
Dockerfileを利用してApacheを起動してみる

Dockerfileからイメージを作成してApacheを起動してみます。
httpd_sampleというディレクトリを作成して移動します。

$ mkdir httpd_sample
$ cd httpd_sample/

Dockerfileを作成します。
RUNでOSコマンドを実行できます。yumhttpdをインストールするコマンドを記述します。
CMDでデーモン実行することが出来ます。httpdをforegroundで実行します。

$ vi Dockerfile
$ cat Dockerfile
# setting base image
FROM centos:centos7

# Author
MAINTAINER pppurple

# install Apache http server
RUN ["yum",  "-y", "install", "httpd"]

# start httpd
CMD ["/usr/sbin/httpd", "-D", "FOREGROUND"]
exec形式とshell形式

RUNとCMDはexec形式がshell形式で書けます。
exec形式の場合、下記の様にjson配列で記述します。

# install Apache http server
RUN ["yum",  "-y", "install", "httpd"]

# start httpd
CMD ["/usr/sbin/httpd", "-D", "FOREGROUND"]

shell形式の場合、/bin/shで実行される形で指定します。

# install Apache http server
RUN yum install -y httpd

# start httpd
CMD /usr/sbin/httpd -D FOREGROUND

今回はexec形式で記述します。
httpd_sampleというイメージ名を指定してビルドします。

$ docker build -t httpd_sample .
Sending build context to Docker daemon 2.048 kB
Step 1 : FROM centos:centos7
 ---> 05188b417f30
Step 2 : MAINTAINER 0.1 pppurple
 ---> Running in a124cdc1f2b1
 ---> 9adef1b0b242
Removing intermediate container a124cdc1f2b1
Step 3 : RUN yum install -y httpd
 ---> Running in db42db6cfcce
Loaded plugins: fastestmirror, ovl
Determining fastest mirrors
 * base: ftp.riken.jp
 * extras: ftp.riken.jp
 * updates: ftp.riken.jp
Resolving Dependencies
--> Running transaction check
---> Package httpd.x86_64 0:2.4.6-40.el7.centos.1 will be installed
--> Processing Dependency: httpd-tools = 2.4.6-40.el7.centos.1 for package: httpd-2.4.6-40.el7.centos.1.x86_64
--> Processing Dependency: system-logos >= 7.92.1-1 for package: httpd-2.4.6-40.el7.centos.1.x86_64
--> Processing Dependency: /etc/mime.types for package: httpd-2.4.6-40.el7.centos.1.x86_64
--> Processing Dependency: libaprutil-1.so.0()(64bit) for package: httpd-2.4.6-40.el7.centos.1.x86_64
--> Processing Dependency: libapr-1.so.0()(64bit) for package: httpd-2.4.6-40.el7.centos.1.x86_64
--> Running transaction check
---> Package apr.x86_64 0:1.4.8-3.el7 will be installed
---> Package apr-util.x86_64 0:1.5.2-6.el7 will be installed
---> Package centos-logos.noarch 0:70.0.6-3.el7.centos will be installed
---> Package httpd-tools.x86_64 0:2.4.6-40.el7.centos.1 will be installed
---> Package mailcap.noarch 0:2.1.41-2.el7 will be installed
--> Finished Dependency Resolution

Dependencies Resolved
            :
            :
            :
            :
Complete!
 ---> e7f418a0e428
Removing intermediate container db42db6cfcce
Step 4 : CMD /usr/sbin/httpd -D FOREGROUND
 ---> Running in b16214e739b7
 ---> 5f7abb3c9b8a
Removing intermediate container b16214e739b7
Successfully built 5f7abb3c9b8a

ビルドしたイメージを起動してみます。docker runコマンドで起動します。
-dオプションでバックグラウンドで実行します。
-pオプションでホストOSとコンテナのポート番号のマッピングを指定します。
「ホストのポート番号:コンテナのポート番号」の形式で指定します。
下記の様に指定すると、ホストOSの80ポートにアクセスすると、コンテナの80ポートにアクセスされます。

$ docker run -d -p 80:80 httpd_sample
fe5b2b600b288728a1ebdca059f54a3d4baa36870e68bc3d19e5155e7f68c103

http://192.168.99.100/へアクセスしてみます。
下記のApacheのデフォルト画面が表示されました。
f:id:pppurple:20160711015424p:plain:w500

docker statsコマンドでコンテナの稼働状況を確認してみます。
topコマンドの様な形式で表示され、起動したコンテナが稼働しているのが分かります。

$ docker stats fe5b2b600b

CONTAINER           CPU %               MEM USAGE / LIMIT     MEM %               NET I/O               BLOCK I/O           PIDS
fe5b2b600b          0.01%               3.707 MB / 1.044 GB   0.35%               6.633 kB / 41.94 kB   69.63 kB / 0 B      9
ベースイメージを作成する

ベースイメージを作成することで、他のDockerfileからベースイメージとして指定できるようになります。
共通の環境はベースイメージを利用し、個々の独自の設定はDockerfileで指定するようなことが出来るようになります。

base_sampleというディレクトリを作成して移動します。

$ mkdir base_sample
$ cd base_sample/

Dockerfile.baseという名前でベースイメージとなるファイルを作成します。
ONBUILDでこのDockerfile.baseをベースイメージとするDockerファイルをビルドするときに、
ONBUILDで指定したコマンドが実行されます。
ここではADDコマンドでweb.tarファイルを/var/www/html/配下に配置します。

$ vi Dockerfile.base
$ cat Dockerfile.base
# setting base image
FROM centos:centos7

# Author
MAINTAINER 0.1 pppurple

# install Apache http server
RUN ["yum",  "-y", "install", "httpd"]

# deploy
ONBUILD ADD web.tar /var/www/html/

# start httpd
CMD ["/usr/sbin/httpd", "-D", "FOREGROUND"]

web.tarというファイルを用意します。
これは簡単なhtmlとcssをtarでアーカイブしたものです。
ファイル構成はこんな感じです。

web.tar
  ├─index.html
  └─public/
        └─css/
             └─index.css 

index.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <link href="./public/css/index.css" rel="stylesheet">
    <title>Docker</title>
</head>
<body>
<h1 align="center">Docker httpd sample</h1>
<table class="brwsr1">
    <tbody>
        <tr>
            <th class="r1">name</th>
            <th class="r2">John</th>
            <th class="r3">Mary</th>
            <th class="r4">Larry</th>
        </tr>
        <tr>
            <th class="r1">country</th>
            <td class="r2">America</td>
            <td class="r3">Canada</td>
            <td class="r4">Japan</td>
        </tr>
        <tr>
            <th class="r1">age</th>
            <td class="r2">27</td>
            <td class="r3">22</td>
            <td class="r4">43</td>
        </tr>
        <tr>
            <th class="r1">lang</th>
            <td class="r2">Java</td>
            <td class="r3">Perl</td>
            <td class="r4">Python</td>
        </tr>
    </tbody>
</table>
</body>
</html>

index.css

table.brwsr1 {
    font-size: 12px;
    margin: 0 auto;
    border-collapse: separate;
    border-spacing: 0px 1px;
}
 
table.brwsr1 th {
    padding: 12px;
    vertical-align: middle;
    text-align: left;
    border-bottom: #999 1px solid;
    color: #fff;
}
 
table.brwsr1 td {
    padding: 12px;
    vertical-align: middle;
    text-align: left;
    border-bottom: #999 1px solid;
    font-size: 11px;
}
 
table.brwsr1 th.r1 {
    width: 152px;
    border-right: #999 1px solid;
    background: #447791;
}
 
table.brwsr1 th.r2,
table.brwsr1 td.r2 {
    width: 128px;
    border-left: #fff 1px solid;
    border-right: #999 1px solid;
    background: #5893b1;
}
 
table.brwsr1 th.r2,
table.brwsr1 th.r3,
table.brwsr1 th.r4 {
    text-align: center;
}
 
table.brwsr1 th.r3,
table.brwsr1 td.r3 {
    width: 128px;
    border-left: #fff 1px solid;
    border-right: #999 1px solid;
    background: #7cacc2;
}
 
table.brwsr1 th.r4,
table.brwsr1 td.r4 {
    width: 128px;
    border-left: #fff 1px solid;
    background: #a0c2d3;
}

web.tarをDockerfile.baseと同じ階層に配置します。

$ ll
total 16
-rw-r--r--    1 docker   staff          248 Jul  9 15:27 Dockerfile.base
-rw-r--r--    1 docker   staff        10240 Jul  9 15:39 web.tar

Dockerfile.baseをビルドしてみます。
-tオプションでhttpd_baseというイメージ名を指定します。
-fオプションでDockerfile名を指定します。Dockerfileというファイル名の場合は明示する必要はありませんが、
この場合はDockerfile.baseという名前なので明示的に指定する必要があります。

$ docker build -t httpd_base -f Dockerfile.base .
Sending build context to Docker daemon 2.048 kB
Step 1 : FROM centos:centos7
 ---> 05188b417f30
Step 2 : MAINTAINER 0.1 pppurple
 ---> Using cache
 ---> 9adef1b0b242
Step 3 : RUN yum -y install httpd
 ---> Running in 5c83dde366d1
Loaded plugins: fastestmirror, ovl
Determining fastest mirrors
 * base: www.ftp.ne.jp
 * extras: www.ftp.ne.jp
 * updates: www.ftp.ne.jp
Resolving Dependencies
--> Running transaction check
---> Package httpd.x86_64 0:2.4.6-40.el7.centos.1 will be installed
--> Processing Dependency: httpd-tools = 2.4.6-40.el7.centos.1 for package: httpd-2.4.6-40.el7.centos.1.x86_64
--> Processing Dependency: system-logos >= 7.92.1-1 for package: httpd-2.4.6-40.el7.centos.1.x86_64
--> Processing Dependency: /etc/mime.types for package: httpd-2.4.6-40.el7.centos.1.x86_64
--> Processing Dependency: libaprutil-1.so.0()(64bit) for package: httpd-2.4.6-40.el7.centos.1.x86_64
--> Processing Dependency: libapr-1.so.0()(64bit) for package: httpd-2.4.6-40.el7.centos.1.x86_64
--> Running transaction check
---> Package apr.x86_64 0:1.4.8-3.el7 will be installed
---> Package apr-util.x86_64 0:1.5.2-6.el7 will be installed
---> Package centos-logos.noarch 0:70.0.6-3.el7.centos will be installed
---> Package httpd-tools.x86_64 0:2.4.6-40.el7.centos.1 will be installed
---> Package mailcap.noarch 0:2.1.41-2.el7 will be installed
--> Finished Dependency Resolution

Dependencies Resolved
          :
          :
          :
Dependency Installed:
  apr.x86_64 0:1.4.8-3.el7
  apr-util.x86_64 0:1.5.2-6.el7
  centos-logos.noarch 0:70.0.6-3.el7.centos
  httpd-tools.x86_64 0:2.4.6-40.el7.centos.1
  mailcap.noarch 0:2.1.41-2.el7

Complete!
 ---> 469a95b2c558
Removing intermediate container 5c83dde366d1
Step 4 : ONBUILD add web.tar /var/www/html/
 ---> Running in 9320c104b1af
 ---> 762220c3ffc6
Removing intermediate container 9320c104b1af
Step 5 : CMD /usr/sbin/httpd -D FOREGROUND
 ---> Running in 537125692b61
 ---> 466247b3c857
Removing intermediate container 537125692b61
Successfully built 466247b3c857

docker imagesコマンドで確認してみると、httpd_baseというDockerイメージが作成されています。

$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
httpd_base          latest              466247b3c857        5 seconds ago       316.7 MB

作成したhttpd_baseをベースイメージとしたDockerfileを作成します。
中身はFROMでhttpd_baseを指定するだけのファイルです。

$ vi dockerfile
$ cat dockerfile
# base image
FROM httpd_base

作成したDockerfileをhttpd_webというイメージ名でビルドします。
ビルドした時に、Dockerfile.baseのONBUILDで指定したコマンドが実行されます。
下記の標準出力を確認すると、web.tarが/var/www/html/配下に配置されているのが分かります。

$ docker build -t httpd_web .
Sending build context to Docker daemon 13.82 kB
Step 1 : FROM httpd_base
# Executing 1 build trigger...
Step 1 : ADD web.tar /var/www/html/
 ---> 6206210226df
Removing intermediate container 0aba0727ea3b
Successfully built 6206210226df

docker imagesで確認してみると、httpd_webというイメージが作成されています。

$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
httpd_web           latest              6206210226df        32 seconds ago      316.7 MB
httpd_base          latest              466247b3c857        5 minutes ago       316.7 MB

docker runコマンドでhttpd_webを起動してみます。

$ docker run -d -p 80:80 httpd_web
dc7c838affebdc5ed0245493e73b98030752e3a4b6ea145ede0d3dc8eb540c2d


http://192.168.99.100/へアクセスしてみます。
すると、web.tarがApacheにデプロイされ、内容が出力されていることが分かります。
f:id:pppurple:20160711030035p:plain

終わり。


【参考】