docker buildコマンドおさらい 

はじめに

docker buildを中心とするdockerコマンドの基本的なところをまとめた。基礎に立ち返って再入門する。

Dockerコマンドについて

よく使うのはこのあたり

コマンド意味
runDockerイメージからDockerコンテナを作成
execDockerコンテナでコマンド実行
pushDockerイメージをDockerレジストリへ送信
buildDockerfileに基づき、imageを作成
rm停止中のコンテナを削除
rmiDockerホスト上のイメージを削除
commitDockerコンテナからイメージを作成する
kill起動中のコンテナを強制停止
loadtarアーカイブからDockerイメージを読み込む
tag既存のDockerイメージから新しDockerイメージを作成
historyDockerイメージの精製履歴を表示
psDockerコンテナ一覧を表示

Dockerfileとは

DockerイメージはDockerfileというファイルを生成、buildコマンドで読み込ませることによりイメージにすることが可能。

基本構文はこちら

docker build -f {Dockerfileへのパス} -t {イメージ名}:{タグ名} {Dockerfileのあるディレクトリ}

デフォルトでコマンドを実行するディレクトリにあるDockerfileが読み込まれる。

AnsibleやChefなどを用いて環境構築することもできるが、Dockerfileでも構築手順が明確になる。

コマンド意味
FROMベースになるDockerイメージを指定
ENV環境変数を設定
ARGbuild時の引数を定義するコマンド
デフォルト値の設定も可能
buildコマンドから --build-argsオプションを使う
LABELDockerイメージにメタデータを付与
versionやdescriptionを記載
RUNshellの実行を行う
SHELLデフォルトのシェルを設定
WORKDIR基点となるいディレクトリを設定
これを設定すると、Dockerfile内の多くのコマンドが相対パスで利用可能
ADDファイルやディレクトリのコピー
(重要!圧縮ファイルは自動的に展開される)
COPYファイルやディレクトリを指定したURLからコピー。(重要!圧縮ファイルは展開されない)
EXPOSEコンテナがlistenするポートを明記
ENTRYPOINTコンテナ起動時に実行するコマンド
CMDENTRYPOINTと同じくコンテナ起動時に実行するコマンドを指定

動いているコンテナを全て止める

停止前の状態

MacBook:Dockerfile darkenergy$ docker ps
CONTAINER ID        IMAGE                   COMMAND                  CREATED             STATUS              PORTS                         NAMES
10fea02bca93        redash/nginx:latest     "nginx -g 'daemon of…"   5 weeks ago         Up About an hour    0.0.0.0:80->80/tcp, 443/tcp   redash_nginx_1
25581536faf9        redash/redash:latest    "/app/bin/docker-ent…"   5 weeks ago         Up About an hour    0.0.0.0:5000->5000/tcp        redash_server_1
b71d8b8f7dd4        postgres:9.5.6-alpine   "docker-entrypoint.s…"   5 weeks ago         Up About an hour    5432/tcp                      redash_postgres_1
e60a2354c981        redis:3.0-alpine        "docker-entrypoint.s…"   5 weeks ago         Up About an hour    6379/tcp                      redash_redis_1
24229a9e8831        redash/redash:latest    "/app/bin/docker-ent…"   5 weeks ago         Up About an hour    5000/tcp                      redash_worker_1
MacBook:Dockerfile darkenergy$ 

docker ps -qでコンテナIDのみ表示させることが可能。

それとdocker stopコマンドを組み合わせることにより、動いているコンテナを停止させる事ができる。

MacBook:Dockerfile darkenergy$ docker stop `docker ps -q`
10fea02bca93
25581536faf9
b71d8b8f7dd4
e60a2354c981
24229a9e8831
MacBook:Dockerfile darkenergy$ docker ps -q 
MacBook:Dockerfile darkenergy$ 

止まっているコンテナを削除する

MacBook:Dockerfile darkenergy$ docker ps -a
CONTAINER ID        IMAGE                   COMMAND                  CREATED             STATUS                          PORTS               NAMES
10fea02bca93        redash/nginx:latest     "nginx -g 'daemon of…"   5 weeks ago         Exited (0) About a minute ago                       redash_nginx_1
25581536faf9        redash/redash:latest    "/app/bin/docker-ent…"   5 weeks ago         Exited (0) About a minute ago                       redash_server_1
b71d8b8f7dd4        postgres:9.5.6-alpine   "docker-entrypoint.s…"   5 weeks ago         Exited (0) About a minute ago                       redash_postgres_1
MacBook:Dockerfile darkenergy$ 

このコンテナを削除

docker ps -qaで停止しているコンテナID一覧が表示できる。これとdocker rmコマンドを組み合わせる。

MacBook:Dockerfile darkenergy$ docker rm `docker ps -qa`
10fea02bca93
25581536faf9
b71d8b8f7dd4
MacBook:Dockerfile darkenergy$ docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
MacBook:Dockerfile darkenergy$ 

docker build時のキャッシュの利用を止める

Dockerをbuildしている時、以下のようにキャッシュを使われてしまう事がある。その利用を停止させる

 ---> Using cache

docker buildするとデフォルトで “` –no-cache=false “` が設定されている。これを “` –no-cache=true “` にすることにより、キャッシュを使わずbuildする事が可能になる。

Dockerfileは以下とする

FROM ubuntu

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

RUN echo "$myName, $myDog, $myCat"

キャッシュを利用した場合

MacBook% docker build -f env/Dockerfile_first -t build:env_first .
Sending build context to Docker daemon   72.7kB
Step 1/5 : FROM ubuntu
 ---> 113a43faa138
Step 2/5 : ENV myName John Doe
 ---> Using cache
 ---> 94a9595b4ad2
Step 3/5 : ENV myDog Rex The Dog
 ---> Using cache
 ---> 8e541e0cadf3
Step 4/5 : ENV myCat fluffy
 ---> Using cache
 ---> d7f742cdd48d
Step 5/5 : RUN echo "$myName, $myDog, $myCat"
 ---> Using cache
 ---> 08403e0b3e95
Successfully built 08403e0b3e95
Successfully tagged build:env_first
MacBook% 

キャッシュを利用しなかった場合

MacBook% docker build -f env/Dockerfile_first -t build:env_first . --no-cache=true
Sending build context to Docker daemon   72.7kB
Step 1/5 : FROM ubuntu
 ---> 113a43faa138
Step 2/5 : ENV myName John Doe
 ---> Running in f14667b92f6d
Removing intermediate container f14667b92f6d
 ---> 7b9af0d9b741
Step 3/5 : ENV myDog Rex The Dog
 ---> Running in 042dc782bef6
Removing intermediate container 042dc782bef6
 ---> 51d13644f407
Step 4/5 : ENV myCat fluffy
 ---> Running in 482cfc9e924e
Removing intermediate container 482cfc9e924e
 ---> b0dd7f89783c
Step 5/5 : RUN echo "$myName, $myDog, $myCat"
 ---> Running in 099ffe8325d8
John Doe, Rex The Dog, fluffy
Removing intermediate container 099ffe8325d8
 ---> 327d3ea27902
Successfully built 327d3ea27902
Successfully tagged build:env_first
MacBook% 

docker inspectを利用する

docker inspectはイメージの詳細を調べるコマンド

FROM ubuntu:16.04
LABEL maintainer="tsukada@sumito.jp" 
MacBook% docker inspect build:label                                       
[
    {
        "Id": "sha256:19832872f5b87f8adf2f212d9371a32f396537394ecedd86ad7794487e4cbd4d",
        "RepoTags": [
            "build:label"
        ],
        "RepoDigests": [],
        "Parent": "sha256:7aa3602ab41ea3384904197455e66f6435cb0261bd62a06db1d8e76cb8960c42",
        "Comment": "",
        "Created": "2018-11-24T08:40:08.172027394Z",
        "Container": "22d4da4c92440ad7a9b946088a0ce970919c801bef124a1587c9f3d5374b714a",
        "ContainerConfig": {
            "Hostname": "22d4da4c9244",
            "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:7aa3602ab41ea3384904197455e66f6435cb0261bd62a06db1d8e76cb8960c42",
            "Volumes": null,
            "WorkingDir": "",
            "Entrypoint": null,
            "OnBuild": null,
            "Labels": {
                "maintainer": "tsukada@sumito.jp"
            }
        },
        "DockerVersion": "18.09.0",
        "Author": "",
        "Config": {
            "Hostname": "",
            "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/bash"
            ],
            "ArgsEscaped": true,
            "Image": "sha256:7aa3602ab41ea3384904197455e66f6435cb0261bd62a06db1d8e76cb8960c42",
            "Volumes": null,
            "WorkingDir": "",
            "Entrypoint": null,
            "OnBuild": null,
            "Labels": {
                "maintainer": "tsukada@sumito.jp"
            }
        },
        "Architecture": "amd64",
        "Os": "linux",
        "Size": 114808794,
        "VirtualSize": 114808794,
        "GraphDriver": {
            "Data": {
                "LowerDir": "/var/lib/docker/overlay2/80942b3ef1ac6bd6683a0a610ebe509f493b3ab8e9981f55dad8277363dc5481/diff:/var/lib/docker/overlay2/44018ca585286af57480e331d2fa04d89de442742fe0432d9ee1ee0290872bf6/diff:/var/lib/docker/overlay2/c5e674d237e84ae63fcc71cf3e8fea790ea6072635406d095c16a9f22fa72706/diff:/var/lib/docker/overlay2/38077e61ba31390b978a4eabe12f01e31cc638590344241909c137356cae60c8/diff",
                "MergedDir": "/var/lib/docker/overlay2/020aa677865cf852f816916ac2e7df525a26d9984f4e78e8c2d9e7e478a2c22b/merged",
                "UpperDir": "/var/lib/docker/overlay2/020aa677865cf852f816916ac2e7df525a26d9984f4e78e8c2d9e7e478a2c22b/diff",
                "WorkDir": "/var/lib/docker/overlay2/020aa677865cf852f816916ac2e7df525a26d9984f4e78e8c2d9e7e478a2c22b/work"
            },
            "Name": "overlay2"
        },
        "RootFS": {
            "Type": "layers",
            "Layers": [
                "sha256:0a42ee6ceccb1b90de2a3badec7c74cc452ce61e7ef20a80bb7f20ea53f2825e",
                "sha256:c2af38e6b250a39e0e7b9665687385c75fdf7bab5ea856a2eec4fd6b74adda95",
                "sha256:5e95929b27983df137a6cff59695739f69f6571e70fa68eb6a7abe3b74e402d2",
                "sha256:2166dba7c95bfbc84b38b7a6c7d96d323d16239aeff2f2292c61821002df2dfb",
                "sha256:bcff331e13e35a0beb71d43b4f6b859327f18587f084a1036a603e64a990e44d"
            ]
        },
        "Metadata": {
            "LastTagTime": "2018-11-24T08:40:08.241971894Z"
        }
    }
]
MacBook% 

docker run

shellの実行を行うためのコマンド

RUN <command> shell from

shell fromと呼ばれる使われ方

SHELLの値にもとづいたコマンドによって実行される。

“` /bin/sh -c “` で実行される

RUN [“executable”, “param1″,”param2”] (exec from)

exec fromと呼ばれる使われ方

SHELLの値とは無関係に実行可能コマンドを直接実行

shell fromとexec fromの違い

shell fromはSHELLの設定により実行される
“` /bin/sh -c echo $HOGE “`

exec from はexecutableに指定されたコマンドが実行

コマンドシェル経由での実行ではなく、直接実行する

“`  echo $HOGE    “`

参考方法: https://docs.docker.com/engine/reference/builder/#run

/bin/sh: 1: Syntax error: “(” unexpected

shellの指定がされていない可能性が高い

SHELL ["/bin/bash", "-c"]

RUNコマンドの前に上記SHELLを追加することにより解消できる

SHELL

SHELLコマンドはRUNやCMD,ENTRYPOINTなどでshell fromが行われた際のコマンドを指定する事が可能

“` SHELL [“executable”, “parameters”] “`

WORKDIR

linuxで言うところの、mkdirとcdを同時に実行しているようなコマンド

FROM ubuntu:16.04
WORKDIR /sumito.tsukada
WORKDIR b
WORKDIR c
RUN pwd

と言うdockerfileがあったとすると、

/sumito.tsukada/b/c

と表示される

ADDとCOPYの違い

COPYはURLを指定する事ができない

圧縮ファイル(tarファイル)を自動で解凍しない

ENTRYPOINT

exec from

exec fromは推奨された使い方。

Dockerfile

FROM ubuntu:16.04
ENTRYPOINT ["top", "-H"]

build

docker build -f entrypoint/exec/Dockerfile -t build:entrypoint_exec ./entrypoint/exec/.
Sending build context to Docker daemon  2.048kB
Step 1/2 : FROM ubuntu:16.04
 ---> a51debf7e1eb
Step 2/2 : ENTRYPOINT ["top", "-H"]
 ---> Running in f48801d93416
Removing intermediate container f48801d93416
 ---> 8c57c2838f55
Successfully built 8c57c2838f55
Successfully tagged build:entrypoint_exec

PIDが1で起動される

docker run --rm -it build:entrypoint_exec 

top - 12:27:52 up  4:39,  0 users,  load average: 0.00, 0.03, 0.00
Threads:   1 total,   1 running,   0 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.2 us,  0.5 sy,  0.0 ni, 99.3 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :  2047036 total,   502868 free,   260180 used,  1283988 buff/cache
KiB Swap:  1048572 total,  1048104 free,      468 used.  1599568 avail Mem 

  PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND                                                                                   
    1 root      20   0   36660   3036   2620 R  0.0  0.1   0:00.07 top                                                                                       

shell from

こちらが推奨された使い方ではない

Dockerfile

FROM ubuntu:16.04

ENTRYPOINT top -H

build

build -f entrypoint/shell/Dockerfile -t build:entrypoint_shell ./entrypoint/shell 
Sending build context to Docker daemon  2.048kB
Step 1/2 : FROM ubuntu:16.04
 ---> a51debf7e1eb
Step 2/2 : ENTRYPOINT top -H
 ---> Running in 30505870ab0c
Removing intermediate container 30505870ab0c
 ---> e5825519f101
Successfully built e5825519f101
Successfully tagged build:entrypoint_shell

docker run

docker run --rm -it build:entrypoint_shell

top - 12:31:56 up  4:43,  0 users,  load average: 0.00, 0.02, 0.00
Threads:   2 total,   1 running,   1 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.0 us,  0.3 sy,  0.0 ni, 99.7 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :  2047036 total,   502612 free,   260024 used,  1284400 buff/cache
KiB Swap:  1048572 total,  1048104 free,      468 used.  1599720 avail Mem 

  PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND                                                                                   
    1 root      20   0    4500    696    624 S  0.0  0.0   0:00.04 sh                                                                                        
    6 root      20   0   36660   3140   2724 R  0.0  0.2   0:00.00 top   

1はshが動き、shell fromによって起動されたコマンドは別プロセスになってしまう。これにより、ホスト側が実施したコマンドを直接受け取る事ができない。

docker stopの動作

docker stopを実施すると、PID 1にSIGTERMを送信する。

しかしデフォルトで10秒応答が返ってこない場合はSIGKILLを実施。強制終了させると言う仕様がある。

shell fromとexecの違い

RUNはあくまでもDockerイメージをbuildするために実際にコンテナでコマンドを実施。commitすることにイメージに変更を加える。

参考情報

オライリー本より読みやすく、Dockerについて体系的に学ぶことができるのでおすすめ。