LoginSignup
1
3

More than 3 years have passed since last update.

Docker コンパクトマニュアル(4:カスタムイメージを作成する)

Last updated at Posted at 2020-10-30

最初に

本記事「Dockerコンパクトマニュアル」は4項目で構成されております。
他の記事はこちらです。

投稿番号 サブタイトル及びアクセス先
1 初歩・基本コマンド
2 マウントとデータ永続化
3 docker-compose
4 カスタムイメージを作成する (*本記事)

この記事の目的

自分自身でアプリ作成をする場合にはカスタマイズされたコンテナが必要です。
それにはDockerHubからのイメージだけではなく自分が入れ込みたいデータを含んだ
カスタムなDockerイメージを作成しなければいけません。
今回はカスタムDockerイメージの作成手法に焦点をあてます。

Dockerfileのベストプラクティス

カスタムなイメージを作成する前にチェックしておきたい事項として
Docker公式でDockerfileのベストプラクティスが公開されています。
ある程度このベストプラクティスに沿わないと
分かりにくい、使いづらい、メンテナンスできない、バグがある 等の原因となります。
この内容を元に作成される事が推奨されます。

Best practices for writing Dockerfiles

英語かー と思った人 :raised_hand:
日本語化プロジェクトで翻訳したサイトがあります。:relaxed:
下記サイトからアクセスをお願いします。

Dockerfile のベスト・プラクティス

1つ注意点として、更新履歴は確認をお願いします。
更新履歴が古い場合は合わせて公式サイトも確認した方がいいと思います。

スクリーンショット 2020-10-26 17.01.10.png

Dockerfileからカスタムイメージを作成する

コンテナからコンテナイメージを作成する方法(docker commit)もあるのですが、
Dockerfileとイメージに含めるデータを同じ作業用のディレクトリに格納して作成するのが一般的です。

スクリーンショット 2020-10-26 19.34.51.png

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 がどの時点で実行されているのか??
私も間違えました。これは図で覚えた方がいいと思います。
スクリーンショット 2020-10-26 20.58.54.png

  • RUNはイメージ作成の段階
  • CMD, ENTRYPOINTは コンテナ起動の段階

ハマりやすいポイント その2

CMD, ENTRYPOINTの使い分け
どう使い分けすればいいのか??

結論
ほとんどの場合はCMDを使ってください。
CMDを使った場合はユーザーが明示的にコマンドを記述すればそちらが優先されます。
例えばカスタムコンテナでバグが発生した場合、ENTRYPOINTで指示している場合は
強制コマンド実行される為に変更ができません。そのバグが発生し続けます。
一方CMDはユーザーが規定コマンドに任せるのも任意コマンドを実行するのも選択できるからです。

サンプル例

Railsでのカスタムサンプルも公開されています。
Docker Hubの公式イメージでの命令事項と異なっているのがわかります。

Docker Hub公式 rails

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"]

Quickstart: Compose and Rails

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
書籍
1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3