モーダルを閉じる工作HardwareHub ロゴ画像

工作HardwareHubは、ロボット工作や電子工作に関する情報やモノが行き交うコミュニティサイトです。さらに詳しく

利用規約プライバシーポリシー に同意したうえでログインしてください。

工作HardwareHub ロゴ画像 (Laptop端末利用時)
工作HardwareHub ロゴ画像 (Mobile端末利用時)

Dockerfile ベストプラクティス (仮)

モーダルを閉じる

ステッカーを選択してください

モーダルを閉じる

お支払い内容をご確認ください

購入商品
」ステッカーの表示権
メッセージ
料金
(税込)
決済方法
GooglePayマーク
決済プラットフォーム
確認事項

利用規約をご確認のうえお支払いください

※カード情報はGoogleアカウント内に保存されます。本サイトやStripeには保存されません

※記事の執筆者は購入者のユーザー名を知ることができます

※購入後のキャンセルはできません

公開日公開日
2015/03/01
最終更新最終更新
2020/02/26
記事区分記事区分
一般公開

目次

    アカウント プロフィール画像 (サイドバー)

    Webアプリの自動テストエンジニア

    0
    ステッカーを贈るとは?

    Dockerfile を書く際に気になるポイント集です。「Best practices for writing Dockerfiles」および「Dockerfile Reference」をもとにしています。

    Dockerfile ポイント集

    .dockerignore で不要なファイルを除外

    Dockerfile をもとに build コマンドを実行すると Dockerfile の存在するディレクトリ以下のファイルすべてが "build context" として Docker デーモンに転送されます。ビルドは docker クライアントコマンドで実行されずに docker デーモンで実行されるためです。

    Sending build context to Docker daemon

    という出力で転送されるファイルのうちビルドに不要なものは無視リスト .dockerignore に含めましょう。転送にかかる時間を短縮できます。例えば .git は除外するべきです。

    コピー用途ならば ADD ではなく COPY

    COPY はホストからコンテナ内にファイルをコピーすることしかできません。一方で ADD は COPY のようにホストからコンテナ内にファイルをコピーする機能に加えて tar.gz など圧縮ファイルをコピー後に解凍する機能など有しています。そのような機能の使用を意図していないことを明らかにするために、単純なコピー用途であれば COPY を使用することが推奨されます。

    USER を頻繁に使用しない

    USER の記載された行以降の CMD, RUN, ENTRYPOINT は設定された権限で実行されます。しかしながら頻繁に root → 一般ユーザ → root → ... とスイッチしなければならないような Dockerfile は好ましくありません。ちなみに CMD には docker run で指定されたコマンドも含みます。また、ユーザは事前に作成しておく必要があります。

    RUN useradd username
    USER username
    

    RUN で cd するのではなく WORKDIR を利用

    すべての Instruction は独立しており初期化されます。

    RUN cd /path/to/dir
    

    としても次の RUN ではまたもとの位置に戻ってしまいます。すべての RUN で

    RUN cd /path/to/dir && コマンド
    

    とすることでも解決できますが、もっとスマートに WORKDIR を利用しましょう。この情報は以降の RUN, CMD, ENTRYPOINT, COPY, ADD で使用されます。CMD には run で指定されたコマンドも含みます。WORKDIR では cd コマンドのように相対パスも使用できます。例えば

    WORKDIR /a
    WORKDIR b
    WORKDIR c
    

    とすると RUN pwd の結果は /a/b/c となります。存在しないディレクトリが指定された場合は自動で作成されます。

    ENV はまとめて一行にできる

    ENV myName="John Doe" \
        myCat=fluffy
    

    ENV myName John Doe
    ENV myCat fluffy
    

    は同じ結果になります。前者は 1 LAYER で実現されるためビルド時のステップ数を節約できます。

    バックスラッシュで複数行に分ける

    例えば apt-get で大量のパッケージをインストールする RUN はバックスラッシュで複数行に分けてアルファベット順にしておきます。見易いだけでなく重複した記載を避けることができます。

    RUN apt-get update && apt-get install -y \
      bzr \
      cvs \
      git \
      mercurial \
      subversion
    

    EXPOSE は -P のヒント

    EXPOSE で提供される情報は -P で bind する際やコンテナ同士を link するときの情報として使用されます。EXPOSE で指定したポート番号は必ずしもホストのインタフェースに bind されないことに注意してください。コンテナを実行する管理者の判断によっては、そもそも -P オプションが付与されなかったり -p (小文字) で一部のポートしか bind されない状態でコンテナが作成される可能性があります。

    CMD について

    有効に指定できるのは一つだけ

    CMD は Dockerfile 内に一つだけ指定可能です。仮に複数指定すると最後の CMD だけが有効になります。

    必ずしも実行されない

    CMD で指定された内容はあくまでもイメージの COMMAND です。コンテナを作成するコマンド run および create の引数で COMMAND が指定された場合は CMD の内容は上書かれます。

    ENTRYPOINT との違い

    CMD は ENTRYPOINT の引数を指定します。ENTRYPOINT の既定値は [""] です。ENTRYPOINT を変更しない場合、コンテナ内では start または exec 時に

    CMD top -b
    → /bin/sh -c 'top -b'
    
    CMD ["top", "-b"]
    → top -b
    

    が実行されます。ENTRYPOINT を変更すると以下のように CMD は ENTRYPOINT の引数として機能します。

    ENTRYPOINT ["top", "-b"]
    CMD this_does_not_work
    → top -b /bin/sh -c this_does_not_work
    
    ENTRYPOINT ["top", "-b"]
    CMD ["-d1"]
    → top -b -d1
    

    Dockerfile 内で ENV を利用可能

    ENV foo /bar
    

    としておくと、コンテナ内だけでなく以降の Dockerfile 内の ENV, ADD, COPY, WORKDIR, EXPOSE, VOLUME, USER で $foo が利用できます。

    WORKDIR $foo
    WORKDIR ${foo}_blah
    

    複数のイメージを一つの Dockerfile で作成できる

    FROM は Dockerfile 内に何度も指定できます。これは複数のイメージを一つの Dockerfile で作成できるということを意味します。

    FROM ubuntu
    RUN echo foo > bar
    # Will output something like ===> 907ad6c2736f
    
    FROM ubuntu
    RUN echo moo > oink
    # Will output something like ===> 695d7793cbe4
    

    VOLUME で作成したボリュームは rm -v で削除可能

    Dockerfile

    FROM centos:centos6
    VOLUME /DataVolume名
    

    以下のコマンドで作成したコンテナには /DataVolume名 ボリュームがマウントされます。

    $ docker build -t username/mydata .
    $ docker create -it username/mydata /bin/bash
    $ docker volume list
    DRIVER              VOLUME NAME
    local               18f4246b6f977ea865e17c6bc5c8465dc2987ff3738c129673728610bab77f23
    

    コンテナを削除 rm する際に -v オプションを付与するとボリュームも削除されます。

    $ docker rm -v コンテナ名
    

    複数の VOLUME が指定されている場合は複数削除されます。

    VOLUME ["/DataVolume名1", "/DataVolume名2"] 
    → $ docker rm -v コンテナ名
    
    0
    詳細設定を開く/閉じる
    アカウント プロフィール画像 (本文下)

    Webアプリの自動テストエンジニア

    記事の執筆者にステッカーを贈る

    有益な情報に対するお礼として、またはコメント欄における質問への返答に対するお礼として、 記事の読者は、執筆者に有料のステッカーを贈ることができます。

    さらに詳しく →
    ステッカーを贈る コンセプト画像

    Feedbacks

    Feedbacks コンセプト画像

      ログインするとコメントを投稿できます。

      関連記事