Dockerを入手する方法-常に最新の画像を使用するように作成する
1. 序章
私たちのプロジェクトでは、私たちはよく使用します docker-compose コンテナ化されたアプリケーションをデプロイします。 CIとCDでは、コードの変更と展開が最近非常に頻繁に行われています。 したがって、docker-composeが常にアプリケーションの最新のイメージを使用するようにすることが重要です。.
このチュートリアルでは、同じことを実現するためのいくつかのオプションを確認します。
2. 画像を明示的にプルする
docker-composeファイルの簡単な例を見てみましょう。
version: '2.4'
services:
db:
image: postgres
my_app:
image: "eugen/test-app:latest"
ports:
- "8080:8080"
ここでは、2つのサービスを使用しました。1つはPostgreSQLデータベースで、もう1つはテストアプリケーションです。 次のコマンドを使用してアプリケーションをデプロイします。
$ docker-compose up -d
これにより、両方のイメージがリモートリポジトリ(たとえば、 dockerhub )からプルされ、対応するコンテナが作成されます。
同じコマンドを使用してアプリケーションを再デプロイすると、問題が発生します。 イメージはローカルリポジトリにすでに存在するため、リモートリポジトリでこれらのイメージに変更があるかどうかはチェックされません。したがって、事前にdocker-composeファイル内のすべてのイメージをプルするオプションがあります。
$ docker-compose pull
Pulling db ... done
Pulling my_app ... done
このコマンドは、最初にdockerhubの両方のイメージで利用可能な更新があるかどうかを確認します。 次に、リモートで画像を最新の状態に保つために必要なレイヤーのみをダウンロードします。
ただし、Postgresのイメージをプルすることを常に好むとは限りません。 データベースの安定バージョンを使用する場合、イメージに変更はありません。 したがって、展開ごとにダウンロードするのは意味がありません。 場合によっては、既存のデータファイルが新しいバージョンと互換性がないことがあります。 これにより、展開が中断される可能性があります。 その場合、プルコマンドで特定のサービスの名前のみを使用できます:
$ docker-compose pull my_app
Pulling my_app ... done
ここで、upコマンドを実行すると、最新のイメージでコンテナーが再作成されます。
$ docker-compose up -d
Starting docker-test_db_1 ... done
Starting docker-test_my_app_1 ... done
もちろん、両方のコマンドを組み合わせて単一のライナーを作成することもできます。
$ docker-compose pull && docker-compose up -d
3. ローカル画像の削除
同じ例をもう一度考えてみましょう。 主な問題はローカル画像の存在であることはすでにわかっています。 したがって、ここでの2番目のオプションは、すべてのコンテナーを停止し、ローカルリポジトリからそれらのイメージを削除することです:
$ docker-compose down --rmi all
Stopping docker-test_my_app_1 ... done
Removing docker-test_db_1 ... done
Removing docker-test_my_app_1 ... done
Removing network docker-test_default
Removing image postgres
Removing image eugen/test-app:latest
down コマンドは、コンテナーを停止して削除します。 –rmi オプションは、ローカルリポジトリから画像を削除します。 rmiタイプlocalは、ローカルでビルドされたイメージのみを削除します。 したがって、rmiタイプallを使用して、現在の構成で使用されているすべてのイメージが確実に削除されるようにすることをお勧めします。
ここで、upコマンドを使用してコンテナーを再起動します。
$ docker-compose up -d
Creating network "docker-test_default" with the default driver
Pulling db (postgres:)...
latest: Pulling from library/postgres
7d63c13d9b9b: Pull complete
cad0f9d5f5fe: Pull complete
...
Digest: sha256:eb83331cc518946d8ee1b52e6d9e97d0cdef6195b7bf25323004f2968e91a825
Status: Downloaded newer image for postgres:latest
Pulling my_app (eugen/test-app:latest)...
latest: Pulling from eugen/test-app
df5590a8898b: Already exists
705bb4cb554e: Already exists
...
Digest: sha256:31c05c8245192b32b8b359fc58b5e45d8397674ccf41f5f17a7d3109772ab5c1
Status: Downloaded newer image for eugen/test-app:latest
Creating docker-test_db_1 ... done
Creating docker-test_my_app_1 ... done
これにより、ローカルリポジトリで画像が見つからなくなったことがわかります。 そのため、リモートリポジトリから最新のイメージをプルして、コンテナを再作成します。
このアプローチの欠点は、削除する特定の画像を選択できないことです。 そのため、常に postgres イメージを削除し、同じイメージを再度ダウンロードしますが、これは不要です。 これを解決するには、 dockerrmiを使用して特定のイメージを削除します。
$ docker rmi -f eugen/test-app:latest
Untagged: eugen/test-app:latest
Untagged: eugen/test-app@sha256:31c05c8245192b32b8b359fc58b5e45d8397674ccf41f5f17a7d3109772ab5c1
Deleted: sha256:7bc07b4eb1c23f7a91afeb7133f107e0a8318fb77655d7d5f2f395a035a13eb7
4. 画像の再構築
別のフレーバーを持つdocker-composeファイルの同じ例を見てみましょう。
version: '2.4'
services:
db:
image: postgres
my_app:
build: ./test-app
ports:
- "8080:8080"
ここでは、Postgresで同じdbサービスを使用しました。 ただし、サービス my_app には、既製のイメージを使用する代わりに、ビルドセクションを指定しました。 このセクションには、test-appのビルドコンテキストが含まれています。 test-appディレクトリにあるdockerファイルは次のようになります。
FROM openjdk:11
COPY target/test-app-0.0.1-SNAPSHOT.jar app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
このシナリオでは、 up コマンドを使用して再デプロイすると、docker-composeはローカルイメージが存在する場合はそれを再利用します。 したがって、デプロイメントをトリガーするたびにdocker-composeがイメージを再構築することを確認する必要があります。 オプション–build:を使用してこれを行うことができます
$ docker-compose up -d --build
Building my_app
[+] Building 2.5s (8/8) FINISHED
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 41B 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load metadata for docker.io/library/openjdk:11 2.3s
=> [auth] library/openjdk:pull token for registry-1.docker.io 0.0s
=> [1/2] FROM docker.io/library/openjdk:11@sha256:1b04b1958a4a61900feec994e3938a2a5d8f88db8ec9515f46a25cbe561b65d9 0.0s
=> [internal] load build context 0.0s
=> => transferring context: 84B 0.0s
=> CACHED [2/2] COPY target/test-app-0.0.1-SNAPSHOT.jar app.jar 0.0s
=> exporting to image 0.0s
=> => exporting layers 0.0s
=> => writing image sha256:4867a3f0b0a043cd54e16086e2d3c81dbf4c418806399f60fc7d7ffc094c7159 0.0s
=> => naming to docker.io/library/docker-test_my_app 0.0s
Starting docker-test_db_1 ...
Starting docker-test_db_1 ... done
別のアプローチは、upコマンドを実行する前にbuildコマンドを使用することです。
$ docker-compose build --pull --no-cache
db uses an image, skipping
Building my_app
... 0.0s
=> => naming to docker.io/library/docker-test_my_app
このコマンドには、さらに2つのオプションがあります。 –pull オプションは、イメージの構築中にDockerfileのベースイメージをリモートリポジトリからプルするように要求します。 –no-cache オプションは、ローカルキャッシュがスキップされることを示します。 ただし、ここでは直接イメージを使用しているため、dbサービスの構築はスキップされます。
ここで、作成構成を再起動すると、コンテナーは最新のイメージを使用します。
$ docker-compose up -d
Starting docker-test_db_1 ... done
Recreating docker-test_my_app_1 ... done
5. 結論
この記事では、docker-composeがデプロイ時に最新のイメージを使用しない理由を説明しました。 また、docker-composeが常に最新のイメージを使用して、そのイメージでコンテナーを再作成する方法をいくつか学びました。 また、アプローチの落とし穴と、それらを軽減する方法についても説明しました。
この記事に関連するコードは、GitHubでから入手できます。