複数のFROM-それが意味すること


112

githubでLinkuriousプロジェクトのDockerイメージを構築したいのですが、実行するにはNeo4jデータベースとNode.jsの両方が必要です。

私の最初のアプローチは、Neo4jを含む、私のイメージのベースイメージを宣言することでした。リファレンスドキュメントは、「ベースイメージ」を有用な方法で定義していません。

基本画像:親がない画像は基本画像です

私は、その画像に基本画像自体がない場合にのみ、基本画像がある可能性があることを読みました。

しかし、ベースイメージとは何ですか?FROMディレクティブでneo4j / neo4jを宣言した場合、イメージが実行されると、neoデータベースが自動的に実行され、ポート7474のコンテナー内で使用できるという意味ですか?

Dockerリファレンスを読む(https://docs.docker.com/reference/builder/#fromを参照)

FROMは、単一のDockerfile内に複数回出現して、複数のイメージを作成することができます。新しいFROMコマンドを実行する前に、コミットによって出力された最後のイメージIDをメモしてください。

複数の画像を作成したいですか?私が望むのは、他の画像のコンテンツを含む単一の画像を持つことです(neo4jやnode.jsなど)。

リファレンスマニュアルで依存関係を宣言するディレクティブが見つかりませんでした。RPMのように、私のイメージを実行するために、呼び出しコンテキストが最初に必要なイメージをインストールする必要がある依存関係はありませんか?

よくわかりません...


注:2017年5月、1つのに複数のが含まFROMれるようになりましたDockerfile。以下の私の編集した回答を参照してください。
VonC 2017年

私の答えがきれいになっているかどうかを確認してください。もしそうなら、それを受け入れることを検討してください。
エヴァンキャロル

回答:


113

ベースイメージとは

一連のファイル、およびEXPOSE'dポート、ENTRYPOINTおよびCMD
ファイルを追加し、そのベースイメージに基づいて新しいイメージを構築できます。ディレクティブでDockerfile始まる新しいイメージを使用できます。以下で説明するイメージは、新しいイメージの「ベースイメージ」です。FROMFROM

ディレクティブで宣言neo4j/neo4jしたFROM場合、イメージが実行されると、neoデータベースが自動的に実行され、ポート7474のコンテナー内で使用できるという意味ですか?

CMDとを上書きしない場合のみENTRYPOINT
ただし、画像自体で十分です。特定のの使用にFROM neo4j/neo4j関連するファイルを追加する必要がある場合は、aを使用neo4jしますneo4j

FROM 単一のDockerfile内で複数回出現できます

しない:とにかくその「機能」を削除する提案があります(問題13026

問題14412は次のように述べています:

複数を使用することFROMは実際には機能ではなくバグです(まあ、制限は厳しくFROM、Dockerfile での複数の使用例はほとんどありません)。


2017年5月(18か月後)、docker(moby)17.05-ceで更新します。

1つのDockerfileで複数のFROM 使用できます。
Dockerでのビルダーパターンとマルチステージビルド」(Alex Ellisによる)およびTõnisTiigiによるPR 31257を参照してください

前:

ビルダーパターンでは、2つのDockerイメージを使用します。1つはビルドを実行し、もう1つは最初のビルドの結果を、最初のイメージのビルドチェーンとツールのペナルティなしで出荷します。

後:

一般的な構文ではFROM、Dockerfile内に時間を追加しますFROM。最後のステートメントが最終的なベースイメージになります。中間画像からアーティファクトと出力をコピーするには、を使用しますCOPY --from=<base_image_number>

Dockerfileの最初の部分:

FROM golang:1.7.3 as builder
WORKDIR /go/src/github.com/alexellis/href-counter/
RUN go get -d -v golang.org/x/net/html  
COPY app.go    .
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .

同じ(!)Dockerfileの2番目の部分:

FROM alpine:latest  
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=builder /go/src/github.com/alexellis/href-counter/app    .
CMD ["./app"]  

結果は、2枚の画像、建物のための1つだけ有するもの得られたアプリであろう(はるかに、はるかに小さいです)

REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE

multi               latest              bcbbf69a9b59        6 minutes ago       10.3MB  
golang              1.7.3               ef15416724f6        4 months ago        672MB  

2
複数のFROMの削除について残念。それは、特に依存メカニズムがない場合に、私にとって最も便利に思えます。たとえば、RPMを使用すると、パッケージを実行するために別のパッケージが必要であることを宣言できるため、インストール時にすべてがセットアップされます。実際には、ほとんどの場合、複数の依存関係が必要になるため、複数のFROMがない場合、どのように機能するのでしょうか。
ekkis 2015年

3
@ekkisは、以前の回答(stackoverflow.com/a/33295292/6309)で述べたように、複数のコンテナをオーケストレーションし、それぞれが特定のサービスを提供し、--link(docs.docker.com/ userguide / dockerlinks /…)。
VonC、2015年

2
@VonC確かに、理想的な世界では、新しいアプリとすべてのパターンが理解されています。それまでの間、ソリューションをDockerに移行しようとする人が増え、ソフトウェアの依存関係など、ネットワークでは解決できないニーズがあり、すべて互換性のあるベースを使用しているが、複数のDockerfilesを使用していると思います。代わりに、これまでのところ私が把握できる最善の方法は、Dockerfileをハッキングして独自のものを作成することです。
Rainabba

@rainabba同意した。従来のモノリスは簡単に移行されません。興味深いのは、読み取りますmartinfowler.com/articles/...をthreedots.tech/post/microservices-or-monolith-its-detailhackernoon.com/...
VonC

2

最初の答えは複雑すぎて、歴史的で、私の好みには何の情報もありません。


それは実際にはかなり単純です。Dockerは、マルチステージビルドと呼ばれる機能を提供します。ここでの基本的な考え方は、

  • 必要なものをホワイトリストに強制することで、不要なものを手動で削除する必要がなくなります。
  • Dockerの実装のために使用されるはずの無料のリソース。

最初から始めましょう。たいていの場合、Debianのようなものが表示されます。

RUN apt-get update \ 
  && apt-get dist-upgrade \
  && apt-get install <whatever> \
  && apt-get clean

これらすべてについて、上記で説明できます。上記のコマンドはチェーン化されているため、中間イメージを必要としない単一の変更を表します。このように書けば

RUN apt-get update ;
RUN apt-get dist-upgrade;
RUN apt-get install <whatever>;
RUN apt-get clean;

その結果、さらに3つの一時的な中間イメージが生成されます。イメージが1つに減ったため、残っている問題が1つありapt-get cleanます。それは、インストールで使用されたアーティファクトをクリーンアップしないことです。Debianのメンテナが自分のインストールにシステムを変更するスクリプトを含めている場合、その変更は最終的なソリューションにも存在します(pepperflashplugin-nonfreeその例については、何かを参照してください)。

マルチステージビルドを使用すると、1つの変更されたアクションのすべての利点が得られますが、COPY --fromここに記載されている構文を使用して一時イメージで導入されたファイルを手動でホワイトリストに登録してコピーする必要があります。さらに、(のようなapt-get clean)代替手段がなく、最終的なイメージに不要なファイルがたくさんある場合には、優れたソリューションです。

こちらもご覧ください


感謝しますが、私の問題にどのように取り組んでいるのかわかりません。私にとって、FROMは継承メカニズムであり、複数のディレクティブがあることは、複数の親から継承できることを意味します。あなたの回答では、FROMや、他の人がソフトウェアのパッケージを利用するという概念に言及していない
ekkis

1
おそらくそれは混乱です。FROM主に名前空間宣言です。修飾子は継承よりも拡張のようなものです。複数の名前空間を宣言できます。そして、それらの名前空間のそれぞれは、他の1つの名前空間を拡張できます。@ekkis他の答えがあなたのために働くなら、それなら、必ずそれに固執してください。
エヴァンキャロル
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.