Dockerfile を使用して Docker でイメージを構築する方法

Dockerfile を使用して Docker でイメージを構築する方法

イメージを構築する

これまで、テストやデモンストレーションにさまざまなイメージを使用しました。多くの場合、ビジネス ニーズを満たすには独自のイメージが必要です。そのため、必要なイメージをカスタマイズできる必要があります。Docker イメージを構築するには 2 つの方法があります。

  • docker commit コマンドを使用します。
  • docker build コマンドと Dockerfile を使用してファイルをビルドします。

現在、docker commit コマンドの使用は推奨されておらず、代わりに、より柔軟で強力な Dockerfile を使用して Docker イメージを構築することが推奨されています。

1.コミットコマンドを使用してビルドする

docker commit コマンドは、新しいイメージを作成する最も直感的な方法です。プロセスは次の 3 つのステップで構成されます。

  • コンテナを実行します。
  • コンテナを変更します。
  • コンテナを新しいイメージとして保存します。

まず、新しいコンテナを作成しましょう。このコンテナには、共通の Ubuntu イメージを使用します。手順は次のとおりです。

1.1 変更するコンテナを実行する

root@ubuntu:~# docker run -ti ubuntu /bin/bash
ルート@733a4b080491:/#

1.2 Apacheパッケージをインストールする

root@733a4b080491:/# apt-getアップデート
……
root@733a4b080491:/# apt-get install -y apache2
……

コンテナを起動し、その中に Apache をインストールしました。このコンテナを Web サーバーとして実行し、この手順を毎回実行しなくても済むように保存する必要があります。

1.3 カスタムコンテナの送信

ルート@ubuntu:~# docker ps -a
コンテナID イメージ コマンド 作成ステータス ポート名
733a4b080491 ubuntu "/bin/bash" 11 分前 終了 (0) 5 秒前 suspect_mestorf
root@ubuntu:~# docker コミット 733a4b080491 wzlinux/ubuntu_with_apache
sha256:902ac2c87147fefc5b70c741ce9550dcda426cea9f824f442d5cc2744bdc90ae
root@ubuntu:~# docker イメージ
リポジトリ タグ イメージ ID 作成 サイズ
wzlinux/ubuntu_with_apache 最新 902ac2c87147 33 秒前 261MB
ubuntu 最新 20c44cd7596f 10日前 123MB

ご覧のとおり、docker commit を使用して変更されたコンテナを送信しました。サイズから、ソフトウェアのインストールによりイメージが大きくなっていることがわかります。docker commit は、コンテナの作成に使用したイメージとコンテナの現在の状態との差分のみを送信するため、更新が非常に軽量になります。

上記は、docker commit を使用して新しいイメージを作成する方法を示しています。ただし、Docker では、ユーザーがこの方法でイメージを構築することは推奨されていません。これは手動で画像を作成する方法であるため、エラーが発生しやすく、非効率的で、再現性が低くなります。たとえば、Debian ベースイメージに Apache を追加する場合は、前の手順をすべて繰り返す必要があります。さらに重要なのは、ユーザーはイメージがどのように作成されたか、またはイメージに悪意のあるプログラムが含まれているかどうかを知らないことです。つまり、イメージを監査することができず、セキュリティ上のリスクが生じます。

ただし、Docker をより包括的に理解するには、docker commit を使用して Docker イメージを構築する方法を理解する必要があります。イメージを構築するために Dockerfile (推奨される方法) を使用する場合でも、基礎となる docker commit によって新しいイメージがレイヤーごとに構築されるためです。 docker commit を学習すると、ビルド プロセスとイメージの階層構造をより深く理解できるようになります。

2. Dockerfileを使用してビルドする

Dockerfile は、基本的な DSL (ドメイン固有言語) 構文ベースの指示を使用して Docker イメージを構築します。Docker commit ではなく Dockerfile メソッドを使用することをお勧めします。前者を使用してイメージを構築すると、より繰り返し可能で、透過的で、べき等性があるためです。

Dockerfile ができたら、docker build コマンドを使用して、Dockerfile 内の指示に基づいて新しいイメージを構築できます。

2.1 最初のDockerfile

Dockerfile を使用して上記の ubuntu_with_apache を作成します。内容は以下のとおりです。

# バージョン 0.0.1
Ubuntuから
sed -i 's/archive.ubuntu.com/cn.archive.ubuntu.com/g' /etc/apt/sources.list を実行します。
sed -i 's/security.ubuntu/cn.archive.ubuntu/g' /etc/apt/sources.list を実行します。
apt-get -y update && apt-get -y install apache2 を実行します。
エクスポーズ80

docker build コマンドが実行されると、Dockerfile 内のすべての命令が実行されてコミットされ、コマンドが正常に完了すると新しいイメージが返されます。

root@ubuntu:~/sample# docker build -t ubuntu_with_apache_dockerfile . ①
ビルドコンテキストをDockerデーモンに送信 6.144kB ②
ステップ 1/5: Ubuntu から ③
 ---> 20c44cd7596f
ステップ 2/5: sed -i 's/archive.ubuntu.com/cn.archive.ubuntu.com/g' /etc/apt/sources.list を実行します。
 ---> bac6dc3b900f で実行中
 ---> c66ad94ad8a4
中間コンテナ bac6dc3b900f を削除しています
ステップ 3/5: sed -i 's/security.ubuntu/cn.archive.ubuntu/g' /etc/apt/sources.list を実行します。
 ---> 5158558b6403 で実行中
 ---> 0a4c480147c5
中間コンテナ5158558b6403を削除
ステップ4/5: apt-get -y update && apt-get -y install apache2 を実行します ④
 ---> f547ce7a1b39 で実行中 ⑤
 …
 …
 ---> 118bde35120a ⑥
中間コンテナの取り外し f547ce7a1b39 ⑦
ステップ 5/5: EXPOSE 80
 ---> e546786de05b で実行中
 ---> f55d7b07365b
中間コンテナ e546786de05b を削除
f55d7b07365b のビルドに成功しました ⑧
ubuntu_with_apache_dockerfile:latest のタグ付けに成功しました


① docker build コマンドを実行します。-t は、新しいイメージに ubuntu-with-apache-dockerfile という名前を付けます。コマンドの末尾の . は、ビルド コンテキストが現在のディレクトリであることを示します。デフォルトでは、Docker はビルド コンテキストで Dockerfile ファイルを検索します。-f パラメータを使用して Dockerfile の場所を指定することもできます。

② このステップから実際のイメージ構築プロセスが始まります。 まず、Docker はビルド コンテキスト内のすべてのファイルを Docker デーモンに送信します。ビルド コンテキストは、イメージのビルドに必要なファイルまたはディレクトリを提供します。

Dockerfile 内の ADD、COPY などのコマンドを使用すると、ビルド コンテキスト内のファイルをイメージに追加できます。この例では、ビルド コンテキストは現在のディレクトリ /sample であり、このディレクトリの下にあるすべてのファイルとサブディレクトリが Docker デーモンに送信されます。

したがって、ビルド コンテキストを使用するときは注意が必要です。ビルド コンテキストに不要なファイルを置かないでください。特に、/ または /usr をビルド コンテキストとして使用しないでください。そうしないと、ビルド プロセスが非常に遅くなったり、失敗したりします。

③ ステップ1: FROMを実行し、ubuntuをベースイメージとして使用します。 Ubuntu イメージ ID は 452a96d81c30 です。

④ステップ4:RUNを実行してApacheをインストールします。具体的な手順は⑤~⑬です。

⑤ ID e38bc83df8b1の一時コンテナを起動し、apt-getを使用してコンテナ内にApacheをインストールします。

⑥ インストールが成功したら、コンテナをID fbc9af08328d のイメージとして保存します。このステップでは、最下層で docker commit に似たコマンドを使用します。

⑦ 一時コンテナ02a4f3243ddaを削除します。

⑧ イメージが正常に構築されました。

docker イメージを通じてイメージ情報を表示します。

root@ubuntu:~/sample# docker イメージ
リポジトリ タグ イメージ ID 作成 サイズ
ubuntu_with_apache_dockerfile 最新 f55d7b07365b 27 分前 261MB
wzlinux/ubuntu_with_apache 最新 902ac2c87147 約1時間前 261MB
ubuntu 最新 20c44cd7596f 10日前 123MB

2.2 画像構造の表示

ubuntu_with_apache_dockerfile は、ベースイメージの上にいくつかの新しいイメージレイヤーを追加することによって取得されます。

上の画像は原文からコピーしたもの、下の画像は私のパソコンで実験して得たデータです。IMAGE IDは異なりますが、他は同じです。


次のようにして、Ubuntu マシンの IMAGE 履歴を確認します。


出力からわかるように、各コマンドはミラー レイヤーを生成します。

Docker 履歴には、イメージのビルド履歴、つまり Dockerfile の実行プロセスが表示されます。

ubuntu イメージと比較すると、ubuntu_with_apache_dockerfile にはレイヤーが少しだけ多くあります。Dockerfile 内の各命令はレイヤーを作成します。docker 履歴には、イメージのレイヤー構造も表示され、各レイヤーは上から下に配置されます。

2.3 画像キャッシュ機能

ビルドプロセスの各ステップで結果がイメージとして送信されるため、Docker のイメージビルドプロセスは非常にスマートです。前の画像レイヤーをキャッシュとして扱います。

たとえば、EXPOSE 80 を EXPOSE 8080 に変更します。

ubuntu をビルドします。   
ビルドコンテキストを Docker デーモンに送信 6.144kB
ステップ 1/5: Ubuntu から 
---> 20c44cd7596f
ステップ 2/5: sed -i 's/archive.ubuntu.com/cn.archive.ubuntu.com/g' /etc/apt/sources.list を実行します。
 ---> キャッシュを使用 ---> c66ad94ad8a4ステップ 3/5: RUN sed -i 's/security.ubuntu/cn.archive.ubuntu/g' /etc/apt/sources.list 
---> キャッシュの使用 
---> 0a4c480147c5
ステップ 4/5: apt-get -y update && apt-get -y install apache2 を実行します。 
---> キャッシュの使用 
---> 118bde35120a
ステップ 5/5: EXPOSE 8080 
---> c89f8210c56a で実行中 
---> ac88967e578e
中間コンテナ c89f8210c56a を削除しています
ac88967e578e の構築に成功しました
ubuntu_with_apache_8080:latest のタグ付けに成功しました

以前の命令は同じであることがわかるので、Docker は以前のキャッシュを直接使用し、変更した命令のみをビルドします。新しいイメージ レイヤーは次のようになります。


イメージをビルドするときにキャッシュを使用しない場合は、docker build コマンドに --no-cache パラメータを追加できます。

Dockerfile 内の各命令はイメージ レイヤーを作成し、上位レイヤーは下位レイヤーに依存します。レイヤーが変更されるたびに、その上のすべてのレイヤーのキャッシュが無効になります。つまり、Dockerfile 命令の実行順序を変更したり、命令を変更または追加したりすると、キャッシュは無効になります。たとえば、コマンド MAINTAINER wzlinux "[email protected]" を先頭に追加します。次のように:

# バージョン 0.0.1
Ubuntuから
メンテナー wzlinux "[email protected]"
sed -i 's/archive.ubuntu.com/cn.archive.ubuntu.com/g' /etc/apt/sources.list を実行します。
sed -i 's/security.ubuntu/cn.archive.ubuntu/g' /etc/apt/sources.listを実行します。
apt-get -y update && apt-get -y install apache2 を実行します。
エクスポーズ80

次に、docker を使用してビルドし、プロセスを確認します。

ubuntu をビルドします。

ビルドコンテキストを Docker デーモンに送信 6.144kB
ステップ 1/6: Ubuntu から
 ---> 20c44cd7596f
ステップ 2/6: MAINTAINER wzlinux "[email protected]" 
---> 637bb3457407 で実行中 
---> 829b24531d69
中間コンテナ 637bb3457407 を削除しています
ステップ 3/6: sed -i 's/archive.ubuntu.com/cn.archive.ubuntu.com/g' /etc/apt/sources.list を実行します。 
---> 416ae8aefb61 で実行中 
---> 84643fe8447a
中間コンテナ 416ae8aefb61 を削除
ステップ 4/6: sed -i 's/security.ubuntu/cn.archive.ubuntu/g' /etc/apt/sources.list を実行します。 
---> 58d8375fd5c3 で実行中 
---> 1cb5776982d3
中間コンテナ 58d8375fd5c3 を削除しています
ステップ 5/6: apt-get -y update && apt-get -y install apache2 を実行します。 
---> 0514a7d04814 で実行中
 …
 …
sgml-base (1.26+nmu4ubuntu1) の処理トリガー
 ... 
---> 30eb21527料金
中間コンテナ 0514a7d04814 の取り外し
ステップ 6/6: EXPOSE 80 
---> 476ca5f98886 で実行中 
---> 30672998f3d0
中間コンテナ 476ca5f98886 を削除しています
30672998f3d0 の構築に成功しました
ubuntu_with_apache_author:latest のタグ付けに成功しました


出力結果から多くの新しい画像レイヤーが生成され、キャッシュが無効になりました。

2.4 Dockerfileのデバッグ

Dockerfile を含むすべてのスクリプトまたはプログラムは失敗します。間違いがあってもそれほどひどいことではありませんが、問題を解決する方法が必要です。ビルド プロセス中にコマンドでエラーが発生した場合にどうするかをテストしてみましょう。たとえば、2 番目の sed コマンドを誤って記述し、代わりに sd と記述しました。

# バージョン 0.0.1
Ubuntuから
メンテナー wzlinux "[email protected]"
sed -i 's/archive.ubuntu.com/cn.archive.ubuntu.com/g' /etc/apt/sources.list を実行します。
実行 sd -i 's/security.ubuntu/cn.archive.ubuntu/g' /etc/apt/sources.list
apt-get -y update && apt-get -y install apache2 を実行します。
エクスポーズ80

以下のようにdocker buildを実行します。


4 番目のステップである RUN 命令を実行すると、Dockerfile が失敗します。 3 番目の手順で作成したイメージ 84643fe8447a は、docker run -it を介してイメージのコンテナーを起動することでデバッグに使用できます。

root@ubuntu:~/sample# docker run -ti 84643fe8447a /bin/bash
ルート@422ecce78664:/#sd
bash: sd: コマンドが見つかりません

実際、私たちは sd が存在しないことを知らないほど愚かではありません。これは単なる例として使用しているだけです。この方法は、他のより難しいトラブルシューティング方法にも使用します。

2.5 Dockerfileの指示

から
ベースイメージを指定します。

メンテナー
画像の作成者を設定します。任意の文字列を指定できます。

コピー
ビルド コンテキストからイメージにファイルをコピーします。
COPY は次の 2 つの形式をサポートします。
コピー src dest コピー ["src", "dest"]
注意: src はビルド コンテキスト内のファイルまたはディレクトリのみを指定できます。

追加
COPY と同様に、ビルド コンテキストからイメージにファイルをコピーします。違いは、src がアーカイブ ファイル (tar、zip、tgz、xz など) の場合、ファイルは自動的に dest に解凍されることです。

環境
後続の命令で使用できる環境変数を設定します。例えば:

ENV MY_VERSION 1.3RUN apt-get install -y mypackage=$MY_VERSION

さらす
Docker は、コンテナ内のプロセスがポートをリッスンするように指定することで、ポートを公開できます。

音量
ファイルまたはディレクトリをボリュームとして宣言します。

ワークディレクトリ
後続の RUN、CMD、ENTRYPOINT、ADD、または COPY 命令のために、イメージ内の現在の作業ディレクトリを設定します。

走る
コンテナ内で指定されたコマンドを実行します。

CMDF
コンテナの起動時に指定されたコマンドを実行します。
Dockerfile には複数の CMD 命令を含めることができますが、最後の命令のみが有効になります。 CMD は、docker 実行後にパラメータで置き換えることができます。

エントリーポイント
コンテナの起動時に実行するコマンドを設定します。
Dockerfile には複数の ENTRYPOINT 命令を含めることができますが、最後の命令のみが有効になります。 CMD または docker run 後のパラメータは、ENTRYPOINT へのパラメータとして渡されます。

以上がこの記事の全内容です。皆様の勉強のお役に立てれば幸いです。また、123WORDPRESS.COM を応援していただければ幸いです。

以下もご興味があるかもしれません:
  • Dockerfile ファイルの書き込みとイメージ構築コマンドの分析
  • Dockerfile を使用したカスタムイメージの構築の実装
  • Dockerfileを使用してDockerイメージを構築する
  • Dockerfileを使用してDockerイメージを構築する手順
  • Dockerfile に基づいて Tomcat イメージを構築する方法
  • Dockerfile を使用して nginx イメージを構築する例
  • Dockerfileを使用してイメージを構築する方法
  • dockerfile命令を使用してdockerイメージを構築するためのサンプルコード

<<:  Mac 向け MySQL のインストールと設定のチュートリアル

>>:  ウォーターフォールフローレイアウト(無限読み込み)を実現する js

推薦する

MySQLの分離レベルとロックメカニズムの詳細な説明

目次簡単な説明: 1. 取引の4つの特徴2. 複数の同時トランザクションによって発生する問題3. ト...

Linux の daily_routine サンプルコードの詳細な説明

まずサンプルコードを見てみましょう: #/bin/bash cal 日付 -u echo "...

超詳細なMySQL使用仕様の共有

最近、データベース関連の操作が多くなり、会社の既存の仕様はあまり包括的ではありません。インターネット...

Yahooのフロントエンド最適化に関する35のルールについての簡単な説明

概要: 仕事でも面接でも、Web フロントエンドのパフォーマンスを最適化することは非常に重要です。で...

DELL R730 サーバーの構成 RAID とインストール サーバー システムとドメイン制御の詳細なグラフィック チュートリアル

最近、会社で DELL R730 サーバーを購入したのですが、偶然次のチュートリアルを見つけたので、...

CSS3 アニメーション ボールローリング JS コントロールアニメーション一時停止

CSS3 はアニメーションを作成でき、多くの Web ページのアニメーション画像、Flash アニメ...

Linux で Redis のリモート接続を実装する方法

LinuxにRedisをインストールしたら、Javaを使って接続します。Javaコードは次のとおりで...

CentOS 6.5 の設定 ssh キーフリーログインで pssh コマンドを実行する方法の説明

1. psshを確認してインストールします。yum list pssh 2. キーレスログインが設定...

WeChatアプレットのスケルトン画面の実装例

目次スケルトンスクリーンとはアプレットでスケルトン画面を生成する方法導入方法表示と非表示ユーザーエク...

Dockerは元のタグのイメージの再タグ付けと削除を実装します

docker イメージ ID は一意であり、イメージを物理的に識別できます。repository: ...

js を使用してウォーターフォール効果を実現する

この記事の例では、滝の流れの効果を実現するためのjsの具体的なコードを参考までに共有しています。具体...

MySQLのデッドロックチェック処理の通常の方法

通常、デッドロックが発生すると、重みが最も小さい接続が強制終了され、ロールバックされます。ただし、最...

MySQL 30軍事ルールの詳細な説明

1. 基本仕様(1)InnoDBストレージエンジンを使用する必要があります。解釈:トランザクション、...

Django+Mysql+Redis+Gunicorn+NginxのDockerデプロイメントの実装

I. はじめにDockerテクノロジーは現在非常に人気があります。コンテナを介してプロジェクト環境を...

Node.js でのブレークポイント再開の実装

序文通常のビジネスニーズ: 写真、Excel などをアップロードします。結局のところ、数 MB のサ...