日: 2018年11月24日

  • docker buildコマンドおさらい 

    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について体系的に学ぶことができるのでおすすめ。