web-dev-qa-db-ja.com

継承されたイメージのCMDまたはENTRYPOINTを再利用します

継承されたイメージで使用されているCMDを削除せずに、コンテナの起動/再起動/アタッチに独自のシェルスクリプトCMDを含めるにはどうすればよいですか?

私はこれを使用していますが、これは私のスクリプトをうまく実行しますが、PHP CMD

FROM php

COPY start.sh /usr/local/bin

CMD ["/usr/local/bin/start.sh"]

別に何をすべきですか?親イメージのENTRYPOINTまたはCMDをコピー/貼り付けする可能性を避けていますが、おそらくそれは良いアプローチではありません。

16

コメントで述べたように、これに対する組み込みのソリューションはありません。 Dockerfileから、現在のCMDまたはENTRYPOINTの値を確認できません。 run-partsソリューションを持つことは、上流のベースイメージを制御し、そこにこのコードを含めて、下流のコンポーネントが変更できるようにする場合に便利です。しかし、Dockerには、これに関する問題を引き起こす固有の問題が1つあります。コンテナーは、フォアグラウンドで実行する必要がある単一のコマンドのみを実行する必要があります。したがって、アップストリームイメージが開始すると、後のステップに実行の機会を与えずに実行を継続するため、コマンドを実行する順序を決定する複雑さが残り、最終的に単一のコマンドが終了せずに実行されるようにします。

私の個人的な好みは、独自のコマンドまたはエントリポイントを追加し、execへのコマンドの最後のステップをアップストリームコマンドにするための、はるかに単純でハードコーディングされたオプションです。アップストリームDockerfileから呼び出すスクリプト名を手動で識別する必要があります。しかし、あなたのstart.shには次のものがあります:

#!/bin/sh

# run various pieces of initialization code here
# ...

# kick off the upstream command:
exec /upstream-entrypoint.sh "$@"

exec呼び出しを使用して、pid 1をアップストリームエントリポイントに転送して、信号が正しく処理されるようにします。そして、末尾の"$@"はコマンドライン引数をすべて通過します。独自の$@スクリプトで処理および抽出したい引数がある場合は、setを使用してstart.shの値を調整できます。

20
BMitch

ベースイメージが自分のものでない場合、残念ながら手動で親コマンドを呼び出す必要があります。

親画像を所有している場合は、camptocampの人々が提案するものを試すことができます here

基本的には、ディレクトリでrun-partsを呼び出すエントリポイントとして汎用スクリプトを使用します。それは、そのディレクトリ内のすべてのスクリプトを辞書式順序で実行することです。したがって、画像を拡張するときは、新しいスクリプトを同じフォルダーに配置するだけです。

ただし、それは、手に負えなくなる可能性のあるスクリプトにプレフィックスを付けることで順序を維持する必要があることを意味します。 (親イメージが新しいスクリプトを後で追加することにしたと想像してください...)。

とにかく、それは動作する可能性があります。

アップデート#1

このdocker compose issue には、コンテナ実行後のプロビジョニングに関する長い議論があります。 1つの提案は、シェルスクリプトでdocker runまたはcomposeコマンドをラップしてから、他のコマンドでdocker execを実行することです。

このアプローチを使用する場合は、基本的に親CMDをrunコマンドとして保持し、Dockerの実行後にdocker execとして配置します。

4
Morgan Kobeissi