Beberapa FROM - apa artinya

112

Saya ingin membuat image buruh pelabuhan untuk proyek Linkurious di github, yang membutuhkan database Neo4j, dan Node.js untuk dijalankan.

pendekatan pertama saya adalah mendeklarasikan gambar dasar untuk gambar saya, yang berisi Neo4j. Dokumen referensi tidak mendefinisikan "gambar dasar" dengan cara yang berguna:

Gambar dasar: Gambar yang tidak memiliki induk adalah gambar dasar

dari mana saya membaca bahwa saya mungkin hanya memiliki gambar dasar jika gambar itu tidak memiliki gambar dasar itu sendiri.

tapi apa itu gambar dasar? apakah ini berarti bahwa jika saya mendeklarasikan neo4j / neo4j dalam direktif FROM, bahwa ketika image saya dijalankan, database neo akan secara otomatis berjalan dan tersedia dalam container di port 7474?

membaca referensi Docker (lihat: https://docs.docker.com/reference/builder/#from ) Saya melihat:

FROM dapat muncul beberapa kali dalam satu Dockerfile untuk membuat banyak gambar. Cukup buat catatan keluaran ID gambar terakhir dengan komit sebelum setiap perintah FROM baru.

apakah saya ingin membuat banyak gambar? sepertinya yang saya inginkan adalah memiliki satu gambar yang berisi konten gambar lain misalnya neo4j dan node.js

Saya tidak menemukan arahan untuk mendeklarasikan dependensi di manual referensi. apakah tidak ada ketergantungan seperti di RPM di mana untuk menjalankan gambar saya konteks panggilan harus terlebih dahulu menginstal gambar yang dibutuhkannya?

Saya bingung...

ekkis
sumber
Catatan: Mei 2017, Anda sekarang memiliki beberapa FROMfile Dockerfile. Lihat jawaban saya yang sudah diedit di bawah.
VonC
Lihat apakah Anda menemukan jawaban saya lebih bersih. Dan jika demikian, pertimbangkan untuk menerimanya.
Evan Carroll

Jawaban:

113

apa itu gambar dasar?

Satu set file, plus EXPOSEport, ENTRYPOINTdan CMD.
Anda dapat menambahkan file dan membuat gambar baru berdasarkan gambar dasar tersebut, dengan yang baru Dockerfiledimulai dengan FROMpetunjuk: gambar yang disebutkan setelahnya FROMadalah "gambar dasar" untuk gambar baru Anda.

apakah itu berarti bahwa jika saya mendeklarasikan neo4j/neo4jdalam sebuah FROMarahan, bahwa ketika gambar saya dijalankan, database neo akan secara otomatis berjalan dan tersedia dalam container di port 7474?

Hanya jika Anda tidak menimpa CMDdan ENTRYPOINT.
Tetapi gambar itu sendiri sudah cukup: Anda akan menggunakan a FROM neo4j/neo4jjika Anda harus menambahkan file yang terkait neo4juntuk penggunaan khusus Anda neo4j.

FROM dapat muncul beberapa kali dalam satu Dockerfile

Jangan: ada usulan untuk tetap menghapus "fitur" itu ( masalah 13026 )

Issue 14412 menyebutkan:

Menggunakan banyak FROMsebenarnya bukan fitur tetapi bug (oh well, batasnya ketat dan ada beberapa kasus penggunaan untuk beberapa FROMdi Dockerfile).


Perbarui Mei 2017 (18 bulan kemudian), dengan buruh pelabuhan (moby) 17.05-ce .

Beberapa FROM dapat digunakan dalam satu Dockerfile.
Lihat " Pola pembangun vs. bentukan multi-tahap di Docker " (oleh Alex Ellis ) dan PR 31257 oleh Tõnis Tiigi .

Sebelum:

Pola builder melibatkan penggunaan dua image Docker - satu untuk melakukan build dan satu lagi untuk mengirimkan hasil build pertama tanpa penalti dari build-chain dan tooling di image pertama.

Setelah:

Sintaks umum melibatkan penambahan FROMwaktu tambahan dalam Dockerfile Anda - mana saja yang merupakan FROMpernyataan terakhir adalah gambar dasar akhir. Untuk menyalin artefak dan keluaran dari gambar perantara, gunakan COPY --from=<base_image_number>.

Bagian pertama dari 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 .

Bagian kedua dari Dockerfile yang sama (!):

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"]  

Hasilnya akan menjadi dua gambar, satu untuk membangun, satu dengan hanya aplikasi yang dihasilkan (jauh, jauh lebih kecil)

REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE

multi               latest              bcbbf69a9b59        6 minutes ago       10.3MB  
golang              1.7.3               ef15416724f6        4 months ago        672MB  
VonC
sumber
2
kasihan tentang menghapus beberapa FROM. menurut saya paling berguna, terutama dengan tidak adanya mekanisme ketergantungan. dengan RPM, misalnya, saya dapat menyatakan bahwa paket saya memerlukan paket lain untuk dijalankan sehingga pada saat penginstalan semuanya disiapkan untuk saya. kenyataannya adalah bahwa hampir semua hal akan membutuhkan banyak ketergantungan jadi dengan tidak adanya beberapa FROM, bagaimana cara kerjanya?
ekkis
3
@ekkis seperti yang saya sebutkan dalam jawaban saya sebelumnya ( stackoverflow.com/a/33295292/6309 ), Anda menjalankan sistem Anda dengan mengatur beberapa wadah, masing-masing menyediakan layanan tertentu, dan berkomunikasi melalui --link ( docs.docker.com/ userguide / dockerlinks /… ).
VonC
2
@VonC Tentu, di dunia yang ideal, dengan aplikasi baru dan semua polanya dipahami. Sementara itu, saya berharap ada lebih banyak contoh orang yang mencoba memigrasi solusi mereka ke buruh pelabuhan dan memiliki kebutuhan yang tidak diselesaikan oleh jaringan, seperti ketergantungan perangkat lunak, semua menggunakan basis yang kompatibel, tetapi DARI beberapa Dockerfiles. Sebaliknya, yang terbaik yang bisa saya ketahui sejauh ini adalah meretas file Docker mereka untuk membuat file saya sendiri.
rainabba
@rainabba Setuju. Monolit lama tidak akan mudah dimigrasi. Bacaan menarik: martinfowler.com/articles/… , threedots.tech/post/microservices-or-monolith-its-detail , hackernoon.com/…
VonC
2

Jawaban pertama terlalu rumit, bersejarah, dan tidak informatif untuk selera saya.


Sebenarnya cukup sederhana. Docker menyediakan fungsionalitas yang disebut multi-stage build , ide dasarnya di sini adalah,

  • Bebaskan Anda dari keharusan untuk secara manual menghapus apa yang tidak Anda inginkan, dengan memaksa Anda untuk memasukkan apa yang Anda inginkan ke daftar putih,
  • Sumber daya gratis yang seharusnya digunakan karena implementasi Docker.

Mari kita mulai dengan yang pertama. Sangat sering dengan sesuatu seperti Debian yang akan Anda lihat.

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

Kami dapat menjelaskan semua ini dengan istilah di atas. Perintah di atas dirangkai bersama sehingga mewakili satu perubahan tanpa diperlukan Gambar perantara. Jika ditulis seperti ini,

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

Ini akan menghasilkan 3 Gambar perantara sementara. Setelah direduksi menjadi satu gambar, ada satu masalah yang tersisa: apt-get cleantidak membersihkan artefak yang digunakan dalam penginstalan. Jika pengelola Debian menyertakan skrip yang mengubah sistem yang dimodifikasi itu juga akan hadir dalam solusi akhir (lihat pepperflashplugin-nonfreecontoh seperti itu).

Dengan menggunakan build multi-tahap, Anda mendapatkan semua manfaat dari satu tindakan yang diubah, tetapi ini akan mengharuskan Anda untuk memasukkan ke daftar putih dan menyalin file yang dimasukkan dalam gambar sementara secara manual menggunakan COPY --fromsintaks yang didokumentasikan di sini. Selain itu, ini adalah solusi hebat di mana tidak ada alternatif (seperti apt-get clean), dan Anda akan memiliki banyak file yang tidak diperlukan di gambar akhir Anda.

Lihat juga

Evan Carroll
sumber
terima kasih, tetapi saya tidak mengerti bagaimana Anda menangani masalah saya. Bagi saya, FROM adalah mekanisme pewarisan dan memiliki banyak arahan berarti saya bisa mewarisi dari banyak orang tua. dalam jawaban Anda, Anda tidak menyebutkan DARI atau konsep memanfaatkan kemasan perangkat lunak oleh orang lain
ekkis
1
Mungkin itu yang membingungkan. FROMpada dasarnya adalah deklarasi namespace. Kualifikasi di sana lebih seperti perpanjangan dari warisan. Anda dapat mendeklarasikan beberapa namespace. Dan masing-masing namespace tersebut dapat memperluas satu namespace lainnya. @ekkis Jika jawaban lain berhasil untuk Anda, maka tetaplah dengan itu.
Evan Carroll