昨日、Dockerfileを使用してイメージをカスタマイズする方法について書きました。その中で、構築コンテキストは書かれていませんが、今日は別に書きます。
Dockerイメージビルド
ミラーを構築する手順について簡単に説明してください。
-
Dockerfileが配置されているディレクトリをcdします。
-
docker buildbuildコマンドを実行します。
docker build -t imageName:imageTag。
上記のワークフローを通じて、このような誤解を簡単に形成できます。
- docker buildの背後にあるのは、Dockerfileが配置されているディレクトリです。
- Dockerfileファイル名はDockerfileである必要があります。
実際、上記の理解は間違っています。その意味を正確に理解するには、まずDockerアーキテクチャとDockerビルドの動作原理を理解する必要があります。
Dockerアーキテクチャ
DockerはC / S(クライアント/サーバー)アーキテクチャを使用します。DockerクライアントはDockerデーモンと通信します。DockerデーモンはDockerコンテナの構築、実行、および配布を担当します。Dockerクライアントとデーモンは同じシステムで実行できますが、DockerクライアントをリモートのDockerデーモンに接続することもできます。DockerクライアントとデーモンはRESTAPIを使用して、UNIXソケットまたはネットワークインターフェイスを介して通信します。
Dockerビルドの仕組み
- クライアント側はdockerbuild。コマンドを実行します。
- Dockerクライアントは、ビルドコマンドの後に指定されたパス(。)の下にあるすべてのファイルをパッケージ化してDockerサーバーに送信します。
- 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
見ることができるように:
- イメージビルドコンテキストパスは、Dockerfileファイルが配置されているパスではありません。
- 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として指定できます。