Dockerのビルドコンテキストの詳細な説明

昨日、Dockerfileを使用してイメージをカスタマイズする方法について書きました。その中で、構築コンテキストは書かれていませんが、今日は別に書きます。

Dockerイメージビルド

ミラーを構築する手順について簡単に説明してください。

  1. Dockerfileが配置されているディレクトリをcdします。

  2. docker buildbuildコマンドを実行します。

    docker build -t imageName:imageTag。

上記のワークフローを通じて、このような誤解を簡単に形成できます。

  1. docker buildの背後にあるのは、Dockerfileが配置されているディレクトリです。
  2. Dockerfileファイル名はDockerfileである必要があります。

実際、上記の理解は間違っています。その意味を正確に理解するには、まずDockerアーキテクチャとDockerビルドの動作原理を理解する必要があります。

Dockerアーキテクチャ

DockerはC / S(クライアント/サーバー)アーキテクチャを使用します。DockerクライアントはDockerデーモンと通信します。DockerデーモンはDockerコンテナの構築、実行、および配布を担当します。Dockerクライアントとデーモンは同じシステムで実行できますが、DockerクライアントをリモートのDockerデーモンに接続することもできます。DockerクライアントとデーモンはRESTAPIを使用して、UNIXソケットまたはネットワークインターフェイスを介して通信します。

https://docs.docker.com/engine/images/architecture.svg

Dockerビルドの仕組み

  1. クライアント側はdockerbuild。コマンドを実行します。
  2. Dockerクライアントは、ビルドコマンドの後に指定されたパス(。)の下にあるすべてのファイルをパッケージ化してDockerサーバーに送信します。
  3. Dockerサーバーは、クライアントから送信されたパッケージを受信し、それを解凍して、Dockerfileの指示に従ってレイヤーにイメージを構築します。

画像構築コンテキスト(コンテキスト)

ミラーを構築する場合、すべてのカスタマイズがRUN命令で行われるわけではありません。多くの場合、COPY命令、ADD命令などを使用して、一部のローカルファイルをミラーにコピーする必要があります。docker buildコマンドはイメージをビルドします。実際、イメージはローカルではなく、Dockerエンジンであるサーバー側でビルドされます。では、このクライアント/サーバーアーキテクチャでは、サーバーはどのようにしてローカルファイルを取得できますか?

これにより、コンテキストの概念が導入されます。ビルド時に、ユーザーはイメージコンテキストをビルドするためのパスを指定します。dockerbuildコマンドがこのパスを認識した後、パスの下にあるすべてのコンテンツをパッケージ化し、Dockerエンジンにアップロードします。このようにして、Dockerエンジンはコンテキストパッケージを受信した後、イメージのビルドに必要なすべてのファイルを取得します。これをDockerfileに書き込む場合:

COPY ./package.json /app/

これは、docker buildコマンドが実行されるディレクトリにpackage.jsonをコピーすることでも、Dockerfileが配置されているディレクトリにpackage.jsonをコピーすることでもありませんが、コンテキストディレクトリにpackage.jsonをコピーすることです。

したがって、COPY命令のソースファイルパスは相対パスです。これは、COPY ../package.json / appまたはCOPY / opt / xxxx / appが機能しない理由でもあります。これらのパスはコンテキストの範囲を超えており、Dockerエンジンが取得できないため、初心者からよく聞かれます。これらの場所にあるファイル。これらのファイルが本当に必要な場合は、コンテキストディレクトリにコピーする必要があります。

例1:

[root@192 test]# ls
Dockerfile
[root@192 test]# cat Dockerfile
FROM alpine:latest
ADD  /root/mydocker/apache-tomcat-9.0.27.tar.gz /data/soft
[root@192 test]# ls /root/mydocker/apache-tomcat-9.0.27.tar.gz
/root/mydocker/apache-tomcat-9.0.27.tar.gz
[root@192 test]# docker build  .
Sending build context to Docker daemon  3.072kB
Step 1/2 : FROM alpine:latest
 ---> 965ea09ff2eb
Step 2/2 : ADD /root/mydocker/apache-tomcat-9.0.27.tar.gz /data/soft
ADD failed: stat /var/lib/docker/tmp/docker-builder904012777/root/mydocker/apache-tomcat-9.0.27.tar.gz: no such file or directory

見ることができるように:

  1. イメージビルドコンテキストパスは、Dockerfileファイルが配置されているパスではありません。
  2. Dockerfile内の命令の作業ディレクトリは、サーバーがクライアント送信パッケージを解凍するパスです。これは、ADD命令が失敗したためです。つまり、現在のディレクトリにapache-tomcatファイルがありません。

ビルドコンテキストを理解することは、イメージビルドにとって、行われるべきではない間違いを避けるために非常に重要です。たとえば、一部の初心者は、COPY / opt / xxxx / appが機能しないことを発見したため、ビルドするハードディスクのルートディレクトリにDockerfileを配置するだけで、Dockerビルドが実行された後、数十GBを送信することがわかりました。非常に遅くて簡単でしたビルドが失敗しました。これは、このアプローチがDockerにハードドライブ全体のパッケージをビルドさせるためであり、これは明らかに誤用です。

一般的に、Dockerfileは空のディレクトリまたはプロジェクトのルートディレクトリに配置する必要があります。このディレクトリに必要なファイルがない場合は、必要なファイルをコピーする必要があります。ディレクトリ内の何かがビルド中にDockerエンジンに渡されたくない場合は、.gitignoreと同じ構文で.dockerignoreを記述できます。このファイルは、コンテキストとしてDockerエンジンに渡す必要をなくすために使用されます。 。

では、なぜ誰かが誤って考えるのでしょうか。Dockerfileが指定されているディレクトリですか。これは、デフォルトでは、Dockerfileが追加で指定されていない場合、コンテキストディレクトリ内のDockerfileという名前のファイルがDockerfileとして使用されるためです。

これは単なるデフォルトの動作です。実際、Dockerfileのファイル名はDockerfileである必要はなく、コンテキストディレクトリにある必要もありません。たとえば、-f ../Dockerfileを使用できます。ファイルをDockerfileとして指定するためのphpパラメーター。

もちろん、人々は通常、デフォルトのファイル名Dockerfileを使用して、それをイメージビルドコンテキストディレクトリに配置します。

例2

[root@192 test]# docker images
REPOSITORY                         TAG                         IMAGE ID            CREATED             SIZE
tomcat                             jdk8-adoptopenjdk-hotspot   1a2bfb3e6eee        15 hours ago        318MB
openjdk                            8-jre-slim                  d0cfe439ce3d        13 days ago         184MB
btnguyen2k/oraclejdk8_jre-alpine   latest                      fab475620d00        4 years ago         208MB
[root@192 test]# cat ../mynginx/test
FROM alpine:latest
[root@192 test]# ls
apache-tomcat-9.0.27.tar.gz
[root@192 test]#  docker build -f ../mynginx/test  -t test:v1 .
Sending build context to Docker daemon  10.99MB
Step 1/1 : FROM alpine:latest
latest: Pulling from library/alpine
89d9c30c1d48: Already exists
Digest: sha256:c19173c5ada610a5989151111163d28a67368362762534d8a8121ce95cf2bd5a
Status: Downloaded newer image for alpine:latest
 ---> 965ea09ff2eb
Successfully built 965ea09ff2eb
Successfully tagged test:v1
[root@192 test]# docker images
REPOSITORY                         TAG                         IMAGE ID            CREATED             SIZE
tomcat                             jdk8-adoptopenjdk-hotspot   1a2bfb3e6eee        15 hours ago        318MB
alpine                             latest                      965ea09ff2eb        11 days ago         5.55MB
test                               v1                          965ea09ff2eb        11 days ago         5.55MB
openjdk                            8-jre-slim                  d0cfe439ce3d        13 days ago         184MB
btnguyen2k/oraclejdk8_jre-alpine   latest                      fab475620d00        4 years ago         208MB     

見ることができるように:

Dockerfileのファイル名はDockerfileである必要はなく、コンテキストディレクトリにある必要もありません。たとえば、-f ../mynginx/testパラメータを使用して、ファイルをDockerfileとして指定できます。

おすすめ

転載: blog.csdn.net/qq_45534034/article/details/112567761