1. ホーム
  2. docker

[解決済み] docker-compose: ラン、エクゼクティブの違い、レイヤーはどうなるのか?

2022-03-03 08:38:49

質問

私が理解した範囲では dockerdocker-compose というような流れになります。

Dockerfile --build--> Docker Image --create--> Docker Container #1
                                   --create--> Docker Container #2
                                   --create--> ...
                                   --create--> Docker Container #n

そのため Image のコマンドで作られています。 Dockerfile が、純粋にある種の "オフライン" バージョンである。それをコンテナとしてオンラインにすることができます。

私の理解では docker-compose up がこの2段階の処理をやってくれています。 service の中で定義されています。 docker-compose.yml また、ボリュームのマウントやポートの公開など、他の作業も行います。


最初の質問です。

もし私が docker-compose exec some_command ということは、Dockerコンテナを操作していることになりますよね?

私がドキュメントを理解した限りでは docker-compose run some_command というのはほぼ同じですが、あらかじめ新しいレイヤーを作っているので、このような感じです。

Docker Container #n (layer 0) ----> Docker Container #n (layer 1)

一方 some_command はレイヤー1で実行されますね。 さらに runsome_command をエントリーポイントに、一方 exec は、定義されたエントリポイントを上書きします。

2つ目の質問です。

で作成された新しいレイヤーはどうなるのでしょうか? run の後、どうすればいいですか?新しいレイヤーを作成せずにコマンドを実行する方法はありますか?このようにentrypoint-scriptを追加したので、それを知りたいのです。

#!/bin/sh

case "$@" in
    "update")
        pip3 install -r requirements.txt
        ;;
    "start")
        python manage.py runserver
        ;;
    *)
        echo "executing $@"
        exec "$@"
        ;;
esac

私は、セットアップ、アップデートなどの一般的なタスクを、次のような短いコマンドを実行するだけで実行できるようにするために、そうしました。 docker-compose run backend update . 問題は、このレイヤーを作成するために run を実行しても使用されません。 up を実行した後に

解決方法は?

まず、基本的な用語を整理しておきましょう。引用元は 公式ドキュメント :

An 画像 は、Dockerコンテナの作成方法が記載された読み取り専用のテンプレートです。

基本的に 画像 は、ファイルとディレクトリ構造、およびいくつかの付加的なメタデータを含むファイルシステムのアーカイブに過ぎません(たとえば ENV または CMD ) をコンテナとして使用します。というように考えてもよいでしょう。 tar または zip のアーカイブを作成します。

A コンテナ は、イメージの実行可能なインスタンスです。

新しい コンテナ 画像から docker イメージを解凍し、それぞれの 名前空間 で、解凍されたイメージをファイルシステムのルートとしてプロセスを開始します。

レイヤー は、通常 レイヤー は、ビルドプロセスで作成されたイメージに含まれ、複数のイメージで共通のファイル/レイヤーをキャッシュして再利用するために使用されます。そのため、次のような場合のみ、これらのファイルを気にする必要があります。 でのビルドステップを最適化します。 Dockerfile .

新しいコンテナごとに画像の内容を抽出・コピーするのではなく docker 画像の上に薄い書き込み可能なレイヤーを追加する そのコンテナの変更が保存されます。 この正確な仕組みは 実装の詳細 使用するストレージドライバに依存する ! を使用する場合、ほとんどの場合 docker は気にする必要はないでしょう。


では docker-compose これは基本的に、ビルドして実行するだけです。 docker コマンド* を使って、サービスに必要なコンテナを実行し、管理します。 docker-compose.yml の設定ファイルです。では docker-compose をそれぞれの docker コマンドを使用します。

  • docker-compose build を実行します。 docker build を指定した各サービスに対して build オプション
  • docker-compose pull : docker pull を持つすべてのサービスのイメージは image オプションをそれぞれのリポジトリから取得します。
  • docker-compose up :
    • 必要であれば : が先になります。 docker-compose build / docker-compose pull すべてのサービス
    • をビルドして実行することで、サービスコンテナを起動します。 docker run コマンド
  • docker-compose exec を実行します。 docker exec の中で新しいプロセス/コマンドを開始します。 既存の、実行中の コンテナ
  • docker-compose run : スタート 新しいコンテナ 指定されたコマンドを対話的に実行する、すなわち docker run

* 注意事項 docker-compose が行います。 実際には を呼び出します。 docker コマンドと会話するのではなく docker デーモンが直接 API を使用しています。しかし、理解しやすくするために、そのように見せかけておくことができます。


それでは、ご質問にお答えします。

<ブロッククオート

を実行すると docker-compose exec some_command ということは、Dockerコンテナを操作していることになりますよね?

私がドキュメントを理解した限りでは docker-compose run some_command というのはほぼ同じですが、あらかじめ新しいレイヤーを作っているので、このような感じです。

docker-compose exec の中で実行されます。 既存の実行中のサービスコンテナ 一方 docker-compose run を起動します。 新しい独立したコンテナ .

さらに、次のように思われます。 runsome_command をエントリーポイントに、一方 exec は、定義されたエントリポイントを上書きします。

正しい。 exec はエントリーポイントを使用しません。

で作成された新しいレイヤーはどうなるのでしょうか? run の後、どうすればいいのでしょうか?新しいレイヤーを作成せずにコマンドを実行する方法はありますか?

によって開始されたコンテナの一部であり、その変更は run を削除するまで持続します。 その コンテナを使用します。もし、変更をサービスコンテナ( docker-compose up を実行する必要があります。 docker-compose exec !

このようにentrypoint-scriptを追加したので、それを知りたいです。

セットアップやアップデートなどの一般的な作業を、次のような短いコマンドを実行するだけで行えるようにするためにそうしました。 docker-compose run backend update .

から docker-compose run を実行すると、新しいコンテナでそのコマンドが実行されます。 docker-compose exec の代わりに、手動でエントリーポイントを呼び出します。

docker-compose exec app /entrypoint.sh update

# and if you need to restart your app restart the service containers
docker-compose restart

しかし、これは間違った使い方です。 docker ! なぜなら、コンテナというのは 刹那的 であり、コンテナ内で実行されたコマンドは、その特定のコンテナにのみ影響します。そのイメージで新しいコンテナインスタンスを実行した瞬間(コンテナを停止した、電源が落ちた、など)、すべての変更が失われます。

その代わりに update コマンドを(最後の)コマンドとして Dockerfile で、(最後のレイヤーの)画像を再構築します。

docker-compose up --build

あるいは、ビルドキャッシュをスキップして、強制的に新規ビルドを行う場合。

docker-compose build --no-cache
docker-compose up