最初に
本記事「Dockerコンパクトマニュアル」は4項目で構成されております。
他の記事はこちらです。
投稿番号 | サブタイトル及びアクセス先 |
---|---|
1 | 初歩・基本コマンド |
2 | マウントとデータ永続化 |
3 | docker-compose |
4 | カスタムイメージを作成する (*本記事) |
この記事の目的
自分自身でアプリ作成をする場合にはカスタマイズされたコンテナが必要です。
それにはDockerHubからのイメージだけではなく自分が入れ込みたいデータを含んだ
カスタムなDockerイメージを作成しなければいけません。
今回はカスタムDockerイメージの作成手法に焦点をあてます。
Dockerfileのベストプラクティス
カスタムなイメージを作成する前にチェックしておきたい事項として
Docker公式でDockerfileのベストプラクティスが公開されています。
ある程度このベストプラクティスに沿わないと
分かりにくい、使いづらい、メンテナンスできない、バグがある 等の原因となります。
この内容を元に作成される事が推奨されます。
Best practices for writing Dockerfiles
英語かー と思った人
日本語化プロジェクトで翻訳したサイトがあります。
下記サイトからアクセスをお願いします。
1つ注意点として、更新履歴は確認をお願いします。
更新履歴が古い場合は合わせて公式サイトも確認した方がいいと思います。
Dockerfileからカスタムイメージを作成する
コンテナからコンテナイメージを作成する方法(docker commit)もあるのですが、
Dockerfileとイメージに含めるデータを同じ作業用のディレクトリに格納して作成するのが一般的です。
Dockerfileで指定できる命令事項
注意
Dockerfileでは先頭から順番に1行ずつ命令事項が実行されます。
つまり記述順序が前後するとエラーになったり意図しないコンテナが作成されてしまいます。
命令 | 実行内容 |
---|---|
FROM | ベースイメージを指定 |
ADD | イメージにファイルやフォルダを追加。 圧縮ファイルを指定した場合は自動展開されるので便利 Dockerfileを置いたディレクトリ外のリモートファイルも指定できる。 |
COPY | イメージにファイルやフォルダを追加 圧縮ファイルは展開されずそのままコピーされる Dockerfileを置いたディレクトリ内のファイルしか指定できない。 |
RUN | イメージをビルドする時にコマンド実行 |
CMD | コンテナを起動時実行する規定コマンド ( docker create や docker run で実行するコマンドを省略した時) を指定する |
ENTRYPOINT | イメージ実行時( docker create や docker run する時)において コマンドを強制実行 |
ONBUILD | ビルド完了時の任意命令を実行 |
EXPOSE | 通信想定ポートをイメージ利用者に伝達 |
VOLUME | 永続化データ保存場所をイメージ利用者に伝達 |
ENV | 環境変数定義 |
WORKDIR | RUN,CMD,ENTRYPOINT,ADD,COPYの際の作業ディレクトリを指定 |
SHELL | ビルド時のシェル指定 |
LABEL | 名前・バージョン番号・製作者情報設定 |
USER | RUN,CMD,ENTRYPOINT で指定するコマンドを実行するユーザーや グループを設定する(USER指定無はroot) |
ARG |
docker build する際に指定できる引数を宣言 |
STOPSIGNAL | docker stop する際にコンテナで実行しているプログラムに対して 送信するシグナルを変更する (規定は SIGTERM) |
HEALTHCHECK | コンテナの死活確認をするヘルスチェックの方法をカスタマイズする |
ハマりやすいポイント その1
RUN , CMD , ENTRYPOINT がどの時点で実行されているのか??
私も間違えました。これは図で覚えた方がいいと思います。
- RUNはイメージ作成の段階
- CMD, ENTRYPOINTは コンテナ起動の段階
ハマりやすいポイント その2
CMD, ENTRYPOINTの使い分け
どう使い分けすればいいのか??
結論
ほとんどの場合はCMDを使ってください。
CMDを使った場合はユーザーが明示的にコマンドを記述すればそちらが優先されます。
例えばカスタムコンテナでバグが発生した場合、ENTRYPOINTで指示している場合は
強制コマンド実行される為に変更ができません。そのバグが発生し続けます。
一方CMDはユーザーが規定コマンドに任せるのも任意コマンドを実行するのも選択できるからです。
サンプル例
Railsでのカスタムサンプルも公開されています。
Docker Hubの公式イメージでの命令事項と異なっているのがわかります。
FROM ruby:2.3
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
postgresql-client \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /usr/src/app
COPY Gemfile* ./
RUN bundle install
COPY . .
EXPOSE 3000
CMD ["rails", "server", "-b", "0.0.0.0"]
FROM ruby:2.5
RUN apt-get update -qq && apt-get install -y nodejs postgresql-client
RUN mkdir /myapp
WORKDIR /myapp
COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock
RUN bundle install
COPY . /myapp
# Add a script to be executed every time the container starts.
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000
# Start the main process.
CMD ["rails", "server", "-b", "0.0.0.0"]
にしても Docker HubのRubyのバージョンが2.3、Quickstart も 2.5
古すぎる❗️❗️
version 2.6以降にして欲しいところですね。
ですので、Railsのモダンなコンテナ環境を構築するにはQuickstartの内容をさらにカスタム化
した方がいいと思います。
宣伝
もっと簡単にRailsでモダンな開発環境を簡単に構築できないかなーと思った方
私が作ったこっちのサイトにアクセスしてみて下さい。
"Docker-compose" で "Rails6" の安定的な開発環境構築マニュアル
最後に
4部に渡りDockerの投稿を行いました。
最後までお付き合い頂いた方は大変ありがとうございます。
少しでも参考になりましたらLGTM頂けましたら幸いです。
間違い等がございましたら、ご指摘頂ければ幸いです。
また、多くの方にアドバイスを頂きました。ここに御礼申し上げます。
参考資料・参考元サイト
WEB
- docker docs reference
- Docker ドキュメント日本語化プロジェクト
- Git Hub Dockerドキュメント日本語化プロジェクト zembutsu/docs.docker.jp