Moby: 親画像から継承されたプロパティをリセット

作成日 2014年01月06日  ·  153コメント  ·  ソース: moby/moby

イメージを作成するときに、親イメージからプロパティを継承するのではなく、そのプロパティの一部をリセットしたい場合があります。 デフォルトですべてのプロパティを継承することは理にかなっていますが、理にかなっている場合は、明示的かつ選択的にそれらをリセットする方法が必要です。

これは、 exposeのみをアドレス指定する#2210のより一般的なソリューションです。

arebuilder kinenhancement statuneeds-attention

最も参考になるコメント

親画像から継承したVOLUMEポイントを削除する方法が絶対に欲しいです。

たとえば、永続データに外部マウントポイントを使用するアプリケーションのメインイメージがありましたが、代わりにテストデータが事前に入力されたそれに基づくイメージも必要だったとします。 現状では、親イメージがVOLUMEを使用している場合、これらのディレクトリへの変更/追加は、Dockerのビルド中に行われたとしても、コミット時に失われるため、これを行うことはできません。

全てのコメント153件

構文に関する提案を歓迎します。

私が思いつくことができる最善の方法は、 UNVOLUMEまたはより一般的には-VOLUMEような対応するコマンドです(ただし、それはさらに混乱を招き、 +VOLUMEが機能するはずだという誤解を生む可能性さえあります。 VOLUMEとは異なる動作をするはずです)。

私は間違いなくそのようなものが欲しいです(特にVOLUMEの場合)。 また、VOLUMEのようなものが後続のRUN行に適用されることも少し混乱していますが、ENTRYPOINTのようなものは適用されません。 これは非常に便利な場合とそうでない場合がありますが、一般的な「以前のX命令を無効にする」ことで、この問題をうまく解決できます。

当面の間、これに対する回避策はありますか? ENTRYPOINT(https://github.com/jagregory/pandoc-docker/blob/master/Dockerfile)を使用して画像を拡張しているので、エントリポイントの設定を解除する必要があります。 Dockerfileで次のものを使用してみました。

FROM jagregory/pandoc
ENTRYPOINT [] # this basically gets ignored (bug?)

FROM jagregory/pandoc
ENTRYPOINT [""] # this will make docker try to exec '' (the empty string)

FROM jagregory/pandoc
ENTRYPOINT ["/bin/sh", "-c"] 
# this will only work if docker run args are quoted:
#   docker run dergachev/pandoc "echo a b c"

ありがとう!

親画像から継承したVOLUMEポイントを削除する方法が絶対に欲しいです。

たとえば、永続データに外部マウントポイントを使用するアプリケーションのメインイメージがありましたが、代わりにテストデータが事前に入力されたそれに基づくイメージも必要だったとします。 現状では、親イメージがVOLUMEを使用している場合、これらのディレクトリへの変更/追加は、Dockerのビルド中に行われたとしても、コミット時に失われるため、これを行うことはできません。

@dergachevのコメントから更新するために、 CMD []ENTRYPOINT []は、前回テストしたときに機能していたので、まだ機能しているはずです(他のものはバグファイリングに適しています)。

を介してすべての単一オプションコマンドをリセットできます

ENTRYPOINT []
CMD []
USER 0
WORKDIR /

これにより、リセットできない残りのメタデータがENVVOLUMEEXPOSE 、場合によってはONBUILDます。

(これは#8709から来ています)

親でソケット9000-9002を公開したが、子で9001を公開解除する必要がある場合は、「設定解除」のスタイルで記述する必要があります。

公開
EXPOSE 9000
EXPOSE 9002

これは機能しますが

UNEXPOSE 9001

見栄えがします。

利点は、後で追加したい継承チェーンのさらに上からのEXPOSEに影響を与えないことです。

+1 @ codeon-nat

これは#8177で説明されていますが、実際のユースケースが不足しているため、これを終了します。

なぜこれが閉鎖されているのですか? ここには9人のコメントがありました。 これは本当に便利なものになると思います。 実際のユースケースでは、既存のイメージを簡単に構築できます。 プロパティを追加したい場合もあれば、削除したい場合もあります。 これは正常です。

私は例えば、私は拡張しています、同意nginx SSLオフローダのための画像を、私はしたいUNEXPOSE 80が、去る443

nginxなどの複数のインスタンスを実行する場合は、ポートの公開を解除できることが非常に重要です。

気にしないでください、これは私の側の貧弱な構成でした。

(4月15日:「実際のユースケースはありません」少なくとも1つは想像できず、これを閉じて驚いた)

オプションのソフトウェアのボリュームまたはポートを公開するベースイメージがあり、それを別のDockerfileでFROMして、不要なもの、または祖先からアンインストールしたものを公開してはならないイメージを作成します。 これらの設定を削除できないようにするのはなぜですか?

これのユースケースもあります。 データベーススナップショットを含むイメージを作成できるようにしたいのですが、すべてのmysqlパッケージにVOLUME /var/lib/mysql設定されています。 ボリュームをオフにできると、Dockerfileで行われたデータベースへの変更がイメージに残ります。

他の唯一のオプションは、カスタムmysqlイメージを完全に再作成することですが、他の多くの人々がすでに私よりも優れたデフォルトのmysqlサーバーをまとめているため、それはどういうわけか無駄に思えます。

追加のユースケースの追加-公式のRabbitMQイメージから継承していますが、デフォルトのAMQPポート(5672)ではなく、WebSocketポート(80および443)のみを公開したいと考えています。 このようなことをしたいのはかなり合理的なことのように思われますか?

別のユースケースを追加します。 gogsイメージを使用してgitテスト環境を構築したいのですが、データはすべてボリュームに保存されているため、データを保持するのは面倒です。 環境を設定した後、ボリュームのボリュームを解除してイメージを構築できれば素晴らしいと思います。

+1

公式のphpから継承し、ポートの代わりにソケットを使用したいので、公開された9000ポートを削除する必要があります

自明ではない能力でDockerを使用したことがある人なら誰でも、継承されたコンテナーでこれらの制限に気付くでしょう。

@shykes @icecrimeこれはどのように閉じられましたか? 現在の構文で解決するのは難しすぎて、下位互換性が必要ですか? どんな計画ですか?

+ 1-ここでのEXPOSEオーバーライドの実際のユースケース。

これが3年以上続いていることを考えると(2013年にさかのぼる問題が見つかりました)、いつ公開されたポートを削除できるようになりますか?

+1。 デフォルトのnginxポート80および443を「UNEXPOSE」できる必要があります。

ここでUNEXPOSE求めている人たちのために; EXPOSEステートメントは、コンテナによって公開されているポートのヒントを提供するだけで、実際にはそれらのポートを_公開_しません。 これらのポート( -p / -P )をホストに公開するには、これらのポートを_公開_する必要があります。 言い換えると; DockerfileからEXPOSEステートメントを省略しても、イメージに直接的な影響はありません(たとえば、コンテナーの「ポート80」に到達することはできます)。

さらに、追加のポートを公開する場合は、コンテナー内のサービスをそれらのポートで実行するだけで、これが機能します。

本当ですが、-P(すべてのポートを公開するため)を使用し、ベースイメージが公開したくないポートを公開すると、スタックします。 -pを使用するように切り替えて、他のすべて

知っておくと良い

@kgxは害はありませんが(機能の肥大化の可能性は別として)、「UNVOLUME (またはUNSET VOLUME )はまだ私の個人的なウィッシュリストにあります。 :-)

Dockerを試した最初の72時間で、この問題に遭遇したことを面白がっています。 あらゆる種類の継承を持つ、私が使用する他の主要なツールのすべての構成または言語には、「親をオーバーライドする」タイプの機能があります。

ユースケースは次のとおりです。go-ethereumにデフォルトのDockerイメージを使用しており、外の世界に絶対に接続しないテストバージョンをセットアップできる必要があります。 ホストや他のコンテナから接続できる必要があります。 これを行う最も安全な方法は、プログラムが熱心にピアに接続しようとするため、ポートを変更することです。 また、適切なボリュームを作成するために一度実行するイメージの「データベースのセットアップ」バージョンを作成するには、CMDとENTRYPOINTをオーバーライドできる必要があります。 これらはすべて、Dockerfileで実行するのが非常に困難です。

別のIPアドレスに割り当てることができます...または別のホストポートをバインドします。 エントリポイントとcmdのオーバーライディングについては、後でそれらを再定義するだけです。

---ボクサーから送信| http://getboxer.com

2016年2月20日には午前8時57分00秒でGMT、barkthins [email protected]書いた:ここでは「SAユースケース:私がgo-イーサリアムのデフォルトのドッキングウィンドウの画像を使用している、と私はテストを設定できるようにする必要があります絶対に外の世界に接続しないバージョン。 ホストや他のコンテナから接続できる必要があります。 これを行う最も安全な方法は、プログラムが熱心にピアに接続しようとするため、ポートを変更することです。 また、適切なボリュームを作成するために一度実行するイメージの「データベースのセットアップ」バージョンを作成するには、CMDとENTRYPOINTをオーバーライドできる必要があります。 これらはすべて、Dockerfileで実行するのが非常に困難です。 -このメールに直接返信するか、GitHubで表示してください。

CMDENTRYPOINTは実行時にオーバーライドできます。 docker run --entrypoint=foo myimage mycmd 。 ここでの質問は、本番環境で実行される実際のイメージを「テスト」しないため、テスト中に別のエントリポイント/コマンドを使用して別のイメージを作成することが役立つかどうかです。 (補足)

これらの返信から、少なくともentrypoint、cmd、expose、およびおそらく他のいくつかの範囲では、コマンドラインオプションを優先してdockerfileが非推奨になっているようです。 コマンドラインは、Dockerfileが実行できないことをすでに実行しているため、それが方向性のように見えます。 それが意図されている場合は、混乱を減らすために、Dockerfile情報のできるだけ多くをインスタンス化時間に移動します。 それは意図ですか?

@barkthinsいいえ、Dockerfileは非推奨ではありません。 Dockerfileを使用することは、イメージを生成するための通常の方法です。 また、継承された画像のCMDENTRYPOINTを上書きできます。 私の例は、特定の場合(たとえば、画像に対して代替コマンドを実行する場合)に、実行時にそれらをオーバーライドできることを示すことでした。

Dockerfileのマニュアルページから:

     -- EXPOSE <port> [<port>...]
     The EXPOSE instruction informs Docker that the container listens


実行時に指定されたネットワークポート。 Dockerはこの情報を使用して
リンクと_を使用してコンテナを相互接続し、ポートを設定します
host_でのリダイレクト

  • システム。*
    [...]
    歴史
    * 2014年5月、Zac Dover(redhat dot comのzdover)ベースでコンパイル
    docker.comDockerfileのドキュメント。 * 2015年2月、Brian Goff(
    [email protected]
    読みやすさのために* 2015年9月、Sally O'Malleyによって更新されました(
    [email protected]

[私のイタリック体]は、あなたの言うことが誤解を招く(または少なくともあいまいな)ように思われます
本当。

2016年1月28日木曜日午前6時43分、Sebastiaan van Stijn <
[email protected]>は次のように書いています:

UNEXPOSEを求めているここの人々のために; EXPOSEステートメントのみ
コンテナによって公開されるポートを_ヒント_しますが、公開しません
実際にそれらのポートを_公開_します。 それらのポートを_公開_する必要があります(-p / -P)
それらをホストに公開します。 言い換えると; EXPOSEステートメントを省略します
Dockerfileからの画像には、直接的な影響はありません(
それでも、たとえば、コンテナの「ポート80」に到達します)。

さらに、追加のポートを公開する場合は、
コンテナ内のサービスはこれらのポートで実行され、これは機能します。


このメールに直接返信するか、GitHubで表示してください
https://github.com/docker/docker/issues/3465#issuecomment-176012915

現在Dockerに関する本を共同執筆しています:コード39miellで39%オフ
http://manning.com/miell/?a_aid=zwischenzugs&a_bid=e0d48f62

thaJeztah私のポイントとこのスレッドのポイントは、継承が一貫していないことだと思います。 はい、ENTRYPOINTとCMDをオーバーライドできますが、EXPOSEは露出を追加します。コマンドラインを除いて、親の露出を置き換えることはできません。 3番目の動作があるかどうかを確認するために、他のコマンドを調べていません。 また、どのコマンドが親のコマンドを拡張または置換するかについても文書化されていません。

@thaJeztahUNEXPOSEが必要です

コンテナのメタデータを読み取り、追加のアップストリーム構成を提供するソリューションがいくつかあります。 例えば; HAPROXYでは、Tomcatアプリでそのポートへのアクセスを動的に提供しようとするブロックをブロックするためにEXCLUDE_PORTS=8080を設定する必要があります。

開発者は公開されたポートを確認し、コンテナーの動作について推測します。 たとえば、Tomcatを拡張するベースイメージ(EXPOSE 8080)がありますが、イメージはデフォルト(EXPOSE 8888)とは異なるポートを使用します。 複合イメージにWebサーバーを追加する場合(たとえば、NGINXとTomcatを実行している場合)、HTTP(EXPOSE80およびEXPOSE443)を介してコンテンツを提供します。

後者の例では、8080、8888、80、および443を公開していると自己文書化する画像になり、80/443のみが関連します。

非常に具体的なドキュメントにもかかわらず、コミュニティの開発者に物事を説明し続けなければならないという事実からも明らかなように、これらは実際の問題です。 画像を見るだけでドキュメントが必要なのは誰ですか? <-画像が間違ったことを自己文書化している場合は全員。

この問題には回避策がありますが、それらは回避策です。 これは主要なアーキテクチャの問題ですか? Dockerがこの実際の問題に対するより洗練されたソリューションを検討できないのはなぜですか。

これのステータスは何ですか?

@BillBrowerステータスは、問題ではないと信じる理由を提供せずに問題をクローズしたことです。 明らかに私たちの多くにとって、それは私たちの日常生活を悩ませている現実世界の問題であり続けています;)

@modius @BillBrowerは閉じていても、いつでも再考できます。 基本的に「いいえは一時的」ですが、機能をマージ/実装する場合は「はいは永遠に」です。したがって、機能に懸念がある場合、メンテナの正しい選択は「いいえ」と言うことです。

これを実装しているPRは、機能について確信が持てず、その使用法のより実際的な例を探しているメンテナがいたため、終了しました。 https://github.com/docker/docker/pull/8177#issuecomment -93587164

ほとんど同意できないため、これを終了しますが、コメントで間違っていることを証明してください。再検討できます。

それは1年以上前のことなので、状況が変わった可能性があります。 この問題を再開し、次のメンテナセッションで取り上げます。 (DockerConと保留中の1.12リリースのため、これは通常より少し長くなる可能性があることに注意してください)

ありがとう、@ thaJeztah。 それは非常に理にかなっています。 元の決定の背後にある理論的根拠を説明し、これを実現したい場合に確認する必要があることを概説していただきありがとうございます。

_UNVOLUME_リクエストの1つのユースケース

特に、現在、カスタムボリュームドライバーを使用すると、指定されたコンテナーのすべてのボリュームに適用されるためです。

EFSボリュームドライバーの場合がありました。起動時にボリュームバインディングを指定すると正常に動作します。 バインディングを設定しないと、自動生成されたUUIDからNFS共有をマウントしようとするため、失敗します。 つまり、たとえば親イメージによって作成された、気にしないボリュームも含めて、すべてのボリュームへのバインディングを提供する必要があります。

現在の唯一の回避策は、起動時に、必要のないすべてのボリュームを同じEFS共有の空のサブフォルダーにバインドすることです。

注:docker volumeコマンドはすべてMarathonによって開始され、単一のdocker runコマンドで使用できるはずなので、使用できません。

+ 1UNEXPOSEが必要

UNEXPOSEの場合は+1

UNEXPOSEの場合は+1

UNEXPOSEの場合は+1

UNEXPOSEの場合は+100

UNEXPOSEの場合は+9000

+∞
たとえば、Dockerfileに含まれている公式リポジトリnginx (FROM nginx:stable)を使用します

EXPOSE 80 443

しかし、別のレイヤー、ポート80に削除したいと思います。例:

UNEXPOSE 80

お願いします!
この機能を追加してください!!!!

@frekele 、もし私があなたのお母さんかお父さんだったら、あなたは得られないでしょう。 ありえない。

UNEXPOSE +++
非常に必要な機能!

お願いします、あなたは電子メール通知で他のみんなにスパムを送る必要はありません、そしてあなたは間違いなくこれらすべての「+1」コメントで議論を乱雑にする必要はありません。 問題の説明に👍と反応して、同意を表明することができます。

@underyxこれは話題から外れていますが、人々がこれを言っているのを見続けるので、私は噛みます。 思ったよりニュアンスがあります。 多くの大規模なチームにとって、反応は投票メカニズムではなく社会的特徴として設計されているため、問題に関するコメントの数がエンゲージメントを測定する唯一の方法であり、GH APIを介してレポートを実行する信頼できる方法ではありません(例:とりわけ、ソートできません)。 また、コメントを追加すると、スレッドが自動的にサブスクライブされます。これは、ほとんどの場合、必要なものです。それ以外の場合は、👍_をクリックし、[サブスクライブ]をクリックする必要があります。
https://github.com/isaacs/github/issues/9#issuecomment -195120703を参照して
さて、議論を乱雑にしないようにしましょう;)
/offtopic

この問題については、メンテナ会議で話し合いましたが、通常は、この問題に再び取り組むことができます。

@duglinおそらくこれに取り組むことに興味がありますか?

まだ時間があるかどうかはわかりませんが、要約すると....上記のコメントに基づいて、要件は、人々が以下をクリア/設定解除できるようにすることであると信じています。

EXPOSE  (all or specific one)
ENV  (specific - not sure we need to clear all yet)
LABEL  (ditto)
VOLUME  (all or just specific paths? probably both)
CMD  (possible but only using the json format)
ENTRYPOINT  (possible with json format)

私は何かを逃しましたか?

UNVOLUMEの場合は+10000

@duglin現在は不可能であり、最も要求されているものから始めるのがEXPOSEVOLUME )。 私は他の人への要求をあまり見ていません(しかしそれに反対していません)。

元のPRはUNSET <SOMETHING>を使用していましたが、後でUN<SOMETHING>に変更されました。 私は_個人的に_最初のものがもっと好きでしたが(より一般的)、 @ shykesUN<SOMETHING>好みました、それが変わったかどうかはわかりません。

UNVOLUMEがいいでしょう。

私の使用例: mysqlイメージを使用していて、 /var/lib/mysqlディレクトリに含まれるデータベースを新しいイメージにコミットしたいのですが、親Dockerfileでボリュームとして宣言されているためコミットできません。

@thaJeztah UNSET <something>は読みやすく、奇妙ではありません。 言葉を発明し始める必要はありません。 また、スクリプト作成者にもよく知られています。 1つもすることができます

UNSET  EXPOSE VOLUME LABEL

私の例、

dokuwikiのインストールを設定しています。 私が選んだ画像は、すべての潜在的な構成ボリュームを公開していました。 私がやりたいのは、このベースイメージからインストールをカスタマイズすることです。 ボリュームが公開されているため、イメージのビルド時にPHP構成ファイルを変更できません。

ベースイメージを変更してそれらのボリュームのボリュームを解除することはできますが、そのイメージを永久に維持する必要があります...「最新」を使用することの魔法はなくなりました:(

UNEXPOSEの+1 :)

UNVOLUMEの場合は+1、またはUNSETVOLUMEの場合は+1。

UNVOLUMEの場合は+1。 これは今のところ私にとって役立つかもしれません。 また、学生がボリュームをマウントする必要を心配せずにスピンアップする大学のシナリオでも役立つ可能性があります。

ボリュームをマウントする必要はありません。

そのために必要になるとは思いません。 DockerfileのVOLUME定義は、イメージ内のその場所にあるコンテンツから「匿名」ボリュームを自動的に作成します。

@duglin 、あなたはすでにこれに取り組んでいますか? そうでない場合、私はそれを取り、最も要求されたもの(VOLUMEとEXPOSE)から始めます。 お知らせ下さい。

@runco​​mはそれのために行きます-まだ時間を見つけることができていません。

注意として、 UNENVコマンドは、環境変数の設定を選択的に解除するために(たとえば、同時にUNVOLUME dであるボリュームと一致させるために)引き続き有用であることに注意してください。 未設定の変数は、特にシェルでset -ueとともに使用される場合、空白に設定された変数と同じではありません。

公式画像からVOLUMEとEXPOSEを削除することは可能です
それらは問題です。

2017年1月28日21:23、「henryptung」 [email protected]は次のように書いています。

注意として、UNENVコマンドは引き続き有用であることに注意してください。
環境変数の設定を選択的に解除します(たとえば、
同時にUNVOLUMEdであるボリューム)。 未設定の変数は
特にset-ue inで使用する場合、空白に設定された変数と同じです。
シェル。


このスレッドにサブスクライブしているため、これを受け取っています。
このメールに直接返信し、GitHubで表示してください
https://github.com/docker/docker/issues/3465#issuecomment-275875623 、またはミュート
スレッド
https://github.com/notifications/unsubscribe-auth/AAdcPAKP1tii706MY-8MxVPSFLTFme8Dks5rW7HggaJpZM4BXt2-

UNVOLUMEの場合は+1

UNVOLUMEの場合は+1

UNVOLUMEの私のユースケース:

Webサイトのソースが/ var / www / htmlにコピーされるS2Iシナリオでのlibrary / worpressイメージの使用

VOLUMEは、結果のイメージに空のFSをマウントすることによってそれを押しつぶします。 ->ライブラリ/ワードプレスは使用できません。

@groulot実際、 --volumeを使用してボリュームを明示的にマウントしない場合、コンテナーの作成時にイメージのコンテンツがボリュームにコピーされます。

docker runコマンドは、新しく作成されたボリュームを、ベースイメージ内の指定された場所に存在するデータで初期化します。

https://docs.docker.com/engine/reference/builder/#/volume

docker save / loadを使用したハッキーな回避策があります。http: //stackoverflow.com/q/42316614/808723を参照して

UNVOLUMEの場合は+1

UN-EXPOSEができるという@modiusの論理的根拠をエコーし​​たいと思います。 Dockerを学習するときに開発者が最初に理解することの1つは、 docker psと入力して、コンテナーで何が起こっているかを確認することです。 使用可能としてリストされている標準ポートが表示されます。 開発者は、Docker以前の世界でセットアップしたローカル環境またはテスト環境からの標準ポートに慣れているため、標準ポートを確認して機能することを理解しているため、Dockerを導入することは困難です。 Dockerコンテナに接続していません。

UNVOLUME、UNEXPOSE、UNENV、..の場合は+1

これはしばらく開いているようです。 ここに牽引力はありますか?
また、TCPポート9000の代わりに、公式のPHPfpmアルパインイメージとUNIXソケットを使用したいと思います。
親からのEXPOSEをオーバーライドすることはできず、EXPOSEを取り除くためだけにそのイメージを構築することはできません。

+1

+1

VOLUMEコマンドの設定を解除する機能が大好きです。 Wordpressの公式イメージは、完全なコードベースをボリュームに強制的にダンプします。コードベースの残りの部分をイメージにベイクできるように、wp-content / uploadsディレクトリ用のボリュームのみを用意することをお勧めします。

ルートアクセスを制限するkubernetesクラスタにイメージをデプロイすると、VOLUMEディレクトリにアクセスできなくなりますが、解決策は、親イメージで定義されたボリュームを上書きすることです。

私から+1

UNEXPOSEのユースケース

4つのDockerホストがあり、16個のMavenTomcatコンテナーを実行したいとします。これらはすべてデフォルトで内部ポート8080になっています。

ここで、ランチャーCNIでレジストレーターを使用していると想像してください。これにより、内部ポートにロックダウンされます。
https://github.com/gliderlabs/registrator/issues/541#issuecomment -305012416
これは、ホストごとに1つの8080内部ポートしか実行できないことを意味します。 (8080:8080ポートマッピングを行う必要があるため)

この状況では、dockerの内部->外部ポートマッピングは私の問題を解決するのに十分ではありません。 実際には、できれば元のコンテナを再構築せずに、内部ポートマッピングをオーバーライドする必要があります。

ジュリアン、1対1のマッピングがどのように行われているのかわかりません。 私にとって登録者は
トラフィックのルーティングとは関係なく、登録と登録解除を行うだけです。
実行中のコンテナ。 たとえば、登録者が維持する方法で使用します
Dockerによって割り当てられたIPと公開されたポートをに配置することによるEtcdインスタンス
そこの。 次に、confdを使用して、Etcdインスタンスを監視し、nginxを更新します
独自のコンテナで設定します。
午前4時06分に2017年6月(土)、17日、ジュリアン・ギャンブル[email protected]
書きました:

UNEXPOSEのユースケース

4つのDockerホストがあり、16のMavenTomcatを実行したいとします。
すべてデフォルトで内部ポート8080になっているコンテナ。

今、私が牧場主CNIで登録者を使用していると想像してください-それは私を閉じ込めます
内部ポートに接続します。
gliderlabs / registerrator#541(コメント)
https://github.com/gliderlabs/registrator/issues/541#issuecomment-305012416
これは、ホストごとに1つの8080内部ポートしか実行できないことを意味します。 (私が持っているので
8080:8080ポートマッピングを行うには)

この状況では、dockerの内部->外部ポートマッピングでは不十分です
私の問題を解決するために。 実際に内部ポートマッピングをオーバーライドする必要がありますが、
できれば元のコンテナを再構築せずに。


コメントしたのでこれを受け取っています。
このメールに直接返信し、GitHubで表示してください
https://github.com/moby/moby/issues/3465#issuecomment-309189149 、またはミュート
スレッド
https://github.com/notifications/unsubscribe-auth/ABrq2QGgY81wbePOBKbkTSjpUSoPIocuks5sE0LCgaJpZM4BXt2-

こんにちはブラッドリー、

これを見てくれてありがとう。 私はRancherに組み込まれているipsecurityと組み合わせてregistratorを使用しています。 ここのリンクからわかるように:
https://github.com/gliderlabs/registrator/issues/541#issuecomment -305012416
ランチャースケジュールコンテナのレジストラで外部ポートを表示する機能が制限されていました。 つまり、内部ポートしか使用できませんでした。

ここで解決策を探しているユーザーが怒っていることがわかります。
https://forums.rancher.com/t/do-you-kill-registrator/5152

そしてここで提案された解決策:
https://github.com/cabrinoob/rancher-registrator
(これは一部の人にとっては実現可能ではありませんでした)。

あなたが「登録者牧場主」をグーグル検索するならば、あなたはもっと見つけるかもしれません。

登録者を「内部」モードで実行することをお勧めします。このモードでは、内部ポートを外部ポートに1:1でマップします。 これにより、 UNEXPOSEの問題が発生します-内部ポートがすぐに不足します。

私のポイントは、ホスト内のDockerコンテナネットワーキングに使用されるipsecurityは、Dockerの外部ポートに1:1でマップされた内部ポートにロックされるユースケースにつながる可能性があるということです。 このためには、 UNEXPOSEコマンドが必要です。

これを見てくれてありがとう。

乾杯
ジュリアン

3。5年が経過し、この問題の進展はありませんか?...

UNEXPOSEの場合は+10086。 親イメージが公式ではない場合があります。非公式のポートを使用しているため、ポートを上書きする機能が必要です。

@ pumba-lt
これが解決策を見つけられない理由は、彼らが技術的にそれを行う方法を知らないからだと思います。

また、明確な回避策がある場合は、Dockerfile言語が複雑になります。 親Dockerfileにあまり多くの構成をプッシュせず、代わりに継承イメージの場合はそのままにします。 (別名:Docker Hubでのランダムな画像の調達を停止する:D)

docker 17.05以降、この問題のほとんどの必要性を排除するマルチステージビルドを実行する新しい方法もあります(これは単一のDockerfile )。

# First import the original image
FROM nginx AS source-image

# Second step of the build, start with an empty image
FROM scratch
# Copy the data from the original image
COPY --from=source-image / /
# Re-define all the config
EXPOSE 80
STOPSIGNAL SIGTERM
CMD ["nginx", "-g", "daemon off;"]

編集:言うのを忘れた、2番目の解決策は前のすべての層を押しつぶします。 大したことではないと思いますが、知っておくとよいでしょう。

@ zimbatm-それは素晴らしいです!

これが解決策を見つけられない理由は、彼らが技術的にそれを行う方法を知らないからだと思います。

変更自体はそれほど複雑ではありません。 実装はこのPRにあります。 https://github.com/moby/moby/pull/8177。 当時はコンセンサスはありませんでしたが、1月からの私のコメントに従えば、 https://github.com/moby/moby/issues/3465#issuecomment -247405438、状況が変わり、(それ以降、人々が考えを変えない限り)、これを実装するための貢献を受け入れます。

なぜまだそこにないのかについて。 誰もそれに取り組み始める時間がなかったという理由だけで、誰かが興味を持っていれば、それはおそらく受け入れられるでしょう。

@zimbatmはい、あなたの例は直接の問題を解決しますが、別のレイヤーも作成し、すべての画像レイヤーを平坦化することに注意してください。 これにより画像サイズが小さくなる場合もありますが、それらのレイヤーが親としてnginxを使用する画像と共有されなくなるため、より多くの画像をダウンロードする必要が生じる可能性があります。 例えば;

元のnginxイメージ:

$ docker inspect nginx -f '{{json .RootFS.Layers}}' | jq .

[
  "sha256:54522c622682789028c72c5ba0b081d42a962b406cbc1eb35f3175c646ebf4dc",
  "sha256:1c3fae42c5007fd0e70309b5b964eb5d49046562bd425424da734784098894e7",
  "sha256:87823f21b7939eac6e099fa878871a806c1904a7698793edb63bf6e5f5371e1f"
]

そして、作成したnginxイメージ。

$ docker inspect nginx2 -f '{{json .RootFS.Layers}}' | jq .
[
  "sha256:9a71ba430225d4f24e0d57837a71b6b2b68bf88ca7530c0a89c98783c98531b5"
]

更新してくれてありがとう@thaJeztah

使用する提案を繰り返してもいいですか

UNSET XXXX

新しくて奇妙な語彙を発明する代わりに(例:UNVOLUME)。

この方法で、1行で複数のプロパティの設定を解除することもできます。

UNSET VOLUME EXPOSE LABEL

個人的にはUNSET実行しても大丈夫ですが、どちらかを実行しても大きな変更にはならない可能性があるため、PRが到着したときにレビュープロセスに残しておきます

こんにちは、2回目にFROMを使用する場合でも、親Dockerイメージで公開されているポートの一部を公開しないことを除いて、親イメージのすべてを保持するにはどうすればよいですか? これに関する公式の決議はありますか、これを受け入れて作業するか拒否するか

これを受け入れて作業するか拒否するか

@rajiff上記の私のコメントを参照してくださいhttps://github.com/moby/moby/issues/3465#issuecomment-313549657貢献は大歓迎です

変更自体はそれほど複雑ではありません。 実装はこのPRにあります。 #8177。 当時はコンセンサスはありませんでしたが、1月からの私のコメントに従えば、 #3465(コメント)、状況が変わり、(それ以来人々が考えを変えない限り)、これを実装するための貢献を受け入れます。

したがって、コンセンサスが変更された可能性がある場合は、 #8177を再開してみませんか?

では、コンセンサスが変わった可能性がある場合は、#8177を再開してみませんか?

そのPRは3年以上前に開かれました。 コードは適用されなくなりました

UNsomethingコマンドを具体的に使用する代わりに、
FROMコマンドを改善して、実際に継承したいものをリストできるようにしてみませんか?

次のようなものを使用できます:
ベースイメージから(VOLUME、EXPOSE、PORT、..)
または、否定を付けて本当に必要な場合:
FROM baseimage(*、-VOLUME、-EXPOSE)
またはより良い構文を持っている;)

そもそも、これはすべてFROMコマンドの一部である必要があるように思われます。

Dockerfile内からのボリュームの変更:ビルドステップで、宣言後にボリューム内のデータが変更された場合、それらの変更は破棄されます。

それは完全に真実ではないようです。 あなたはまだこれを行うことができます:

VOLUME /avolume/subdir
WORKDIR /avolume
COPY ./Dockerfile /avolume/subdir

ボリュームを元に戻すために使用できるかどうかはわかりませんが。

親イメージ/コンテナENTRYPOINTのオーバーライドは、最新バージョンでは機能しません。

17.09.1-ceバージョン

$ docker run --name=experiment --entrypoint=/bin/bash ubuntu:16.04
$ docker inspect experiment --format "{{.Config.Entrypoint}}"
[/bin/bash]
$ IMAGE=$(docker commit -c "ENTRYPOINT []" experiment)
$ docker inspect $IMAGE --format "{{.Config.Entrypoint}}"
[]

17.10.0-ceバージョン以降

$ docker run --name=experiment --entrypoint=/bin/bash ubuntu:16.04
$ docker inspect experiment --format "{{.Config.Entrypoint}}"
[/bin/bash]
$ IMAGE=$(docker commit -c "ENTRYPOINT []" experiment)
$ docker inspect $IMAGE --format "{{.Config.Entrypoint}}"
[/bin/bash]

UNSET ENTRYPOINTも機能しません。
バグですか?

@ alexey-igrychev別の問題を開くことができますか? あなたがコメントしている問題は、DockerfileにUNSET xx命令を実装するための_機能リクエスト_です。 ( UNSET命令はまだ実装されていないので、それは予想されます。)

その問題の回避策としては、使用して[""]の代わりに[]エントリポイントのためには、仕事に思えます。

IMAGE=$(docker commit -c "ENTRYPOINT [\"\"]" experiment)
docker inspect $IMAGE --format "{{.Config.Entrypoint}}"
[]

テーブルとデータがプリロードされたデータベースイメージを作成できるように、ボリュームの設定を解除する方法も必要です。
残念ながら、ベースイメージはプライベート(oracle)であるため、ベースのdockerfileにアクセスできないため、コピーすることもできません。 画像を拡張することしかできません。
この問題には、多数の+1と実際のユースケースがリストされており、複数のPRが作成されていますが、PRはクローズされています。 では、この機能を利用するには何をする必要がありますか?

@veqrynこの問題を再開して以来、誰もプルリクエストの作業を開始しませんでした。 既存のプルリクエストはコードベースに正しく適用されなくなったため、新しいリクエストを開く必要があります。 誰かがこれに取り組むことに興味があるなら、物事は再び進むことができます。

私の以前のコメントを参照してください。 https://github.com/moby/moby/issues/3465#issuecomment -247405438

この問題については、メンテナ会議で話し合いましたが、通常は、この問題に再び取り組むことができます。

@duglinおそらくこれに取り組むことに興味がありますか?

そしてhttps://github.com/moby/moby/issues/3465#issuecomment-313549657

なぜまだそこにないのかについて。 誰もそれに取り組み始める時間がなかったという理由だけで、誰かが興味を持っていれば、それはおそらく受け入れられるでしょう。

私のユースケースはdocker-compose.yamlから来ています:TLSリバースプロキシ、Mavenリポジトリを追加し、ポート80/443を引き継ぎ、ポート80と5432を非公開にする、本番用のオーバーライドを備えた開発用の作成ファイルが欲しいです。開発構成ファイルが公開します。 または、開発オーバーライドを使用した本番用の作成ファイル。

Dockerfilesから継承された構成ファイルを階層化するという追加のみの性質により、システム設計が複雑になります。 一部のパラメーターを撤回できる場合、またはオーバーライドをアクティブにして別のコンテナーを作成した場合は、非常に便利です。 docker-composeのフードの下でどのように機能するかについては気になりません。

ありがとう@ thaJeztah-プルリクエストでこれを修正することを検討するために読み始める場所であるコードの行を教えていただけますか?

私自身はビルダーコードにあまり取り組んでいませんが、変更はhttps://github.com/moby/moby/tree/master/builderパッケージにあるはずです。

この号は3年です! とても基本的な機能に同意するのはとても難しいですか、それとも私は何かが欠けていますか?

@caruccioはい、何かが足りません:4つのコメントを上にスクロールしてくださいhttps://github.com/moby/moby/issues/3465#issuecomment -356988520

また、いくつかのユースケース(1つは個人プロジェクト、もう1つは作業プロジェクト)があり、 VOLUMEEXPOSE 、およびENTRYPOINTステートメントを過負荷にします。親画像。

ENTRYPOINT []で新しい空のエントリポイントを設定するだけでENTRYPOINT回避策があり、おそらくEXPOSEを無視して生きることを学ぶことができますが、...私は引っかき傷が残っていますVOLUME定義を継承しない方法についての私の頭。

親画像にボリュームがあるコードベースでこの問題に遭遇しました。つまり、子画像のこのボリュームに対するすべての変更が破棄されました。 ついにこの問題への道を見つけるまで、私は2日間怒っていると思っていました。 誰かがこれを実装できますか?

回避策があります。

いつでもdocker save image -o image.tar 、そのアーカイブを解凍し、メタデータを編集して、 docker load -i image2.tar再パックできます。 そうすれば、以前のVOLUME宣言が含まれていないimage2を作成できます。

これらの手順を定期的に実行する必要があるため、サードパーティのイメージをクリーンアップするタスクに役立つ小さなスクリプトを作成しました。 docker-copyeditをご覧ください

素晴らしい作品@gdraheim ! 250行未満のPythonで実行可能なソリューション。

@gdraheimうわー、これは素晴らしいです! READMEから:

すべてのボリュームを削除したいという願望は、プログラムとデータの両方を定義された状態に戻して別の状態にするために、データ部分も履歴にコミットする必要があるローカルテスト用にテスト済みのイメージをダウンロードしたかったという事実から来ました。テスト実行は、まったく同じチェックポイントから開始されます。

これは私たちのユースケースでもあります。

docker-copyeditを拡張して、画像のすべてのメタデータエントリをカバーするようにしました。これにより、EXPOSEリストとVOLUMEリストの問題のあるケースを超えて、すべての継承されたプロパティで機能できるようになります。 それは、よく見られるもののuser、workingdir、labels、env設定になります。 ENTRYPOINTをCMDにコピーすることも、私が定期的に行う変更です。 中間のdocker-buildステップを実行する必要はありません。docker-copyeditを実行するだけです。 ;)

Dockerチームがこの問題を追跡して繰り返し無視するために使用した時間は、おそらく代わりにそれを修正するのに十分だったでしょう。

明らかに大量のユーザーがこれを要求した後、これを再開してください...
または、少なくとも、すべてのユースケースを無視するだけでなく、それに対して合理的な議論をします(私もポートを公開解除し、自分のイメージを構築する前に、クソ(80/80 / tcp)なしでよりクリーンなDockerps出力を取得したいだけです。 ..(非オープンソースのDockerfileでは難しい)

問題はまだ開いています。 オープンソースです。 貢献は大歓迎ですhttps://github.com/moby/moby/issues/3465#issuecomment-356988520

@thaJeztahhttps //github.com/docker/compose/pull/3939を参照

これはmoby / buildkitで修正されると思いますか? そこにDockerfileコマンドインフラストラクチャのほとんどがあります。

私はUNSETファンでもあります

UNSET EXPOSE 9000

また

UNSET LABEL foo

したがって、 HEALTHCHECK CMDフォームのように、サブコマンド風のフォームを持つコマンドを調べていますが、 HEALTHCHECKすでに未設定のフォームがあることに気付きました...

HEALTHCHECK NONE

これは興味深い選択ですが、 HEALTHCHECKも1つの構成のみを定義し(最新のものでオーバーライドし)、 LABELEXPOSEように複数を定義することはできません。そしてVOLUMEはそうします。

これらがどのように相互作用するのか、または他の種類のNONEフォームが機能するのではないかと思います。

ホストネットワークを使用するときに公開されるものを制御するには、公開されたポートを削除する何らかの方法が本当に必要です。

+1 EXPOSE []

つまり.... 5年間、DockerチームはUNSETオペレーターを実装できず、素晴らしい

@AnthonyMastreanが言ったように、この問題をmoby/buildkitプロジェクトに移動する必要がありますか?

十分に文書化され、テストされているがマージされていないPRもありますが、このPRも移動/リベースする必要がありますか?

この機能は本当にありがたいですし、Azureのnginxベースのイメージの問題に対処します。

UNSETCLEARRESETOVERRIDEIGNOREは大丈夫です- UNxxxは避けたいのでサポートおよび文書化するために予約済みキーのリストを複製します。

FROMを使用する場合、何を無視/リセットするかを指定することもできます。

FROM nginx:1.13 IGNORE EXPOSE, ENTRYPOINT

多段階ビルドを使用して、もう1つの回避策を提案します。
すべてのファイルを元の画像から新しい画像にコピーしますが、メタデータはありません。

FROM postgres as orig

FROM alpine:3.8 as postgres
COPY --from=orig / /
ENTRYPOINT ["docker-entrypoint.sh"]
EXPOSE 5432
CMD ["postgres"]

そんなことを考えていなかったなんて信じられません。 それは実際にはかなり良い@kotofosです。 上流のコンテナのレイヤーが失われますが、それは大きな損失ではありません。

@kotofosなぜFROM scratch as postgresないのですか?

@farcaller良いキャッチ。 ファイルシステム全体を上書きしているので、スクラッチの方が間違いなく良いでしょう

最後にテストしたところ、 COPY --from=xxx ...はファイルシステムを保持しません
所有権があるため、その回避策には注意が必要な場合があります。

@tianon正解ですが、シングルプロセスコンテナの場合、 --chownフラグを使用して、実行しているユーザーをコンテナのように設定できるため、これは問題にはなりません。

https://docs.docker.com/engine/reference/builder/#copy

これは2014年にさかのぼります。5年が経過し、近い将来、すべてのプロパティに一般的な「未設定」または「リセット」がなくなるようです。 私も一般的なアプローチを好みますが、考慮すべきことがたくさんあります。実際、それはすぐには起こらないでしょう。

つまり、少なくとも「UNEXPOSE」を取得して、開いているすべてのポートを閉じることはできますか、それともCMDおよびENTRYPOINTの場合と少なくとも同じ動作を取得できますか(最後の1つが勝ちます)。 これは、最も要求された「未設定」のプロパティであり、他のコマンドからの「最後の1つが勝つ」動作を考慮すると、(直感的ではない)動作に気付かないユーザーにとって潜在的なセキュリティリスクです。

多段階ビルドを使用して、もう1つの回避策を提案します。
すべてのファイルを元の画像から新しい画像にコピーしますが、メタデータはありません。

FROM postgres as orig

FROM alpine:3.8 as postgres
COPY --from=orig / /
ENTRYPOINT ["docker-entrypoint.sh"]
EXPOSE 5432
CMD ["postgres"]

PGDATA指すDockerボリュームを無視して、そのコンテンツをボリュームとしてではなくイメージにバンドルできるようにしたかったのです。
私にとってより軽い解決策は、単にPGDATA値を変更すること

FROM postgres:11.2-alpine
ENV PGDATA /var/lib/postgresql/test-data

# stuff that will create all my schemas
COPY create-scripts /docker-entrypoint-initdb.d/

# a weird way to trigger the entrypoint script to run the stuff in docker-entrypoint-initdb.d but not hang after starting postgres
RUN /docker-entrypoint.sh postgres --version

dockerfilesにEXPOSEVOLUMEを含めることには、いくつかの利点がありますか? 結局のところ、 --expose (または-p )と名前付きボリュームまたはバインドマウントを使用して、 docker run (およびdocker-composeファイル)で簡単に定義できます。 私はそれらのために何度も噛まれ、それらをリセットする方法はありません(特に公式画像またはmakefileで作成された画像を拡張する場合、新しいdockerfileを作成することはあまり実行可能ではありません)。 私はそれらをアンチパターン見なしており、

@lucasbasquerotto EXPOSEは、gitlab-runnerなどのツールによって使用され、イメージによって公開されていると宣言されたポートが実際に開いているかどうかを検出します。 これは、コンテナの準備ができているかどうかを検出するためのHEALTHCHECKの義務であることに同意しますが、宣言されたポートのリストを持つことは、自動化に実際に役立つ可能性があります。
VOLUMEは、コンテナーの停止/開始のユーザーフレンドリーなエクスペリエンスを提供し、データを自動的に永続化するために必要です。 繰り返しになりますが、これは他の方法で解決できると思いますが、データを検査可能にすることは、ツールにとって(そしてこの場合は人間にとっても)良いことです。

psはDockerfile構文を擁護していませんが、アンチパターンはキーワード自体が原因ではなく、このような一般的なユースケースで発生する可能性のある問題を解決するためにエコシステムが前進していないためです。宣言されたボリュームとボリューム内のいくつかの開始データを含むイメージを提供するなど(たとえば、スキーマがプリロードされたmysqlイメージ)

@zarelit gitlab-runnerどのように機能するか正確にはわかりませんが、Dockerfileの外部でチェックするポートを指定する方法があるはず

VOLUME 、名前付きボリュームを使用してステートフルデータを永続化するか、 -vを使用して既存のディレクトリにマウントできます(conainerを再作成するときにデータを保持する場合)。 また、dockerfile内のVOLUMEは、そのdockerfileを拡張する人にとってはわかりにくいため、このアプローチを使用する方がよいと思います。それがそこにあるかどうかわからない場合は、コンテナーが再現可能であると考える可能性があります。さまざまな環境で、副作用なしにバージョンを変更できますが、内部で永続データを使用しているため、後で噛まれるだけです。

また、ビルド中にファイルをそのディレクトリに移動することもできません(ボリュームとして使用したくない場合は、 /var/www/html/を定義するwordpressのように、ディレクトリをボリュームとして定義するDockerfileを継承します)。 VOLUMEとして/var/www/html/ 、そして別のディレクトリを使用するためにいくつかのハックを使用する必要がありました)。

-vを使用して、ボリュームが必要であることを明示的に宣言し、DockerfileのVOLUMEの黒魔術による望ましくない驚きを回避します。

また、多くの匿名ボリュームが作成される可能性があります。

イメージ内でボリュームを定義すると、コンテナーを起動するときにボリュームを定義しなくても、このデータをコンテナーの残りの部分とは別に保存するようにDockerに指示します。 このデータを保存するDockerの方法は、名前のないローカルボリュームを作成することです。 名前自体は長い一意のID文字列であり、アタッチされているイメージまたはコンテナへの参照は含まれていません。 また、コンテナーを削除するときにボリュームを削除するようにDockerに明示的に指示しない限り、これらのボリュームは残り、二度と使用されることはありません。

ソース: https

@lucasbasquerotto私はほとんどあなたに同意します、すべての長年の問題があります、私はそれらが無効にならないパスに従うべきだと思います、それらは次のように有益になります...あなたがボリュームで回すことができる提案されたパス、サーバーがリッスンできる推奨ポート。

Dockerジャーニーの大部分がOCI標準に抽出されたと思います。したがって、このようなレガシーをすべて備えていない新しいツールを作成する必要があります。

便利だと思った人は、 tugboat.qadockerの画像を自由に使用してhttps

dockerfilesにEXPOSEVOLUMEを含めることには、いくつかの利点がありますか? 結局のところ、 --expose (または-p )と名前付きボリュームまたはバインドマウントを使用して、 docker run (およびdocker-composeファイル)で簡単に定義できます。 私はそれらのために何度も噛まれ、それらをリセットする方法はありません(特に公式画像またはmakefileで作成された画像を拡張する場合、新しいdockerfileを作成することはあまり実行可能ではありません)。 私はそれらをアンチパターン見なしており、

最近の多くのベンダーは、アプリを単純なコンテナーイメージとして提供し、それとともにdockerfilesを提供しています。
これらのファイルにEXPOSEVOLUMEを含めると、アプリディレクトリに単純なdocker runを含む単純なアプリケーションを使用できるようになります。 アプリが期待するパラメータについて何も知る必要はありません。dockerfileで提供されているすべてのデフォルトで機能します。
そうです。composeやk8sのような、単純なローカルアプリケーション用の複雑なアプリケーション用のより大きなガンはまだ最適です。 そして、正しく機能するデフォルトがあると、使用が便利になります。

@ m451 (より多くのオプションが定義されている)長いものよりも短い

代わりのdocker run some_imageあなたは簡単に実行することができますdocker run --expose 3000 -v my_volume:/container/dir some_imageし、容器が破壊された後も持続するホストとボリュームに暴露されたポートを明確に理解しました。

また、これは簡単なことであり、必要な場合にのみボリュームを公開してマップします(dockerfileで公開されているすべてのポートや、定義されているすべてのボリュームが必要ない場合があります。一部のポートを公開することが本当に重要な場合または、ボリュームを使用する場合は、リポジトリにドキュメント化して、公開またはマッピングする必要があるものだけがわからないようにすることをお勧めしますが、結局のところ、これはコンテナの外部に影響を及ぼし、その後も持続する可能性がありますコンテナが破壊されます)。

それがdockerfileにある場合、実際には何が起こっているのかを知るのが難しくなり、ボリュームが永続化されていてわからない場合、長期的には予期しない驚きを引き起こす可能性があります(特に、dockerfileが別のファイルから継承されている場合は、わからない可能性があります)ボリュームが何をするかをより深く調べない限り、ボリュームが定義されていることを事前に確認してください)。 したがって、この問題が解決されたとしても、VOLUMEとEXPOSEは悪いと思います。

さらに、この問題は解決されていませんが(5年半以上開いていることを考えると、解決に何年かかるかわかりません)、リセットする方法がありません。それら

dockerfilesにEXPOSEVOLUMEを含めることには、いくつかの利点がありますか? 結局のところ、 --expose (または-p )と名前付きボリュームまたはバインドマウントを使用して、 docker run (およびdocker-composeファイル)で簡単に定義できます。 私はそれらのために何度も噛まれ、それらをリセットする方法はありません(特に公式画像またはmakefileで作成された画像を拡張する場合、新しいdockerfileを作成することはあまり実行可能ではありません)。 私はそれらをアンチパターン見なしており、

最近の多くのベンダーは、アプリを単純なコンテナーイメージとして提供し、それとともにdockerfilesを提供しています。
これらのファイルにEXPOSEVOLUMEを含めると、アプリディレクトリに単純なdocker runを含む単純なアプリケーションを使用できるようになります。 アプリが期待するパラメータについて何も知る必要はありません。dockerfileで提供されているすべてのデフォルトで機能します。
そうです。composeやk8sのような、単純なローカルアプリケーション用の複雑なアプリケーション用のより大きなガンはまだ最適です。 そして、正しく機能するデフォルトがあると、使用が便利になります。

私はそれをするベンダーが無知からそれをすることを主張するでしょう。 これが本番環境で製品を使用したい人々に引き起こす問題を理解していない。 確かに、誰かが製品のテスト/デモインスタンスを立ち上げるのが簡単になります。 しかし、実際に実行したい場合は、Dockerfileをgit clone / sedするか、動作するイメージを取得するためだけに独自のファイルを作成する必要があります。

@ m451 (より多くのオプションが定義されている)長いものよりも短い

代わりのdocker run some_imageあなたは簡単に実行することができますdocker run --expose 3000 -v my_volume:/container/dir some_imageし、容器が破壊された後も持続するホストとボリュームに暴露されたポートを明確に理解しました。

また、これは簡単なことであり、必要な場合にのみボリュームを公開してマップします(dockerfileで公開されているすべてのポートや、定義されているすべてのボリュームが必要ない場合があります。一部のポートを公開することが本当に重要な場合または、ボリュームを使用する場合は、リポジトリにドキュメント化して、公開またはマッピングする必要があるものだけがわからないようにすることをお勧めしますが、結局のところ、これはコンテナの外部に影響を及ぼし、その後も持続する可能性がありますコンテナが破壊されます)。

それがdockerfileにある場合、実際には何が起こっているのかを知るのが難しくなり、ボリュームが永続化されていてわからない場合、長期的には予期しない驚きを引き起こす可能性があります(特に、dockerfileが別のファイルから継承されている場合は、わからない可能性があります)ボリュームが何をするかをより深く調べない限り、ボリュームが定義されていることを事前に確認してください)。 したがって、この問題が解決されたとしても、VOLUMEとEXPOSEは悪いと思います。

さらに、この問題は解決されていませんが(5年半以上開いていることを考えると、解決に何年かかるかわかりません)、リセットする方法がありません。それら

同意しました。 それでは、必要なパラメーターを伝達するための標準的な方法を定義しましょう。
何もない場合は、レガシーアプリと同じ混乱、つまりベンダー固有のドキュメントとドキュメント形式になってしまいます。 開くポートを教えてくれる人もいれば、開かない人もいます。 半分しか教えてくれない人もいれば、間違ったポートを教えてくれる人もいます。 ポート番号のみを通知し、プロトコルなどは通知しないものもあります。

Dockerfilesは、その混乱を標準化するための優れた方法です。

@ m451私はその点であなたに同意しますが、ポートを公開するだけでは有用な情報が伝わらないことを考慮するのは良いことです。 公開されたポートが期待するデータ/接続の種類は何ですか? 複数のポートがある場合、各ポートは何をしますか?

データを永続化する場合は、名前付きボリュームまたはホスト上の特定の場所にマウントする必要がありますが、VOLUMEはそれを支援しません。 一時データをより高いパフォーマンスで保存したい場合は、VOLUMEが役立ちます(これは、VOLUMEが役立つ可能性がある唯一のケースです)。 コンテナへの書き込みは、

ドキュメントのタイプとしてVOLUMEとEXPOSEを使用しても、悪い(または不足している)ドキュメントを正当化することはできません。 また、画像の一部の消費者に害を及ぼす可能性があります(おそらくそうなるでしょう)。

@ m451私はその点であなたに同意しますが、ポートを公開するだけでは有用な情報が伝わらないことを考慮するのは良いことです。 公開されたポートが期待するデータ/接続の種類は何ですか? 複数のポートがある場合、各ポートは何をしますか?

正しい。 秒からのポートの穴のアイデア。 視点は時代遅れです。 ただし、ここでは、開く必要のあるポートと閉じたままにできるポートを定義し、すべてのポートで交換されるデータを理解しようとしています。 HTTPSは今日、ほとんどすべてのラッパーになりました。通常、コードの作成者以外に、特定のポートを介して転送されるデータを正確に知っている人は誰もいません。 それでも、更新のたびに変わる可能性があります。

RLでは、アプリケーションのトラブルシューティング以外に、どのデータ/情報がどのポートを介して転送されるかを気にする必要はありません。 アプリケーションを信頼することにしました。 したがって、アプリケーションがポートXとYを開く場合は、それも信頼できます。
標準的な日常の操作では、アプリを起動するだけですぐに機能します(安全なデフォルトを想定)。
コンテナは、箱から出してすぐに使用できるようにするためのパッケージングアプリの形式になっています。

そうは言っても、良いドキュメントが重要であることに同意します。 しかし、RLでは、開くポートを知るためだけに何時間もドキュメントを読みたがる人はいません。 日常の運用タスクには何のメリットもありません。

パイの私の部分。

DockerfileでVOLUMEを使用することは無益です。 ユーザーが永続性を必要とする場合は、指定されたコンテナーを実行するときに必ずボリュームマッピングを提供します。 ディレクトリの所有権(/ var / lib / influxdb)を設定できないという私の問題が、InfluxDBのDockerfileのVOLUME宣言によるものであることを突き止めるのは非常に困難でした。 UNVOLUMEタイプのオプションがない場合、またはオプションを完全に削除しない場合、指定されたフォルダーに関連する_何か_を変更することはできません。 これは理想的とは言えません。特に、セキュリティを意識していて、特定のUIDを指定したい場合は、ホスト上でソフトウェアを実行している必要以上の権限を持つランダムなユーザーを避けるために

ユーザーのカスタマイズのために画像を拡張するときに、これらのVOLUMEディレクティブをオーバーライドする方法が必要です。 現時点での私の唯一の解決策は、自分でイメージを完全に再作成し、_DockerfileFROM_全体を動的に役に立たないようにすることです。

from nginx:latest
herokuにデプロイした後、80ポートはnginxによって公開されましたが、herokuでは許可されないので、何ができますか? nginxからすべてのdockerfileをコピーし、EXPOSE 80を削除しますか?

新しいものは書きません...しかし、EXPOSEディレクティブをオーバーライドすると非常に便利です。

これを共有する-https ://github.com/gdraheim/docker-copyedit/blob/master/docker-copyedit.py (私の作成ではなく、明確にするために、@ gdraheimに感謝します!)

これは、次のコマンドでdockerfileに設定されたpostgresコンテナからボリュームを削除するのに役立ちました。

python docker-copyedit.py FROM postgres:11.5-alpine INTO postgres:11.5-alpine remove volume /var/lib/postgresql/data

コンテナに損傷を与えることなく作業を完了し、元の画像を取得して適合させ、ボリュームなしで新しい画像を作成したようです(調整された画像から作成されたコンテナで実行されたdocker inspectよる)。 git README以外の目的で使用すると、さまざまな操作が可能になります。

 ./docker-copyedit.py FROM image1 INTO image2 -vv \
     REMOVE PORT 4444
 ./docker-copyedit.py FROM image1 INTO image2 -vv \
     remove port ldap and rm port ldaps
 ./docker-copyedit.py FROM image1 INTO image2 -vv \
     remove all ports
 ./docker-copyedit.py FROM image1 INTO image2 -vv \
     add port ldap and add port ldaps

LABELは、「設定を解除する」機能を使用できる別の「プロパティ」(まだ言及されていません)です。

このSO投稿で言及されているように: https

アップストリームイメージからVOLUMEをリセット/削除する別のユースケース:

Oracleデータベースイメージの拡張に取り組んでいますが、ボリュームは/opt/oracle/oradataです。 デフォルトのOracleイメージでは、データベースはコンテナの起動時に作成され、そのボリュームに書き込みます。 しかし、それが原因で、コンテナは最初の起動に25分を要し、許容できないものになります。 したがって、データベースがイメージビルドで作成されるイメージで作業していますが、データベースが作成されるため、 VOLUME /opt/oracle/oradataを削除する必要がありますが、コンテナーを起動すると、ファイルシステム/opt/oracle/oradataは空になります。再び、私のデータベースは起動に失敗します。

Oracleデータベースイメージの拡張に取り組んでいますが、ボリュームは/opt/oracle/oradataです。

まさに私のユースケースです。 他の人がプライベートDockerレジストリからプルできる、事前に割り当てられたプラグ可能なデータベースを生成したいのですが、ボリュームがありません。 私はもっ​​と深く掘り下げて、最も醜い回避策を決定する必要があります。

私はそれを次のように解決しました:

docker-copyeditを使用してボリュームを削除してから、bashスクリプトを作成してデータベースを作成しました(Oracleの起動スクリプトを見て、どのように実行されるかを確認できます)。 事前構成されたPDBを使用すると、イメージからコンテナーを起動するのに25秒しかかかりません。 しかし、画像は本当に大きくなります。

より良いアプローチは、既存のDocker仕様を拡張して、次のようなスティッキーな環境変数/オーバーライドオプションの概念を含めることです。

たとえば、アップストリームのTomcatイメージに基づく私のプロジェクト:

--ENV CATALINA_HOME / some / other / path
tomcatから:8.5.54-jdk8-openjdk
..。

ENVが-で宣言されている場合は、スティッキーステータスに昇格し、宣言された値を保持するか、Dockerfileの処理チェーンの後半でこの変数で検出された値をオーバーライドする必要があります。

--ENV =この時点からDockerfileで先に進みます。

したがって、これは、多段階ビルドなどで同じ変数がさらに遭遇するよりも優先する場合に、Dockerfileの先頭で使用できます。 また、Dockerfileのどこに配置されたかに応じて、ファイルの上位の参照が独立するように柔軟に対応できます。

正しいアプローチは、他の誰かがオーバーライドできるENV参照を使用してVOLUMEを宣言することであるため、UNVOLUMEは必要ありません。

例えば

ENV PROJ_VOL / some / path
VOLUME $ PROJ_VOL

ENTRYPOINT []ENTRYPOINT [""]どちらも、BuildKitを使用していない場合、各ビルドのキャッシュを無効にするようです。 簡単なDockerfileデモンストレーション:

FROM jrottenberg/ffmpeg:4.3-alpine311 as base

ENTRYPOINT []

RUN echo "HERE!"

手順2と3は、キャッシュを使用しません。 これは私の回避策です:

FROM jrottenberg/ffmpeg:4.3-alpine311 as base

ENTRYPOINT ["/usr/bin/env"]

RUN echo "HERE!"

最初のパターンでキャッシュ障害を再現できません:: confused:

$ cat Dockerfile
FROM alpine:3.12
ENTRYPOINT []
RUN echo 'HERE!'

$ docker build .
Sending build context to Docker daemon  17.25MB
Step 1/3 : FROM alpine:3.12
 ---> a24bb4013296
Step 2/3 : ENTRYPOINT []
 ---> Running in d921be2e563d
Removing intermediate container d921be2e563d
 ---> 7801c649d895
Step 3/3 : RUN echo 'HERE!'
 ---> Running in 9e2ca2cf1f9f
HERE!
Removing intermediate container 9e2ca2cf1f9f
 ---> d398fdd442b1
Successfully built d398fdd442b1

$ docker build .
Sending build context to Docker daemon  17.25MB
Step 1/3 : FROM alpine:3.12
 ---> a24bb4013296
Step 2/3 : ENTRYPOINT []
 ---> Using cache
 ---> 7801c649d895
Step 3/3 : RUN echo 'HERE!'
 ---> Using cache
 ---> d398fdd442b1
Successfully built d398fdd442b1

ENTRYPOINTを定義する画像を使用する必要があると思います。 私が行った画像またはmysqlを使用してみてください。

おもしろい- mysql:8.0を使って再現できます。 確かなバグ! :+1:

このページは役に立ちましたか?
0 / 5 - 0 評価